Escolar Documentos
Profissional Documentos
Cultura Documentos
Apostila Linguagem C para Microcontrolador PDF
Apostila Linguagem C para Microcontrolador PDF
1 Introdução
O objetivo desse documento é fornecer um resumo sobre a linguagem C com ênfase em
aplicações para microcontroladores. O emprego da linguagem C na programação de mi-
crocontroladores não é complicado, mas exige conhecimento mínimo da estrutura de pro-
gramação, além de conhecimentos específicos sobre as estruturas internas do microcon-
trolador em questão. Este resumo apresentará as estruturas de programação mais comuns,
necessárias para se programar microcontroladores. Para os conhecimentos específicos de
cada microcontrolador, uma leitura do datasheet do componente se faz necessária.
A estrutura básica de um programa em C para microcontroladores é a seguinte:
void main()
{
// inicializações de hardware e software
Com o uso inteligente dos comentários e funções, a programação se torna de mais fá-
cil compreensão. Programas extensos podem ser divididos em sub-rotinas (funções) que
ocasionalmente consumirão menos memória do microcontrolador e tornarão o se proces-
samento mais rápido.
2 Definições Gerais em Linguagem C 4
Como já comentado, uma palavra reservada da linguagem C não pode ser utilizada pelo
programador como variável do programa. A seguir temos um exemplo de erro no emprego
de variáveis:
while = 1;
int = 200;
2.3 Comentários
Os comentários auxiliam na documentação do programa e são fundamentais para enten-
dimento futuro de sua funcionalidade, especialmente se quem vai fazer a manutenção do
firmware não é o próprio programador que o criou. Além disso, os comentários também
são úteis exclusão de linhas de código durante a compilação, facilitando os testes durante a
programação.
Em geral, grande parte dos compiladores aceita dois tipos de comentários, os de linha
simples e os de múltiplas linhas. Os comentários de linha simples sempre são iniciados
com “//” (dupla barra), fazendo com que o compilador ignore tudo o que estiver na mesma
linha depois da dupla barra. Por exemplo:
// Este é um comentário de linha simples.
2 Definições Gerais em Linguagem C 5
Por sua vez, os comentários de múltiplas linhas devem ser sempre iniciados com “/*” e
terminados com “*/”. Por exemplo:
/* Este é um
comentário de
múltiplas linhas.
*/
• Decimal:
valor_decimal = 125;
• Binário:
PORTA = 0b11110001;
• Hexadecimal:
valor_hexa = 0xFF;
• Octal:
valor_octal = 075;
• Caractere:
caracter = ’a’;
2.5.1 Constantes
Servem para criar símbolos de valor constante que auxiliam na programação. No momento
da compilação, o compilador se encarrega de atribuir os valores corretos aos símbolos
criados. Por exemplo:
const LIGADO = 1;
const DESLIGADO = 0;
const TMAX = 100;
Após definir as constantes, é possível utilizar estas palavras como tendo o mesmo sig-
nificado do valor numérico atribuído.
2 Definições Gerais em Linguagem C 7
2.5.2 Definições
Além de dar nome a valores constantes, também podemos atribuir outros nomes a símbolos
já existentes no microcontrolador. Por exemplo, imagine que você tenha um LED ligado
ao bit 0 da porta A do seu microcontrolador, além de um motor DC ligado ao bit 1 dessa
mesma porta. Para facilitar a programação, pode-se fazer:
#define LED PORTA.B0
#define MOTOR PORTA.B1
Observe que na Linguagem C os comandos iniciados pelo caractere “#” são os únicos
que não recebem ponto-e-vírgula no final da sentença.
Assim, os comandos de definição “#define” e “const” servem para tornar o programa
mais compreensível. Além disso, estes comandos são sempre eliminados pelo compilador,
ou seja, não consomem memória extra do microcontrolador.
Para visualizar sua utilizada, considere o código abaixo utilizando definições e cons-
tantes:
#define LED PORTA.B0
#define MOTOR PORTA.B1
const LIGADO = 1;
const DESLIGADO = 0;
void main()
{
LED = LIGADO;
MOTOR = LIGADO;
}
2.6 Variáveis
Uma variável sempre deve ser declarada da seguinte forma:
(<modificador>) <tipo de dado> <nome da variável> (= <valor>);
return (valor1+valor2)/2;
}
Uma observação importante é que todas as definições de variáveis locais devem apare-
cer logo no início do bloco/função.
int media()
{
return (valor1+valor2)/2;
}
int soma()
{
return valor1+valor2;
}
Mas atenção, apesar de parecer uma boa ideia declarar funções globais devemos ter
bastante cuidado com sua utilização. Uma vez que estas variáveis podem ser acessadas
por todas as funções, é difícil manter o controle sobre seus valores à medida que o código
vai sendo executado. Por essa razão, declarar variáveis globais não é considerada uma boa
prática de programação, devendo ser utilizadas apenas quando estritamente necessárias, e
de forma bastante cuidadosa.
2.7 Funções
Quando temos trechos de códigos que são repetidos várias vezes, podemos isolar estes tre-
chos em funções. Assim, podemos chamar uma função em diferentes pontos do programa
principal, evitando reescrever aquele trecho de código repetidamente.
Uma função deve ser declarada antes de ser chamada. Por isso é importante escrever
todas as novas funções antes da função principal (main). Por exemplo:
2 Definições Gerais em Linguagem C 9
2.8 Header
Em muitos compiladores, é necessário incluir um arquivo que contém todas as definições
do microcontrolador sendo utilizado. Isto é feito através do comando “#include”. Em geral,
temos a seguinte sintaxe que deve ser incluída logo no início de qualquer programa:
#include<microcontrolador.h>
Além deste arquivo com as definições do microcontrolador, podemos utiliza a instrução
“#include” para incluir algum arquivo denominado cabeçalho, contendo funções auxiliares
a serem utilizadas. Por exemplo:
#include<nome_do_arquivo.h>
3 Operadores 10
3 Operadores
A linguagem C possui operadores para atribuir, comparar ou modificar dados e variáveis.
Podemos dividir estes operadores em quatro categorias principais:
• Subtração:
int a = 10;
int b = 5;
int c = 0;
• Multiplicação:
int a = 1;
int b = 20;
int c = 2;
• Divisão:
int a = 0;
int b = 20;
int c = 2;
• Incremento em um:
int contagem = 0;
• Decremento em um:
int contagem = 0;
Exemplo:
void main()
{
unsigned char cont = 0;
while(1)
{
if (PORTA.B0 == 1) // Se o pino A0 estiver ligado
if (cont < 9)
cont++; /* Se contagem for maior que 9,
incrementa */
else
cont = 0; // Caso contrário, zera
}
}
• Exemplo 1:
int A = 0;
if ((A > 0) && (A < 10))
A++;
Significado: se A for maior do que zero E A for menor do que dez, então incremente
A em um.
3 Operadores 13
• Exemplo 2:
int A = 0;
int B = 0;
int C = 0;
if ((A != B) || (A != C))
A--;
• Exemplo 1:
int cont = 0;
if (PORTA.B0 & PORTA.B1)
cont++;
Significado: se PORTA.B0 for igual a um E PORTA.B1 for igual a um, então cont é
incrementado em uma unidade.
• Exemplo 2:
int cont = 0b00000001;
if (PORTA.B0 | PORTA.B1)
cont = cont<<1;
Significado: se PORTA.B0 for igual a um E PORTA.B1 não for igual a um, então o
valor de cont é decrementado de uma unidade.
3 Operadores 14
4 Estruturas Condicionais
4.1 A Estrutura if
A estrutura if, que significa “se” em português, é uma estrutura de decisão baseada no
resultado de um teste lógico. Sua forma geral é:
if (condição)
{
comando 1;
comando 2;
...
comando n;
}
Se houver apenas uma instrução a ser executada após o teste lógico, as chaves podem
desprezadas:
if (condição)
comando;
Caso haja mais de um comando if na sequência, o else estará sempre relacionado com
o último if. Por exemplo:
int i = 10;
int j = 5;
A estrutura if-else if é uma alternativa para tornar tomadas de decisões mais rápidas em
alguns casos, Isto ocorre porque, no momento em que alguma condição seja satisfeita, os
demais blocos if subsequentes não serão sequer testados.
4 Estruturas Condicionais 17
5 Estruturas de Repetição
Neste exemplo, a variável ’i’ é inicialmente carregada com o valor 0 (i = 0). Como
a condição inicial é verdadeira (i < 10), os comandos do laço são executados. Após a
execução dos comandos do laço, a variável ’i’ é incrementada em uma unidade, dada pela
condição de incremento ’i++’, e novamente os comandos do laço são executados. Isto é
feito até que a condição se torne falsa, isto é, quando ’i’ for igual a 10.
Ainda é possível utilizar o laço for em passos decrescentes. O mesmo código acima
pode ser escrito de maneira equivalente como:
for(i = 10; i > 0; i--)
{
PORTA.B0 = 1; // liga o pino A0
delay_ms(1000); // aguarda 1 segundo
PORTA.B0 = 0; // desliga o pino A0
delay_ms(1000); // aguarda 1 segundo
}
A diferença aqui é que os comandos são executados antes de se realizar o teste lógico
de condição. Caso o teste executado ao final seja verdadeiro, o laço é executado novamente
do início. Caso contrário, o programa segue com a instrução imediatamente após o laço.
6 Comentários Finais 21
6 Comentários Finais
Todo o material apresentado neste resumo é material de livre acesso, baseado nas notas de
aula disponíveis em http://paginapessoal.utfpr.edu.br/gbrante, bem como no livro “Progra-
mação Linguagem C para Microcontroladores 8051”, da iniciativa u8051, disponível em
http://www.u8051.com.br/.