Você está na página 1de 38

Desenvolvimento com microcontroladores Atmel AVR

Geovany A. Borges, Antnio Padilha Lanari Bo, Alexandre Simes Martins,


Leandro Csar Cotta, Maurlio Fernandes, Gabriel Freitas,
Ener Diniz Beckmann, Augusto Csar Coelho Felix

Laboratrio de Controle e Viso por Computador (LCVC)


Departamento de Engenharia Eltrica - ENE
Faculdade de Tecnologia - FT
Universidade de Braslia - UnB
Braslia - DF - Brasil
14 de junho de 2008

Resumo
Esta nota tcnica pretende auxiliar aqueles que do seus primeiros passos no desenvolvimento
de projetos com microcontroladores. Mais especificamente, ela deve servir como um guia introdutrio ao microcontrolador AVR ATmega8, da Atmel, descrevendo os procedimentos bsicos para
programao e algumas de suas funes bsicas.

Revises:
01/06/2008

11/06/2006

04/06/2006
17/01/2005

Atualizao do texto para a mais recente distribuio do WinAVR e correo no cdigo exemplo para conversor A/D
considerando a conexo usada no circuito de teste.
Pequenas alteraes (reduo do tamanho da fonte usada
para listagens de programas) e incluso de uma figura que
ilustra melhor a soldagem da placa da gravadora BSD com
o conector DB-25.
Reviso geral do texto, incluso de material sobre gravadora
BSD, LCD e terminal.
Primeira verso da nota tcnica sobre AVR

Sumrio
1 Introduo

2 O microcontrolador Atmel AVR ATmega8

3 Ferramentas de desenvolvimento
3.1 Hardware . . . . . . . . . . . . . . . .
3.1.1 Gravadora BSD . . . . . . . . .
3.1.2 Circuito de referncia . . . . .
3.1.3 Teste do hardware . . . . . . .
3.1.4 Observaes muito importantes
3.2 Software . . . . . . . . . . . . . . . . .
3.2.1 WinAVR . . . . . . . . . . . .
3.2.2 Programmers Notepad . . . . .
3.2.3 Avrdude . . . . . . . . . . . . .
3.2.4 avr-toochain . . . . . . . . . . .

.
.
.
.
.
.
.
.
.
.

4
4
4
7
9
10
11
11
11
12
13

4 Procedimentos bsicos de desenvolvimento


4.1 O primeiro projeto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.2 Registros de configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
4.3 Seleo da freqncia do relgio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

13
13
14
15

5 Funcionalidades particulares
5.1 Interrupes . . . . . . . . . . . . . . . . . . .
5.2 Temporizadores/Contadores (no revisado) .
5.2.1 Funes Peridicas . . . . . . . . . . .
5.2.2 PWM . . . . . . . . . . . . . . . . . .
5.3 Converso A/D . . . . . . . . . . . . . . . . .
5.4 Comunicao Serial (no revisado) . . . . . .
5.5 Usando o PC como terminal de teclado/vdeo
5.6 Display LCD . . . . . . . . . . . . . . . . . .

17
17
18
19
19
20
21
22
23

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

.
.
.
.
.
.
.
.

6 Concluses

24

A CD de iniciao ao AVR

26

B Iniciao rpida

26

C Referncias na Internet

26

D Exemplo de makefile

27

E Circuito de teste

37

Introduo

Em sistemas de Controle e Automao, so raros os exemplos em que no h necessidade do uso de


alguma unidade de processamento. De fato, a no ser que o sistema possua uma lgica extremamente
simples, se faz necessrio o uso de uma ou mais CPUs (Central Processing Unit). Isso inclui sistemas
que apresentam desde uma simples interface com o usurio por meio de um display LCD (Liquid
Cristal Display) at o complexo controle de um veculo aeroespacial.
Entretanto, definida a necessidade de se empregar um elemento processador no sistema, resta o
problema de definir qual plataforma utilizar. Entre as diversas disponveis, h CLPs (Controladores
Lgico-Programveis), FPGAs (Field-Programmable Gate Array), DSPs (Digital Signal Processing),
PCs (embarcados ou no), entre outras. Assim, a escolha do crebro do sistema deve se dar a partir
de um compromisso entre as diversas necessidades do projeto e as caractersticas apresentadas pelo
elemento processador, como custo, capacidade de processamento, memria, linguagem de programao
disponvel, capacidade de atuar em sistemas de controle em tempo real, consumo de energia, etc. Nesse
contexto, os microcontroladores geralmente se apresentam como uma das alternativas de menor custo,
confiabilidade satisfatria, simplicidade, menor tempo de desenvolvimento e menor consumo; porm
com limitada capacidade de processamento e memria.
Em termos gerais, os microcontroladores podem ser definidos como processadores que foram encapsulados com memria, interface de entrada/sada de dados e dispositivos perifricos. Entre os
perifricos esto conversores A/D (analgico/digital), temporizadores/contadores, interface para comunicao serial, watchdog programvel, etc. Em outras palavras, so computadores encapsulados
em um nico invlucro. Tornaram-se comuns em diversos ramos da indstria a partir do final da
dcada de 70 e atualmente existe um nmero crescente de opes disponveis no mercado.
Esta nota tcnica pretende apresentar uma introduo ao desenvolvimento de projetos empregando a famlia de microcontroladores AVR da Atmel, em especial o modelo ATmega8, muito utilizado em pequenos projetos do Grupo de Robtica, Automao e Viso Computacional (GRAV) da
Universidade de Braslia. Uma nfase ser dada utilizao da linguagem C na programao do
microcontrolador.
Para os que tm alguma experincia com o AVR, ou mesmo para aqueles mais apressados, o Anexo
B apresenta os procedimentos para uma iniciao rpida.

O microcontrolador Atmel AVR ATmega8

Nesta seo, se pretende apresentar brevemente as caractersticas principais do funcionamento deste


microcontrolador. Grande parte das informaes aqui fornecidas foram obtidas do manual do ATmega8 [Atmel 2004], doravante denominado AVR, ATmega8 ou simplesmente microcontrolador. Este
documento deve ser, de fato, o ponto de partida na busca de informaes que no se encontram nesta
nota tcnica. Porm, as informaes esto aqui transcritas com uma maior clareza na exposio, bem
como acompanhadas por algumas alteraes visando facilitar a iniciao ao uso do dispositivo.
O ATmega8 um microcontrolador 8-bit de tecnologia CMOS e arquitetura RISC. Uma caracterstica interessante deste dispositivo sua capacidade de executar uma instruo por ciclo de relgio.
Esta taxa de execuo de instrues foi possvel de ser alcanada em virtude da conexo direta de
seus 32 registradores de propsito geral com a unidade lgica aritmtica. Esta caractersta o deixa
em vantagem quando comparado com os concorrentes da famlia PIC da Microchip Technology. Alm
do mais, apesar de ser RISC, possui um grande nmero de instrues (130), o que permite melhor
otimizao de cdigo de alto nvel em linguagem C. Isso significa que deve haver pouca diferena de
tamanho entre um cdigo C e o seu equivalente direto escrito em assembly. Por outro lado, sempre
que se usar linguagem C para sistemas embarcados, deve-se ter em mente que os recursos de memria
so bastante limitados, de forma que boas prticas para sistemas embarcados devem ser usadas.
Com o objetivo de maximizar o desempenho e o paralelismo, o AVR segue arquitetura Harvard,
em que os barramentos associados s memrias de dados e do programa so distintos. Alm disso,

utiliza-se a tcnica do pipeline, em que, enquanto uma instruo comea a ser executada, uma outra
j buscada na memria de programa para que a mesma possa ser executada no prximo ciclo de
relgio. A Figura 1 ilustra o diagrama de blocos do microcontrolador [Atmel 2004].

Ferramentas de desenvolvimento

3.1

Hardware

Para desenvolvimento com o ATmega8, o hardware mnimo sugerido dado por um circuito de
referncia e pela gravadora BSD, mostrados na Figura 2. O circuito de referncia contm o mnimo
para o o ATmega8 funcionar apropriadamente, podendo ser conectado diretamente a uma protoboard
para desenvolvimento. A gravadora possui um conector para o circuito de referncia e um outro para
porta paralela de microcomputadores PC. As sees seguintes apresentam seus circuitos e descrevem
os procedimentos de montagem.
3.1.1

Gravadora BSD

A gravadora um circuito faz a interface entre o microcomputador e o microcontrolador, realizando


as tarefas de programao e configurao. Elas so projetadas de acordo com as particularidades
tcnicas de cada microcontrolador e utilizam geralmente as portas serial ou paralela do PC. Para o
caso do AVR, existem alguns modelos comerciais, mas tambm existem muitos outros gratuitos, que
podem ser montados sem muita dificuldade. No caso do LCVC, costuma-se utilizar a gravadora BSD.
Seu diagrama esquemtico est disponvel na Figura 3. A gravadora conectada ao microcomputador
pela porta paralela, e ao microcontrolador por meio de um flat cable com conector de 10 pinos na
extremidade. Sua alimentao proveniente do circuito em que a gravadora ser conectada. Os pinos
9 e 10 do conector da gravadora no devem ser usados. desta forma, se o usurio cometer o erro de
inverter o conector, isto no deve causar a queima de componentes.
Para montar a gravadora, so necessrios os seguintes componentes (c.f. Figura 4):
1 placa de circuito impresso confeccionada para a gravadora BSD;
1 circuito integrado 74LS367;
1 resistor de 4k7 a 6k8, 1/8W;
1 capacitor eletroltico 10uF 16V, encapsulamento radial de tamanho mini;
1 conector DB-25 macho com capa plstica;
1 conector header 5x2;
70 cm de flat cable c/ 10 fios;
fios para jumpers, normalmente so fios de instalao telefnica ou de cabo de rede;
Para a BSD, sugere-se o layout da Figura 5(a). Essa placa soldada diretamente a um conector
DB-25 macho, utilizado para conectar porta paralela de um PC. Conforme as setas em azul na
Figura 5(b), os quatro furos mais esquerda so para conexes por meio de fios com os pinos 7, 8 , 9
e 10 do DB-25. J nos oito furos direita, so soldados cada fio do flat cable, tomando-se o cuidado
que o terceiro fio trocado com o quinto. Ainda na Figura 5(b), a linha vermelha vertical um fio
que une os dois furos nos extremos da placa e tambm fica na parte superior da mesma. O 74LS367
soldado direto na placa, sem soquete, sendo que o pino 1 o que est mais prximo do resitor de
6k8.
Para a soldagem do conector DB-25, deve-se colocar a placa entre os pinos inferiores e superiores do
conector, conforme mostras as Figuras 5(c)-(e). A face do cobre est voltada para os pinos inferiores

Figura 1: Diagrama de blocos do microcontrolador [Atmel 2004].

Figura 2: Foto do circuito de referncia para protoboard e gravadora BSD.

Figura 3: Diagrama esquemtico da gravadora BSD.

Figura 4: Material para montagem da gravadora BSD


(14 a 25). Certifique-se de que a placa est bem centralizada no mesmo e solde os pinos de 18 a 25
uns aos outros, conforme a Figura 5(c). Na placa, a face do cobre deve alcanar do pino 19 ao 23,
que devem ser soldados placa. Por ltimo, para colocao do conector no flat cable, deve-se tomar
cuidado para que o fio 1 do cabo corresponda ao pino 1 do conector, indicado por uma pequena seta
em relevo, conforme mostra a Figura 5(f).
3.1.2

Circuito de referncia

O circuito de referncia um circuito que serve de base para o desenvolvimento com o ATmega8. Nele
esto os capacitores de desacoplamento para alimentao e conversor A/D, assim como um conector
header para a gravadora BSD. Neste documento prope-se o esquemtico da Figura 6. Neste circuito,
o cristal opcional, devendo este ser usado quando a fonte de relgio da CPU for cristal externo.
De forma similar gravadora BSD, sugere-se uma placa de circuito impressso para o circuito de
referncia. Esta placa foi concebida de modo a permitir que o circuito de referncia seja inserido em
protoboard, facilitando assim o desenvolvimento com o ATmega8. Para a montagem desse mdulo,
so necessrios os seguintes componentes (c.f. Figura 7(a)):
1 placa de circuito impresso confeccionada para o circuito de referncia;
2 soquetes DIP14 torneados. Em conjunto, os dois soquetes formam um soquete de 28 pinos
estreito, difcil de ser encontrado no Brasil;
1 cristal de quatzo de no mximo 16MHz (opcional, se utilizar cristal externo como fonte de
relgio);
1 barra de soquete torneado com 3 pinos (suporte do cristal);
2 capacitores de 100 nF, cermico ou polister;
2 capacitores cermicos de 22 pF;
2 barras de pinos simples header, 14 pinos cada. Cada barra deve ter seus pinos rebaixados,
ficando rentes ao plstico de suporte, usando um alicate de bico como mostrado na Figura 7(b);
1 barra de pinos dupla, 2 x 5 pinos, para receber o conector da gravadora BSD;
fios para jumpers, normalmente so fios de instalao telefnica.

(a) Layout inferior

(b) Face superior (fazer ateno com a seqncia dos


fios do flat cable)

(c) Insero da placa entre os pinos


do conector DB-25

(d) Montagem superior

(e) Montagem inferior

(f) Conector

Figura 5: Placa da gravadora BSD e sua montagem no conector DB-25.

Figura 6: Circuito de referncia para o ATmega8

(a) Componentes

(b) Alterao das barras de terminais de 14 pinos

Figura 7: Material para montagem do circuito de referncia ATmega8


O layout da placa de referncia mostrado na Figura 8(a). A disposio dos componentes
mostrada na Figura 8(b). Deve ser observado que tem uma barra de pinos logo abaixo do soquete
do microcontrolador, devendo esta barra ser soldada antes dos soquetes DIP14. Para a montagem, a
dica soldar primeiro os componentes mais baixos e do centro, deixando por ltimo os componentes
prximo s bordas. Assim, deve-se comear soldando os fios de ponte, que so as linhas vermelhas
na Figura 8(b). Depois, devem ser soldadas as barras de pinos simples. , porm, antes de sold-las
empurre todos os pinos de modo que fiquem rentes ao plstico. Finalmente solde os soquetes, os
capacitores e a barra de pinos dupla.
As Figuras 8(c)-(d) mostram a placa finalizada. interessante usar uma caneta de retroprojetor
para marcar o pino 1 do header para conexo com a gravadora. Nesse caso, o pino 1 o que est
mais prximo do pino 1 do ATmega8.
Conforme mencionado antes, a placa do circuito de referncia foi concebida para ser inserida em
um protoboard. Para poder usar a placa, ainda faz-se necessrio conectar a alimentao. Com a placa
no protoboard, deve-se conectar VCC (5V) ao pino 7 e GND (0V) ao pino 8 do ATmega8. Estes
pinos so conectados protoboard por meio das barras de terminais de 14 pinos.
3.1.3

Teste do hardware

Para testar a gravadora e o circuito de referncia, sugere-se seguir os seguintes passos:


Coloque a placa de referncia a uma protoboard, e conecte a alimentao. No ligar ainda a
fonte de alimentao;
Conecte a gravadora BSD na placa de referncia;

(a) Layout inferior

(c) Vista superior

(b) Face superior

(d) Vista inferior

(e) Vista lateral

Figura 8: Montagem do circuito de referncia ATmega8


Certifique-se que a porta paralela est operando no modo padro (SPP, ou Standard Parallel
Port). Para verificar isto, deve-se reiniciar o microcomputador e entrar no programa de configurao da BIOS. Em geral esta informao encontra-se em um menu de perifrios. Se a porta
paralela estiver configurada para qualquer outro modo, deve-se alterar a configurao para SPP,
sair do programa monitor da BIOS salvando a nova configurao, e reiniciar o microcomputador;
Conecte a gravadora BSD na porta paralela do microcomputador;
Ligue a fonte de alimentao do circuito de referncia. A gravadora tem sua alimentao proveniente do circuito de referncia.
Certifique-se que o programa Avrdude est configurado corretamente (ver Seo 3.2.3);
Execute avrdude.exe que est no diretrio WinAVR/bin com as seguintes opes:
avrdude.exe -p atmega8 -c bsd -P lpt1 -t -u
Se aparecer logo no incio a mensagem avrdude: AVR device not responding ou algo similar,
ento algo est errado. Reveja todos os passos de montagem da gravadora e do circuito de
referncia.
3.1.4

Observaes muito importantes

Nunca se deve desconectar a gravadora do circuito (ou do PC) com o Atmega8 ligado. Este procedimento pode gerar gravao do registro LFUSE para o valor 00h (hexadecimal), que leva o microcontrolador a operar somente com fonte de relgio externa. Isto impossibilita a gravao do ATmega8
com qualquer outra fonte de relgio, inclusive a que vinha sendo usada. Para recuperar o microcontrolador, deve-se construir um oscilador externo a 1MHz, conect-lo ao ATmega8, e usar o avrdude.exe
no modo unsafe para alterar o contedo de LFUSE (e possivelmente HFUSE).

10

3.2

Software

Tendo disponveis a gravadora e o circuito do microcontrolador, deve-se providenciar o ambiente computacional que se comunicar com o dispositivo de acordo com o protocolo estabelecido pelo fabricante.
De fato, necessita-se ao menos de um compilador e/ou um montador para o microcontrolador, e um
programa responsvel pela gravao do dispositivo por meio do hadware da gravadora.
No caso do LCVC, utiliza-se largamente o WinAVR, um pacote de programas em cdigo aberto
para desenvolvimento com microcontroladores da famlia AVR da Atmel no ambiente Windows, que
inclui um editor de texto, debugger, bibliotecas em C, entre outros. Entre os programas mais importantes que acompanham o pacote, so descritos a seguir:
Programmers Notepad: Ambiente Integrado de Desenvolvimento, que gratuito, e permite ser
configurado para trabalhar com as ferramentas de desenvolvimento AVR;
Avrdude: programa de gerenciamento da gravadora em linha de comando DOS, que permite
gravar o dispositivo, ler seu contedo e alterar os registros de configurao da famlia AVR;
avr-toochain: Na verdade, isto no um programa mas um conjunto de ferramentas necessrias
para compilar um programa para o AVR utilizando ferramentas GNU (software livre).
3.2.1

WinAVR

Como mencionado anteriormente, o WinAVR um pacote de vrios softwares utilitrios para desenvolvimento com a famlia AVR. O site da distribuio http://winavr.sourceforge.net/. Sua
instalao trivial, bastando seguir os passos indicados pelo programa de instalao. Entretanto,
no caso de Windows 2000/XP, faz-se necessrio ter privilgios de administrador do sistema. Aps
instalao, criado o diretrio WinAVR na raiz de algum disco do microcomputador, assim como
\WinAVR\bin;\WinAVR\utils\bin; inserido na varivel de ambiente PATH. Se os programas que
compem o WinAVR no funcionarem aps instalao, deve-ser verificar se a varivel PATH foi realmente alterada. Caso no, sua alterao deve ser feita manualmente.
Ap[os a instalao do WinAVR, recomenda-se uma leitura do seu manual, acessvel no menu de
programas.
3.2.2

Programmers Notepad

Programmers Notepad 2 (PN) uma ambiente de desenvolvimento integrado (IDE, do ingls) que
acompanha o pacote. Atravs do PN possvel criar um projeto, que composto de um ou mais
arquivos, editar os arquivos e compilar o projeto. A Figura 9 mostra o PC aberto com um projeto,
em que se v os arquivos que compem o projeto (main.c e makefile), o arquivo main.c aberto para
edio com diferentes cores para as estruturas do programa em linguagem C, e uma janela de sada,
que contm mensagens de compilao.
Quando instalado, o PN deve ser o programa default para abrir arquivos com a extenso .pnproj,
que a extenso do arquivo principal de um projeto. Os passos para criar um novo projeto so os
seguintes:
Execute pn.exe, que est no diretrio \WinAVR\pn ou acessvel atravs da barra de ferramentas
WinAVR do Windows;
No PN, crie um novo projeto atravs do menu File -> New -> Project. Uma janela deve abrir
para o usurio entrar com o nome do projeto, que receber a extenso .pnproj, assim como
sual locao;
No espao do projeto (lado esquerdo da interface) pode-se incluir arquivos no projeto clicando
no boto direito do mouse que deve estar posicionado sobre o nome do projeto. Suger-se que
sejam includos todos os arquivos .c e .h que compem o projeto, e o arquivo makefile. Ao

11

Figura 9: Programmers Notepad 2 com um projeto aberto.


estarem presentes no espao do projeto, estes arquivos podem ser facilmente abertos clicando
com o boto direito do mouse sobre seus nomes;
Com um arquivo em linguagem C aberto para edio, o menu Tools exibe as opes [WinAVR]
Make All, [WinAVR] Make Clean e [WinAVR] Make Program. Ao clicar em qualquer uma destas opes, o programa make.exe chamado com as opes make all, make clean e make
program, respectivamente. A primeira destas opes inicia os procedimentos de compilao
guiada pelo arquivo makefile. Um exemplo de arquivo makefile apresentado e discutido no
Anexo D. Sua compreenso essencial para iniciar o desenvolvimento de novos projetos. O
resultado da compilao um arquivo .hex que a imagem que deve ser gravada no microcontrolador pelo utilitrio avrdude.

3.2.3

Avrdude

A gravadora BSD nada mais do que uma pea de hardware que precisa ser comandada por um
programa. Um destes programas o Avrdude, que um programa que permite gerenciar vrias gravadoras, entre elas a BSD. O Avrdude disponibilizado no diretrio WinAVR/bin como avrdude.exe,
que opera em linha de comando. Alm de poder lere escrever programas na memria flash do microcontrolador, o Avrdude tambm permite alterar registros de configurao. A Seo 4.2 descreve com
mais detalhe alguns procedimentos bsicos de uso do avrdude.exe. Ao leitor recomenda-se consultar
o manual do avrdude.exe que acompanha o CD de iniciao ao AVR (ver Anexo A).
Para qualquer verso do Avrdude, se estiver usando qualquer verso do Windows diferente do Windows 98, o driver GiveIO dever est instalado. Instale GuiveIO executando install_giveio.bat
do diretrio WinAVR/bin.

12

3.2.4

avr-toochain

O projeto GNU (GNU is not GNU)1 foi iniciado em 1984 por Richard Stallman com o objetivo
de criar um sistema operacional totalmente livre, alm de ferramentas para desenvolvimento. O
projeto iniciou com as ferramentas, e abraou o sistema operacional Linux em 1991 como alvo dos
desenvolvimentos. Entretanto, muitas das ferramentas tambm funcionam no Windows, permitindo
assim uma maior difuso do software livre. Desta forma, possvel desenvolver programas para vrios
microprocessadores e microcontroladores sem a necessidade de comprar ferramentas comerciais. Para
o caso do AVR, tem-se, entre outras ferramentas, o avr-gcc (compilador C), avr-g++ (compilador
C++), avr-as (assembler) e avr-ld (linker). No WinAVR, estas ferramentas esto instaladas no
diretrio \WinAVR\bin.
As ferramentas GNU no so descritas em detalhe nesta verso do documento. Uma descrio
detalhada feita no site http://www.gnu.org/manual/manual.html, em que tem-se apenas o nome
da ferramenta sem o prefixo avr-.
Com a instalao do WinAVR, na barra de ferramentas criada uma pasta WinAVR com alguns links, entre eles o avr-libc manual. Este link aponta para o arquivo \WinAVR\doc\avr-libc\
avr-libc-user-manual\index.html que o manual da biblioteca LibC para a famlia AVR. LibC
a na verdade um conjunto de bibliotecas bsicas para se trabalhar com linguagem C/C++ para a
famlia AVR. O manual da biblioteca LibC sempre bastante consultado para desenvolvimento.

Procedimentos bsicos de desenvolvimento

4.1

O primeiro projeto

Cabe dizer, neste momento, que esta nota tcnica trata apenas do desenvolvimento de projetos em
linguagem C. Para aqueles que gostariam de trabalhar com linguagem assembly, a principal diferena
est que os arquivos fonte possuem extenso .s, mudando muito pouco a nvel do processo de construo da imagem hexadecimal a ser programada no microcontrolador. Porm, cabe colocar que a
escolha pela programao em assembly no gera tantos benefcios em termos de desempenho quanto
se obtm em outros microcontroladores, principalmente devido (i) ao grande nmero de instrues
RISC da famlia AVR e (ii) porque o compilador da linguagem C (i.e., gcc) bastante eficiente e
foi amplamente testado. Entretanto, existe espao para que trechos de cdigo sejam escritos em assembly, principalmente se for desejado fazer manipulaes diretamente em registradores da CPU ou
realizar operaes de muito baixo nvel, no permitidas pela linguagem C.
Considerando o circuito da Figura 12 no Anexo E, sugere-se um simples programa para acender intermitentemente um LED ligado a uma porta de E/S do microcontrolador. O algoritmo
extremamente simples e no requer maiores explicaes alm daquelas disponveis no cdigo, listado
logo abaixo. De fato, o programa simplesmente liga e desliga o LED a um perodo que depende da
constante TROCA. As montagem do circuito necessrio para a visualizao do resultado composto
unicamente pela ligao do LED e de um resistor de 220 entre o pino 5 (PD3) e +5V, conforme
mostrado no circuito 12.
#include <inttypes.h>
#include <avr/io.h>
#define TROCA 10000
void main (void) {
int cont = 0;
DDRD |= _BV(DDD3); /* Neste comando seta-se o pino correspondente
como pino de sada. Poderia-se
obter o mesmo efeito com o comando
1

Para entender melhor o porqu desta sigla, sugere-se uma consulta ao site http://pt.wikipedia.org/wiki/GNU

13

DDRD |= 0x04; */
for(;;){
cont++;
if (cont == TROCA){
cont = 0;
PORTD = ~PORTD;
}
}
}

Se denominarmos o programa acima de teste.c, ele deve fazer parte de um projeto do Programmers Notepad, conforme explicado na Seo 3.2.2. Um exemplo de makefile mostrado no Anexo D.
Entretanto, aquele arquivo precisa sofrer uma alterao para funcionar corretamente com o projeto:
O comando TARGET = testportb deve ser alterado de modo a conter o nome do projeto, do
ser gerado o aquivo .hex. No necessrio que o nome do projeto seja o mesmo do arquivo
fonte principal. Por exemplo, se fizer TARGET = projeto, o resultado final da compilao ser
o arquivo projeto.hex;
O comando OPT = s indica que o arquivo final gerado ser o de menor tamanho possvel (size
optimization), sem no entanto ser mais rpido. Entretanto, OPT = 0 corresponde a no haver
otimizao de cdigo e OPT = 2 resulta em geral em cdigo mais rpido;
O comando SRC = main.c deve conter o nome do arquivo principal do projeto. No caso em
questo, deve-se fazer SRC = teste.c. Se o projeto for modular, todos os arquivos fonte devem
ser enumerados aqui.
Com as alteraes acima, o programa est pronto para ser compilado atravs da opo [WinAVR]
Make All do menu Tools. Se nenhum erro ocorrer, o resultado projeto.hex poder ser gravado
no microcontrolador usando o programa Avrdude. Para tanto, basta chamar a opo [WinAVR]
Program do menu Tools.

4.2

Registros de configurao

O ATmega8 possui alguns registros de configurao que no so acessveis pelo programa gravado na
memria flash. Estes registros definem a configurao de hardware do microcontrolador, habilitando
ou no algumas de suas caractersticas. Estes registros so descritos na seo Memory Programming
do manual [Atmel 2004]. So registros de proteo de cdigo e dados (Lock bit byte), fusveis de
configurao (Fuse High byte e Fuse Low Byte), bytes de assinatura do dispositivo e byte de calibrao do oscilador interno. Destes registros, um dos mais usados o Fuse Low byte pois determina
principalmente a principal fonte de relgio da CPU.
Para alterar qualquer um dos registros de configurao, isto somente pode ser feito atravs do
programa avrdude.exe operando no modo unsafe (opo -u). Por exemplo, a seqncia de operaes
abaixo permite obter os valores gravados nos registros Fuse High byte (hfuse no avrdude) e Fuse Low
byte (lfuse no avrdude):
C:\>avrdude.exe -p atmega8 -c bsd -P lpt1 -t -u
avrdude.exe: AVR device initialized and ready to accept instructions
Reading | ################################################## | 100% 0.00s
avrdude.exe: Device signature = 0x1e9307
avrdude> d hfuse
>>> d hfuse
0000 d9 |+ |
avrdude> d lfuse
>>> d lfuse

14

Figura 10: Distribuio dos relgios [Atmel 2004].


0000 e1 |b |
avrdude> quit
>>> quit
avrdude.exe done. Thank you.
No exemplo acima, a opo -t permite entrar no modo terminal, em que o usurio usa alguns
comandos para manipular os registros. Para conhecer melhor o avrdude, sugere-se uma leitura no
manual avrdude.pdf que se encontra no diretrio Docs\Avrdude do CD de iniciao.
Um procedimento comum consiste em alterar o valor do Fuse Low byte para redefinir a fonte
de relgio do microcontrolador. Isto pode ser feito no modo terminal como no exemplo acima, mas
tambm usando linha de comando atravs de
C:\>avrdude.exe -p atmega8 -c bsd -P lpt1 -t -U lfuse:w:0xef:m
Este comando muda a fonte de relgio para cristal externo, o que permite fazer o ATmega8 operar
a at 16MHz. A fonte de relgio definida por alguns bits do registro lfuse, conforme mostrado na
prxima seo.

4.3

Seleo da freqncia do relgio

A freqncia do relgio determina, em ltima instncia, a velocidade de execuo do programa no


microcontrolador. No microcontrolador AVR, o sinal de relgio pode ser obtido atravs de cinco
diferentes fontes (ver Figura 10):
Circuito RC interno calibrado, que um circuito que gera algumas freqncias padro utilizando
um oscilador interno baseado em resistor e capacitor. A preciso da ordem de 3%;
Cristal externo, segundo conexo mostrada na Figura 11(a). Esta fonte de relgio a de
maior preciso, podendo chegar a at 16MHz. Quando o bit CKOPT do registro Fuse High
byte programado em 0, a sada XTAL2 possui faixa de variao de 0 a VCC, tornando o

15

(a)

(b)

(c)

Figura 11: Conexes de fontes externas de relgio: (a) Cristal/ressonador externo, C1 = C2 = 22pF,
(b) Circuito RC externo com freqncia dada por f = 1/(3RC) e (c) Oscilador externo [Atmel 2004].
microcontrolador mais imune a interferncia externa e permitindo XTAL2 ser conectado a uma
porta CMOS/TTL. Por outro lado, com CKOPT programado em 1, a faixa de variao de
XTAL2 bem pequena, o que implica tambm em menor consumo de energia;
Circuito RC externo, que requer um resistor e capacitor ligados externamente conforme mostrado na Figura 11(b). A freqncia do relgio passa a ser f = 1/(3RC), mas com pequena
preciso. Esta configurao interessante quando se deseja trabalhar com baixas freqncias,
o que implica em muito baixo consumo;
Oscilador externo, que gera uma onda quadrada a ser aplicada ao pino 9 (XTAL1) do Atmega8,
conforme mostrado na Figura 11(c). O perodo da onda quadrada no pode sofre alterao de
mais de 2% de seu perodo entre dois ciclos consecutivos. Se isto ocorrer, o comportamento do
microcontrolador ser imprevisvel;
Ressonador cermico externo, que apresenta o mesmo tipo de conexo que o modo cristal externo. Ressonadores cermicos so mais baratos, embora no to precisos quanto cristais de
quartzo.
Ainda de acordo com a Figura 10, cada um dos sinais de relgio gerados pode ser desligado
independentemente (ver seo Power Managament and Sleep Modes, em [Atmel 2004]). Alm disso,
importante destacar que o Watchdog Timer, que funciona como um dispositivo de proteo que
reinicia o microcontrolador aps o no cumprimento de determinada condio em um intervalo de
tempo especificado, conectado diretamente fonte de relgio, e no Unidade de Controle do
Relgio, para proporcionar maior confiabilidade ao sistema.
Deve ser observado que o ATmega8 j vem de fbrica configurado para fonte de relgio dada pelo
circuito RC interno a 1MHz [Atmel 2004]. Para alterar a fonte de relgio a ser utilizada, deve-se
escrever no registro de configurao Fuse Low Byte, conforme ilustrado pela Seo 4.2. A Tabela
1 apresenta as fontes de relgio e o contedo que deve conter os bits CKOPT (registro Fuse High
Byte) e CKSEL3, CKSEL2, CKSEL1 e CKSEL0 (registro Fuse Low Byte). Algumas vezes, alguma
efeito externo provoca a gravao do Fuse Low Byte para 00h, que implica no uso de fonte externa
de relgio. Se isto ocorrer, um procedimento que vem sendo usado no LCVC consiste em aplicar uma
onda quadrada de aproximadamente 1MHz em XTAL1 e refazer a programao dos registros usando
o avrdude.exe.
Uma vez alterada a fonte do relgio, a alterao somente tem efeito aps reiniciar o microcontrolador. Isto significa que da prxima vez que avrdude for usado para gravao, a nova fonte de relgio
j passa a ser utilizada. O mesmo ocorre com o programa da Flash, que passa a operar com a nova
fonte de relgio selecionada.

16

Tabela 1: Seleo da fonte de relgio e bits CKOPT, CKSEL3..0 do registro Low Fuse Byte.
Fonte de relgio
Oscilador externo no pino 9 (XTAL1)
Circuito RC interno calibrado
Circuito RC interno calibrado
Circuito RC interno calibrado
Circuito RC interno calibrado
Circuito RC externo
Circuito RC externo
Circuito RC externo
Circuito RC externo
Cristal externo (baixa freqncia)
Cristal externo (mdia freqncia)
Cristal externo (alta freqncia)
Ressonador cermico externo

Freqncia
0 - 16 MHz
1,0 MHz
2,0 MHz
4,0 MHz
8,0 MHz
< 0,9 MHz
0,9 MHz - 3,0 MHz
3,0 MHz - 8,0 MHz
8,0 MHz - 12,0 MHz
alguns KHz
0,9 MHz - 3,0 MHz
3,0 MHz - 16,0 MHz
0,4 MHz - 0,9 MHz

Bit
CKOPT
X
X
X
X
X
X
X
X
X
X
X
X
1

3
0
0
0
0
0
0
0
0
1
1
1
1
1

CKSEL
2 1 0
0 0 0
0 0 1
0 1 0
0 1 1
1 0 0
1 0 1
1 1 0
1 1 1
0 0 0
0 0 1
1 0 1
1 1 1
0 1 0

Funcionalidades particulares

Esta seo pretende ilustrar o uso de algumas das principais funes disponibilizadas pelo AVR. Essas
funes so, em alguns casos, implementaes em hardware de funcionalidades que at poderiam ser
executadas por software, mas que, dessa forma, poderiam resultar em um cdigo bastante complexo,
alm de um custo computacional consideravelmente maior.

5.1

Interrupes

Um aspecto muito importante na utilizao de um microcontrolador o tratamento das interrupes,


que podem ser tanto internas quanto externas. Pode-se descrever interrupes como sendo desvios
condicionais efetuados pelo programa em funo da ocorrncia de um fenmeno prioritrio ocorrido em
um determinado instante. As interrupes so muito importantes, pois elas permitem o processamento
adequado em resposta a eventos internos ou externos, aumentado a possibilidade de interao com o
meio.
De acordo com [Atmel 2004], como medida de segurana, existe para cada interrupo um vetor de
registradores nico. Essa configurao impede a execuo de uma nova instncia da mesma interrupo quando outra estiver sendo executada. Um outro fato importante a existncia de prioridades na
execuo das interrupes, ou seja, caso a prioridade de uma interrupo seja maior que a de outra,
o seu endereo colocada no vetor geral de interrupo como prioritria e conseqentemente ser
processada primeiro em caso dos eventos ocorrerem simultaneamente.
Para cada fonte de interrupo, existe um bit responsvel por sua habilitao. Este bit fica em
algum dos registros do perifrico associado interrupo. Mas tambm existe o bit I do registro SREG
(registro de estado do microcontrolador) que, quando setado em 1, habilita a ocorrncia de qualquer
interrupo que tenha sido habilitada em seu perifrico reponsvel. Se este bit for colocado em 0,
ento nenhuma solicitao de interrupo ser atendida, mesmo se a interrupo for habilitada em seu
perifrico. Se ocorrer uma solicitao de interrupo habilitada com o bit I em 0, ento o atendimento
somente ocorrer quando o bit I for colocado em 1. Para garantir atomicidade no procedimento
de alterao do bit I em linguagem C, deve-se usar as funes sei() e cli(), que correspondem
s instrues assembly sei (set I bit) e cli (clear I bit). Asism, sei() habilita globalmente as
interrupes, enquanto que cli() desabilita globalmente as interrupes.
Nesta seo sero tratadas apenas as interrupes externas, visto que a maior parte dos outras
interrupes disponveis esto relacionadas s funcionalidades descritas nas prximas sees. Para

17

configurar uma interrupo externa, necessrio atentar aos registradores MCUCR e GICR. O registrador MCUCR contm os bits que configuram o modo de ativao das interrupes 0 e 1, que
so associadas a eventos externos. Em outras palavras, alterando os bits ISCxx, segundo o External
Interrupts de [Atmel 2004], pode-se configurar a interrupo para ocorrer quando h transio de
subida ou de descida do sinal, ou mesmo quando ele se mantm em nvel baixo. J o registrador
GICR aquele em que se permite a ocorrncia de determinada interrupo, por meio dos bits INT1
e INT0.
O trecho de cdigo abaixo ilustra um simples exemplo de utilizao de interrupes: utiliza-se um
boto para alterar o estado de um LED.
...
SIGNAL(SIG_INTERRUPT0){ // Funcao que responde aa interrupcao externa 0
PORTB = ~PORTB;
}
void main(void){
// Configurando a interrupcao
MCUCR = _BV(ISC01) | _BV(ISC00); // Transicao positiva em PD2 (INT0)
GICR = _BV(INT0); // habilita interrupcao INT0
sei(); // habilitacao global das interrupcoes
// Definindo Port B como sada
DDRB = _BV(DDB1);
for(;;){
}
}
Um outro uso das interrupes externas a emulao da instruo assembly SWI (Software Interrupt), que no existe no conjunto de instrues do AVR. Para tal, basta setar o pino PD2 como sada
e ativar a interrupo INT0, por exemplo. Nesta situao, poder executar o cdigo da interrupo
controlando o estado do pino PD2 por meio de instrues de escrita a este pino.
No programa acima, a macro SIGNAL(SIG_INTERRUPT0) permite definir a funo que far o processamento da interrupo externa 0 quando ela ocorrer. De acordo com o manual da biblioteca LibC,
disponvel em \WinAVR\doc\avr-libc\avr-libc-user-manual\index.html, existem duas macros
para definir a funo que ir tratar uma determinada interrupo: SIGNAL() e INTERRUPT(). A principal diferena entre as duas que INTERRUPT() define uma funo de processamento de interrupo
que executada com a mscara global de interrupes ativada, o que permite que outras interrupes
ocorram durante a execuo da rotina de interrupo. Se isto ocorrer, diz-se que o sistema permite
ninho de interrupes. Com SIGNAL(), a mscara global de interrupes desativada, impedindo
assim o atendimento de outras interrupes durante a execuo da rotina de interrupo. Se ocorrer
uma solicitao de interrupo durante a execuo de uma rotina SIGNAL(), a mesma somente ser
atendida quando a rotina atual se encerrar. A desvantagem do uso de SIGNAL() est em um maior
atraso ao atendimento de interrupes, mas isto apresneta vantagem pois reduz a necessidade de
quantidade de memria RAM necessria para armazenar o contexto das instncias interrompidas.

5.2

Temporizadores/Contadores (no revisado)

O microcontrolador possui trs temporizadores, sendo dois de 8 bits e um de 16 bits. O mais simples
deles o timer/counter 0. Ele no possui mdulo comparador, o que no possibilita que seja utilizado
um evento externo para modificar o estado do contador. Um exemplo da aplicao deste mdulo
a gerao de sinais PWM (Pulse Width Modulation), muito utilizado para o controle de velocidade
de motores DC. Essa operao pode, entretanto, ser efetuada por software, acarretando maior custo
computacional.

18

Cada um desses dispositivos pode ser controlado tanto por uma fonte interna ou externa de
relgio. Na maior parte dos casos, entretanto, em que se deseja alterar a base de tempo do timer,
utiliza-se a mesma fonte de relgio do programa conjuntamente com o chamado prescaler, que se trata
basicamente de um divisor de freqncia que altera o perodo de atualizao do timer. A definio
do valor do prescaler feita por meio do registrador TCCRX. Caso o relgio de referncia seja 8, 000
M Hz e o prescaler seja configurado em 8, por exemplo, a freqncia resultante ser dada por:
f=
5.2.1

8 M Hz
= 1 M Hz
8

Funes Peridicas

Uma das interessantes aplicaes dos timers/counters disponveis no AVR a gerao de funes
peridicas. Essas funes podem ser utilizadas tanto para aquisio de dados e atuao em sistemas
de controle de acordo com taxas de amostragem de perodo fixo, quanto para contagem de pulsos em
determinado intervalo de tempo para medio de velocidade de rotao de um motor, por exemplo.
Mais especificamente, a funo peridica nada mais do que um interrupo gerada pelo temporizador quando este atinge o valor mximo de contagem (overflow ). Para o caso do timer 0, por
exemplo, para ativar esta funo, basta garantir que o bit TOIE0 do registrador TIMSK esteja escrito
com o valor 1. Desta forma, no momento em que o contador ultrapassar seu valor mximo, ser executado o cdigo contido na macro SIGNAL(TIMER _OVERFLOW0). Caso o relgio de referncia
seja 8.000KHz e o prescaler seja configurado em 8, por exemplo, o perodo de amostragem da funo
ser dado por:
Ta =

8000
8 256

1

= 0, 256 ms

Caso seja do interesse utilizar taxas de amostragem mais precisas, alm de alterar os valores do
relgio e do prescaler, pode-se, por exemplo, escrever determinado valor no registrador TCNT0 toda
vez em que ocorrer o sinal de overflow. Assim, cada contagem se dar a partir do valor escrito, e no
do zero, que o padro.
A configurao destas funcionalidades nos outros dois timers similar. Basta consultar [Atmel 2004]
para verificar os registradores envolvidos.
5.2.2

PWM

Com exceo do timer/counter 0, os outros temporizadores trazem consigo a funcionalidade da configurao do PWM. Como j foi dito, este tipo de modulao muito utilizado para o acionamento
de motores de corrente contnua. Um exemplo de circuito utilizado para tal finalidade com o uso do
AVR e do circuito integrado L298 encontra-se disponvel no circuito do Anexo E. Neste exemplo,
implementou-se um controle bidirecional de velocidade (um ciclo de trabalho de 50 % mantm o motor
parado e o sinal do pino 14 deve ser o complemento do sinal do pino 15).
A gerao do sinal PWM com o AVR se baseia na comparao dos estados dos contadores com
valores pr-determinados. Assim, o resultado dessa comparao utilizado para alterar a sada do
PWM e, em ltima instncia, definir o ciclo de trabalho do sinal PWM gerado.
Neste contexto, o ATmega8 permite a gerao de trs sinais PWM simultneos. Dois deles so
gerados com o timer/counter 1, que permite resoluo de 16 bits, e o outro com o timer/counter 2, cuja
resoluo permitida de 8 bits. A configurao dessa funo relativamente simples, bastando atentar
s tabelas de configurao referentes aos registradores TCCR1A, TCCR1B ou TCCR2, dependendo
do caso, disponveis em [Atmel 2004]. Abaixo demonstra-se um exemplo de funo para inicializar a
gerao de dois sinais PWM simultneos a partir do timer/counter 1. Para alterar o valor da taxa de
trabalho, basta escrever nos registradores OCR1AH e OCR1AL para o sinal A e OCR1BH e OCR1BL
para o sinal B.

19

void PWM_Iniciar (void){


// valores iniciais dos sinais PWM
OCR1AH = 0x03;
OCR1AL = 0xFF;
OCR1BH = 0x03;
OCR1BL = 0xFF;
// configuracao do PWM
TCCR1A = _BV(COM1A1) | _BV(COM1A0) | _BV(COM1B1) | _BV(COM1B0) | _BV(WGM10) | _BV(WGM11);
TCCR1B = _BV(CS11) | _BV(WGM12);
// set PB1 e PB2 as output
DDRB = _BV(DDB1) | _BV(DDB2);
}

Na configurao acima descrita, o prescaler foi configurado para 8 (CS11) e utilizado o Fast
PWM de 10 bits (WGM10,11,12). Os bits COMXXX so utilizados para definir a sada da operao
de comparao.

5.3

Converso A/D

Muitos sistemas que utilizam microcontroladores requerem a medio de variveis de natureza analgica. Alguns exemplos so a temperatura medida por um termmetro, a posio angular medida por
um potencimetro, entre outros. Neste contexto, para que essas informaes possam ser utilizadas
pelo microcontrolador, h a necessidade de se converter tais sinais para seus correspondentes digitais.
O dispositivo utilizado para esta operao o conversor analgico/digital, ou conversor A/D.
O AVR possui um conversor A/D com resoluo de 10 bits. Esse mesmo conversor pode ser
acessado por seis diferentes canais nos encapsulamentos PDIP. Ou seja, com um AVR ATmega8 neste
encapsulamento pode-se medir facilmente seis sinais analgicos, porm no simultaneamente. Isso se
d porque existe um nico conversor A/D com entradas multiplexadas. Alm do mais o AVR possui
um circuito sample-and-hold que mantm o valor analgico da entrada constante durante o processo
de converso, o que quer dizer que o projetista no precisa se preocupar quanto a esse aspecto no
projeto do circuito. De fato, est disponvel em anexo um simples circuito para conexo dos valores
a serem medidos nos pinos correspondentes. Este circuito oferece certa proteo ao conversor A/D
contra sub- e sobre-tenses. Alm disso, a converso A/D se utiliza uma fonte de tenso distinta
(AVCC), cujo valor no pode diferir muito do valor de VCC, sendo na verdade a alimentao VCC
passada por um filtro para minimizar flutuaes na tenso de alimentao do conversor. O conversor
A/D ainda requer uma tenso de referncia analgica (AREF), que pode ser tanto interna como
externa. De fato, o mximo valor obtido na converso, que seria 1023 visto que o conversor A/D
de 10 bits, ocorrer quando a entrada se igualar ao valor de AREF. Recomenda-se a consulta ao
manual do microcontrolador [Atmel 2004] para melhor compreender o funcionamento do conversor
A/D e atentar para restries de operao, sob o risco de danificar permanentemente o conversor.
A utilizao das funes de converso A/D tambm no complicada, conforme mostra o exemplo
a seguir:
void AD_Iniciar (void) {
// enable ADC e prescaler com division factor 64(ADPS2 e ADPS1)
ADCSRA = _BV(ADEN) | _BV(ADPS2) | _BV(ADPS1);
// setar referncia
ADMUX = _BV(REFS0);
}
void AD_Converter(unsigned char canal, unsigned char *pdatah, unsigned char *pdatal){
ADMUX = _BV(REFS0) | (canal & 0x0F);
ADCSRA |= (0x01<<ADSC);
// esperar fim de conversao
while((ADCSRA & (0x40)));

20

// copiar resultado
*pdatal = ADCL; // deve ser lido antes de ADCH
*pdatah = ADCH;
}
void main (void) {
unsigned char canal,convh, convl;
...
AD_Iniciar();
...
while(true){
...
canal = 1;
AD_Converter(canal,&convh,&convl);
...
}
}

Deve ser observado que o programa acima pode ser usado com o circuito de teste da seo E,
que faz uso do canal 1 do conversor. No CD, o projeto exemplo voltmeter mais completo pois
corresponde a um voltmetro com display de LEDs. No entanto, o projeto voltmeter usa o canal 0
do conversor A/D.

5.4

Comunicao Serial (no revisado)

A fim de que o AVR envie e receba dados por meio de sua interface serial, basta configurar os
registradores corretos. Neste sentido, os principais bits a serem ativados so o RXEN e o TXEN do
registrador UCSRB, que liberam a recepo e a transmisso, respectivamente. Alm disso, preciso
indicar o baud rate utilizado por meio dos registradores UBRRH e UBRRL (ver pginas 156-159
de [Atmel 2004] para tabela de valores), o tamanho da palavra, por meio dos bits UCSZ0, UCSZ1
e UCSZ2 do registrador UCSRC e o bit de parada por meio do bit USBS do mesmo registrador.
A seguir disponibiliza-se exemplos de funo para configurar a comunicao serial, enviar e receber
dados:
void USART_Iniciar (void) {
//Setar baud rate 38400
UBRRH = (unsigned char)(25>>8);
UBRRL = (unsigned char)(25);
//Enable TXD, RXD e ativar RXCIE(enable interrupt on the RCX flag)
UCSRB = _BV(TXEN) | _BV(RXEN); //| _BV(RXCIE);
//Setar tamanho palavra (formatao da comunicao serial)
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0) | _BV(USBS);
//Ativar double speed
UCSRA = _BV(U2X);
}
void USART_Transmitir (unsigned char c) {
//Verificar se o buffer da serial est vazio
while ( !(UCSRA & (1<<UDRE)) );
//coloca o dado no buffer e envia
UDR = c;
}
unsigned char USART_Receber (void) {
//Esperar at que seja feita comunicao em RXD
while ( !(UCSRA & (1<<RXC)) );
//Recebe o dado do buffer

21

return UDR;
}

Dos cdigos acima, percebe-se que, para enviar e receber, basta ler ou escrever no registrador
UDR, a partir do momento em que ele se encontra preenchido ou no, de acordo com o caso. Mais
especificamente, UDRE um bit que informa se o registrador em questo est vazio e RXC o bit que
informa se a recepo se foi finalizada.
Para compatibilidade com o padro RS-232, necessria uma interface, que compe a camada
fsica do protocolo. Isto devido ao fato de o protocolo RS-232 trabalhar com faixas de tenso
distintas do padro 0-5V da interface de comunicao serial. Com este objetivo, utiliza-se o circuito
integrado MAX-232 e um conjunto de capacitores de 10F . O circuito correspondente encontra-se
disponvel no Anexo E.
Para testar o funcionamento do sistema de comunicao serial, recomenda-se a utilizao de
programas como o HyperTerminal, disponvel no Windows ou o Terminal, disponvel online.

5.5

Usando o PC como terminal de teclado/vdeo

Quando as funes da biblioteca STDIO direcionam seus canais stdin e stdout porta serial do microcontrolador, pode-se utilizar funes tais como printf ou scanf para imprimir mensagens na tela ou
ler teclas do teclado de um microcomputador PC. Nesta configurao, diz-se que o microcomputador
est operando apenas como terminal. Para tanto, faz-se necessrio conectar o ATmega8 porta serial
do PC por meio de um conversor de nvel RS-232, tal como o MAX232. Isto feito no circuito da
Figura 12. No PC, faz-se necessrio ter um programa terminal rodando, tal como o Hyperterminal.
Em um programa terminal, tudo que for teclado enviado porta serial na forma de caractere ASCII.
E tambm, todo dado que chegar pela porta serial impresso na tela tambm como caractere ASCII.
O programa exemplo abaixo faz com que o ATmega8 reenvie ao PC tudo que for recebido pela
porta serial. O exemplo est tambm disponvel no CD de iniciao na forma do exemplo terminal.
#include <avr/io.h>
#include <stdio.h>
void USART_Init(void);
int USART_Transmit( char data );
int USART_Receive( void );
int main(void)
{
char ch;
USART_Init();
/*registrando as funes de leitura e escrita de um byte pela serial*/
fdevopen(USART_Transmit, USART_Receive, 0);
//escrevendo "Ola, mundo!" pela serial
printf ("Ola, mundo");
while(1){
// As duas linhas abaixo fazem a mesma coisa: o caracter que chegar
// pela serial ser ecoado por ela. Entretanto, as funes usadas so diferentes.
// A diferena fundamental est na compexidade de cada uma delas.
// Para ter uma melhor compreenso disto, descomente apenas uma das linhas abaixo,
// e compile o programa para ver a diferena de tamanho do programa compilado.
scanf ("%c", &ch); printf ("%c", ch); // Soluo 1.
//
putchar(getchar()); // Soluo 2.
}

22

}
/*
Funo que faz a inicializcao da usart para comunicacao assincrona com o PC
a 9600 baud rate com 16MHz de cristal externo.
A recepo e transmisso so habilitadas, sobrepondo as funes dos pinos TxD e RxD.
Nenhuma interrupo habilitada.
*/
void USART_Init(void)
{
/*zerando o contedo do registrador de dados da serial*/
UDR=0;
//Seta baud rate de 9600 para fosc= 16MHz
UBRRH = 0;
UBRRL = 103;
//Habilita transmisso e recepo serial
UCSRB = _BV(TXEN)| _BV(RXEN);
//Setar tamanho palavra
//URSEL = 1 -> seleciona acesso para UCSRC (0 is UBRRH) reading and writing
//UMSEL = 0 -> Asynchronous Operation
//UPM1 e UPM0 = 00 -> sem paridade
//USBS = 1 -> seleciona 2 bits de parada a ser inserido pelo transmissor
//UCSZ 2 1 0 = 011 -> escolhe tamanho de caractere de 8 bits p/ dado
UCSRC = _BV(URSEL) | _BV(UCSZ1) | _BV(UCSZ0);
}
// Faz a leitura de um byte da serial usando pooling
int USART_Receive( void )
{
while ( !(UCSRA & (1<<RXC)) ); // Wait for data to be received
return UDR; // Get and return received data from buffer
}
// Faz a transmissao
int USART_Transmit(
{
while ( !( UCSRA &
UDR = data; // Put
return 0;
}

de um byte pela serial


char data )
(1<<UDRE)) ); // Wait for empty transmit buffer
data into buffer, sends the data

Caso o usurio deseje imprimir no terminal nmeros em ponto flutuante com a funo printf, ele
deve descomentar a seguinte linha do arquivo makefile (Anexo D):
#LDFLAGS += -Wl,-u,vfprintf -lprintf_flt

5.6

Display LCD

Uma das maneiras mais interessantes de apresentar informaes relativas ao sistema utiliza displays
de cristal lquido (LCDs). Neste sentido, esta subseo disponibiliza um exemplo que pode auxiliar
aqueles que pretendem utilizar este dispositivo. Este exemplo faz uso da bilioteca lcd.c disponvel
no site http://homepage.hispeed.ch/peterfleury/avr-lcd44780.html. O exemplo est tambm
disponvel no CD de iniciao na forma do exemplo lcdmsg.
#include
#include
#include
#include

<inttypes.h>
<string.h>
<stdio.h>
<avr/io.h>

23

#define F_CPU 16.0E6 // relgio com cristal externo de 16MHz


#include <avr/delay.h>
#include "lcd.h"
void delay_us(unsigned int timedelay_us);
void delay_ms(unsigned int timedelay_ms);
int main (void)
{
unsigned int segundos = 0, milisegundos = 0;
char s[10];
lcd_init(LCD_DISP_ON);
lcd_clrscr();
lcd_home();
lcd_puts("Iniciando...");
delay_ms(1000);
lcd_clrscr();
lcd_home();
for(;;){
delay_ms(100);
if((milisegundos+=100)>=1000){
milisegundos = 0;
++segundos;
}
sprintf(s,"%d:%2d",segundos, milisegundos/10);
lcd_gotoxy(7-strlen(s)/2,0);
lcd_puts(s);
}
}
void delay_us(unsigned int timedelay_us)
{
while(timedelay_us>1000){
_delay_loop_2(4000); // 1ms
timedelay_us-=1000;
}
timedelay_us = (4*timedelay_us);
_delay_loop_2(timedelay_us);
}
void delay_ms(unsigned int timedelay_ms)
{
while(--timedelay_ms>0)
delay_us(1000); // 1ms;
}

Concluses

Esta nota tcnica apresentou algumas ferramentas bsicas para desenvolvimento de projetos com
microcontroladores AVR. A partir das informaes disponibilizadas, o leitor convidado a buscar as
mais diversas aplicaes, bem como novas funcionalidades no descritas neste documento. Este ,
de fato, o maior objetivo daqueles que contriburam para a elaborao deste documento e que foram
efetivamente usurios do microcontrolador ATmega8.

24

Referncias
[Atmel 2004]ATMEL. ATmega8(L) Complete Datasheet. [S.l.], 2004.

25

CD de iniciao ao AVR

Para melhor acompanhar esta nota tcnica, est sendo disponibilizado no site http://www.ene.unb.
br/~gaborges/recursos/embarcados/index.htm um CD com todas as ferramentas de desenvolvimento, exemplos e documentao. Como o CD est disponvel na internet, qualquer outra pessoa
interessada pode baix-lo. O arquivo leiame.txt detalha o contedo do CD e d vrias dicas de
como fazer melhor uso do microcontrolador. No CD tambm existem vrios exemplos de programas.

Iniciao rpida

Para aqueles que querem se iniciar rapidamente com o desenvolvimento com AVR, mesmo que correndo todos os riscos associados compreenso limitada do que est sendo realizado, sugere-se seguir
os seguintes passos:
Instalar o WinAVR (Ferramentas - software\WinAVR). Se houver uma verso anterior no
microcomputador, a mesma deve ser desinstalada;
Construir uma gravadora BSD (Ferramentas - hardware\BSD prog simples). No esquecer
de configurar na BIOS do seu computador que a porta paralela deve operar em modo Standard
(geralmente usa-se a sigla SPP);
Construir um circuito de referncia (Ferramentas - hardware\Circuito de referncia ATMEGA8);
Testar o circuito de referncia e a gravadora seguindo o procedimento da Seo 3.1.3.
Usar o Programmers Notepad para desenvolver o projeto (instalado com o WinAVR). Se o
microcontrolador novo, deve-se lembrar que sua configurao de fbrica implica que a fonte
de relgio um circuito RC interno a 1MHz. Uma recomendao para os novatos consiste em
partir de um dos exemplos do CD de iniciao ao AVR;
Verificar se o Makefile est adaptado ao projeto. No esquecer de especificar o microcontrolador
(no caso, ATmega8), a gravadora (no caso, bsd) e a porta em que ela est conectada (lpt1, se
porta paralela 1);
Ligue a alimentao do circuito com o microcontrolador. A gravadora BSD deve estar conectada
ao microcontrolador e ao microcomputador;
Use as opes [WinAVR] Make Clean, [WinAVR] Make All e [WinAVR] Make Program do menu
Tools do Programmers Notepad para limpar o projeto, compilar e gravar no microcontrolador.
Se tudo der certo, ao final dos procedimentos acima o programa dever estar sendo executado no
microcontrolador.
Estes passos foram escritos considerando que o usurio dispe do CD de iniciao (Anexo A);

Referncias na Internet
http://www.atmel.com/ : pgina do fabricante, com manuais e notas de aplicao;
http://www.avrfreaks.net/ : a principal fonte para aqueles que buscam auxlio para o desenc
volvimento com microcontrolador da srie AVR da
Atmel;

26

http://www.microschematic.com/ : apresentao em Flash indicada para aqueles que desejam


programar em assembly;
http://winavr.sourceforge.net/ : site oficial do pacote de desenvolvimento WinAVR;
http://www.bsdhome.com/avrdude/ : site do programador AVRDUDE (BSD);
http://www.freertos.org/ : site do FreeRTOS, um kernel que possui suporte linha de
microcontroladores AVR;
http://members.home.nl/jmnieuwkamp1/AVRlib/ : site da biblioteca AVRlib, que contm um
grande nmero de funes par uso e interface para microcontroladores AVR;
http://homepage.hispeed.ch/peterfleury/index.html : site do Peter Fleury com projetos,
exemplos. Tem uma placa de desenvolvimento e algumas bibliotecas.

Exemplo de makefile

O arquivo makefile (sem extenso) essencial para projetos em que o processo de compilao
mais complexo, embora seja tambm bastante til para projetos simples. O makefile um arquivo
texto com diretivas que determinam como cada arquivo do projeto deve ser compilado, linkado e
como o resultado final deve ser apresentado. Este arquivo usado pelo utilitrio make.exe, devendo
estar no mesmo diretrio da chamada, quando se executa algo do tipo make procedimento em que
procedimento uma palavra reservada que caracteriza o procedimento a ser realizado. De acordo
com o arquivo makefile abaixo, esto definidos procedimentos all, clean e program, entre outros
procedimentos intermedirios:
make all: procedimento de compilao de todos os arquivos fonte que foram alterados desde
a ltima compilao, e gerao de vrios arquivos, entre eles a imagem .hex a ser gravada no
microcontrolador.
make clean: apaga todos os arquivos intermedirios e resultantes de compilao, deixando
apenas os arquivos fonte de um projeto. um procedimento geralmente usado quando se
deseja guardar apenas o necessrio de um projeto para, talvez, enviar para algum.
make program: grava o programa no microcontrolador utilisando a gravadora configurada no
makefile.
O arquivo makefile usado como exemplo foi extrado de um exemplo do pacote WinAVR. Para
compreend-lo, faz-se necessrio saber como o utilitrio make.exe funciona. Para tanto, sugere-se
o site http://www.gnu.org/software/make/manual/make.html. Entretanto, o arquivo est muito
bem comentado.
# Hey Emacs, this is a -*- makefile -*#---------------------------------------------------------------------------# WinAVR Makefile Template written by Eric B. Weddington, Jrg Wunsch, et al.
#
# Released to the Public Domain
#
# Additional material for this makefile was written by:
# Peter Fleury
# Tim Henigan
# Colin OFlynn
# Reiner Patommel
# Markus Pfaff
# Sander Pool

27

# Frederik Rouleau
# Carlos Lamas
#
#---------------------------------------------------------------------------# On command line:
#
# make all = Make software.
#
# make clean = Clean out built project files.
#
# make coff = Convert ELF to AVR COFF.
#
# make extcoff = Convert ELF to AVR Extended COFF.
#
# make program = Download the hex file to the device, using avrdude.
#
Please customize the avrdude settings below first!
#
# make debug = Start either simulavr or avarice as specified for debugging,
#
with avr-gdb or avr-insight as the front end for debugging.
#
# make filename.s = Just compile filename.c into the assembler code only.
#
# make filename.i = Create a preprocessed source file for use in submitting
#
bug reports to the GCC project.
#
# To rebuild project do "make clean" then "make all".
#----------------------------------------------------------------------------

# MCU name
MCU = atmega8

# Processor frequency.
#
This will define a symbol, F_CPU, in all source code files equal to the
#
processor frequency. You can then use this symbol in your source code to
#
calculate timings. Do NOT tack on a UL at the end, this will be done
#
automatically to create a 32-bit value in your source code.
#
Typical values are:
#
F_CPU = 1000000
#
F_CPU = 1843200
#
F_CPU = 2000000
#
F_CPU = 3686400
#
F_CPU = 4000000
#
F_CPU = 7372800
#
F_CPU = 8000000
#
F_CPU = 11059200
#
F_CPU = 14745600
F_CPU = 16000000
#
F_CPU = 18432000
#
F_CPU = 20000000

# Output format. (can be srec, ihex, binary)


FORMAT = ihex

# Target file name (without extension).


TARGET = voltmeter

# Object files directory


#
To put object files in current directory, use a dot (.), do NOT make

28

#
this an empty or blank macro!
OBJDIR = .

# List C source files here. (C dependencies are automatically generated.)


SRC = main.c

# List C++ source files here. (C dependencies are automatically generated.)


CPPSRC =

# List Assembler source files here.


#
Make them always end in a capital .S. Files ending in a lowercase .s
#
will not be considered source files but generated files (assembler
#
output from the compiler), and will be deleted upon "make clean"!
#
Even though the DOS/Win* filesystem matches both .s and .S the same,
#
it will preserve the spelling of the filenames, and gcc itself does
#
care about how the name is spelled on its command-line.
ASRC =

# Optimization level, can be [0, 1, 2, 3, s].


#
0 = turn off optimization. s = optimize for size.
#
(Note: 3 is not always the best optimization level. See avr-libc FAQ.)
OPT = 2

# Debugging format.
#
Native formats for AVR-GCCs -g are dwarf-2 [default] or stabs.
#
AVR Studio 4.10 requires dwarf-2.
#
AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
DEBUG = dwarf-2

# List any extra directories to look for include files here.


#
Each directory must be seperated by a space.
#
Use forward slashes for directory separators.
#
For a directory that has spaces, enclose it in quotes.
EXTRAINCDIRS =

# Compiler flag to set the C Standard level.


#
c89
= "ANSI" C
#
gnu89 = c89 plus GCC extensions
#
c99
= ISO C99 standard (not yet fully implemented)
#
gnu99 = c99 plus GCC extensions
CSTANDARD = -std=gnu99

# Place -D or -U options here for C sources


CDEFS = -DF_CPU=$(F_CPU)UL

# Place -D or -U options here for ASM sources


ADEFS = -DF_CPU=$(F_CPU)

# Place -D or -U options here for C++ sources


CPPDEFS = -DF_CPU=$(F_CPU)UL
#CPPDEFS += -D__STDC_LIMIT_MACROS
#CPPDEFS += -D__STDC_CONSTANT_MACROS

29

#---------------- Compiler Options C ---------------# -g*:


generate debugging information
# -O*:
optimization level
# -f...:
tuning, see GCC manual and avr-libc documentation
# -Wall...:
warning level
# -Wa,...:
tell GCC to pass this to the assembler.
#
-adhlns...: create assembler listing
CFLAGS = -g$(DEBUG)
CFLAGS += $(CDEFS)
CFLAGS += -O$(OPT)
CFLAGS += -funsigned-char
CFLAGS += -funsigned-bitfields
CFLAGS += -fpack-struct
CFLAGS += -fshort-enums
CFLAGS += -Wall
CFLAGS += -Wstrict-prototypes
#CFLAGS += -mshort-calls
#CFLAGS += -fno-unit-at-a-time
#CFLAGS += -Wundef
#CFLAGS += -Wunreachable-code
#CFLAGS += -Wsign-compare
CFLAGS += -Wa,-adhlns=$(<:%.c=$(OBJDIR)/%.lst)
CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
CFLAGS += $(CSTANDARD)

#---------------- Compiler Options C++ ---------------# -g*:


generate debugging information
# -O*:
optimization level
# -f...:
tuning, see GCC manual and avr-libc documentation
# -Wall...:
warning level
# -Wa,...:
tell GCC to pass this to the assembler.
#
-adhlns...: create assembler listing
CPPFLAGS = -g$(DEBUG)
CPPFLAGS += $(CPPDEFS)
CPPFLAGS += -O$(OPT)
CPPFLAGS += -funsigned-char
CPPFLAGS += -funsigned-bitfields
CPPFLAGS += -fpack-struct
CPPFLAGS += -fshort-enums
CPPFLAGS += -fno-exceptions
CPPFLAGS += -Wall
CFLAGS += -Wundef
#CPPFLAGS += -mshort-calls
#CPPFLAGS += -fno-unit-at-a-time
#CPPFLAGS += -Wstrict-prototypes
#CPPFLAGS += -Wunreachable-code
#CPPFLAGS += -Wsign-compare
CPPFLAGS += -Wa,-adhlns=$(<:%.cpp=$(OBJDIR)/%.lst)
CPPFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS))
#CPPFLAGS += $(CSTANDARD)

#---------------- Assembler Options ---------------# -Wa,...:


tell GCC to pass this to the assembler.
# -adhlns:
create listing
# -gstabs:
have the assembler create line number information; note that
#
for use in COFF files, additional information about filenames
#
and function names needs to be present in the assembler source
#
files -- see avr-libc docs [FIXME: not yet described there]
# -listing-cont-lines: Sets the maximum number of continuation lines of hex

30

#
dump that will be displayed for a given single line of source input.
ASFLAGS = $(ADEFS) -Wa,-adhlns=$(<:%.S=$(OBJDIR)/%.lst),-gstabs,--listing-cont-lines=100

#---------------- Library Options ---------------# Minimalistic printf version


PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
# Floating point printf version (requires MATH_LIB = -lm below)
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
# If this is left blank, then it will use the Standard printf version.
PRINTF_LIB =
#PRINTF_LIB = $(PRINTF_LIB_MIN)
#PRINTF_LIB = $(PRINTF_LIB_FLOAT)

# Minimalistic scanf version


SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min
# Floating point + %[ scanf version (requires MATH_LIB = -lm below)
SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt
# If this is left blank, then it will use the Standard scanf version.
SCANF_LIB =
#SCANF_LIB = $(SCANF_LIB_MIN)
#SCANF_LIB = $(SCANF_LIB_FLOAT)

MATH_LIB = -lm

# List any extra directories to look for libraries here.


#
Each directory must be seperated by a space.
#
Use forward slashes for directory separators.
#
For a directory that has spaces, enclose it in quotes.
EXTRALIBDIRS =

#---------------- External Memory Options ---------------# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# used for variables (.data/.bss) and heap (malloc()).
#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff
# 64 KB of external RAM, starting after internal RAM (ATmega128!),
# only used for heap (malloc()).
#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff
EXTMEMOPTS =

#---------------- Linker Options ---------------# -Wl,...:


tell GCC to pass this to linker.
#
-Map:
create map file
#
--cref:
add cross reference to map file
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
LDFLAGS += $(EXTMEMOPTS)
LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS))
LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB)
#LDFLAGS += -T linker_script.x

31

#---------------- Programming Options (avrdude) ---------------# Programming hardware


# Type: avrdude -c ?
# to get a full listing.
#
AVRDUDE_PROGRAMMER = bsd
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = lpt1
# programmer connected to parallel port
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
#AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
# Uncomment the following if you want avrdude leave with /RESET=1 (microcontroller running).
AVRDUDE_EXIT_NO_RESET = -E noreset
# Uncomment the following if you want avrdudes erase cycle counter.
# Note that this counter needs to be initialized first using -Yn,
# see avrdude manual.
#AVRDUDE_ERASE_COUNTER = -y
# Uncomment the following if you do /not/ wish a verification to be
# performed after programming the device.
#AVRDUDE_NO_VERIFY = -V
# Increase verbosity level. Please use this when submitting bug
# reports about avrdude. See <http://savannah.nongnu.org/projects/avrdude>
# to submit bug reports.
#AVRDUDE_VERBOSE = -v -v
AVRDUDE_FLAGS
AVRDUDE_FLAGS
AVRDUDE_FLAGS
AVRDUDE_FLAGS
AVRDUDE_FLAGS

= -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)


+= $(AVRDUDE_NO_VERIFY)
+= $(AVRDUDE_VERBOSE)
+= $(AVRDUDE_ERASE_COUNTER)
+= $(AVRDUDE_EXIT_NO_RESET)

#---------------- Debugging Options ---------------# For simulavr only - target MCU frequency.
DEBUG_MFREQ = $(F_CPU)
# Set the DEBUG_UI to either gdb or insight.
# DEBUG_UI = gdb
DEBUG_UI = insight
# Set the debugging back-end to either avarice, simulavr.
DEBUG_BACKEND = avarice
#DEBUG_BACKEND = simulavr
# GDB Init Filename.
GDBINIT_FILE = __avr_gdbinit
# When using avarice settings for the JTAG
JTAG_DEV = /dev/com1
# Debugging port used to communicate between GDB / avarice / simulavr.
DEBUG_PORT = 4242

32

# Debugging host used to communicate between GDB / avarice / simulavr, normally


#
just set to localhost unless doing some sort of crazy debugging when
#
avarice is running on a different computer.
DEBUG_HOST = localhost

#============================================================================

# Define programs and commands.


SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
SIZE = avr-size
AR = avr-ar rcs
NM = avr-nm
AVRDUDE = avrdude
REMOVE = rm -f
REMOVEDIR = rm -rf
COPY = cp
WINSHELL = cmd

# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = -------- begin -------MSG_END = -------- end -------MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_COFF = Converting to AVR COFF:
MSG_EXTENDED_COFF = Converting to AVR Extended COFF:
MSG_FLASH = Creating load file for Flash:
MSG_EEPROM = Creating load file for EEPROM:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_COMPILING_CPP = Compiling C++:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
MSG_CREATING_LIBRARY = Creating library:

# Define all object files.


OBJ = $(SRC:%.c=$(OBJDIR)/%.o) $(CPPSRC:%.cpp=$(OBJDIR)/%.o) $(ASRC:%.S=$(OBJDIR)/%.o)
# Define all listing files.
LST = $(SRC:%.c=$(OBJDIR)/%.lst) $(CPPSRC:%.cpp=$(OBJDIR)/%.lst) $(ASRC:%.S=$(OBJDIR)/%.lst)

# Compiler flags to generate dependency files.


GENDEPFLAGS = -MMD -MP -MF .dep/$(@F).d

# Combine all necessary flags and optional flags.


# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)

33

ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)

# Default target.
all: begin gccversion sizebefore build sizeafter end
# Change the build target to build a HEX file or a library.
build: elf hex eep lss sym
#build: lib

elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep
lss: $(TARGET).lss
sym: $(TARGET).sym
LIBNAME=lib$(TARGET).a
lib: $(LIBNAME)

# Eye candy.
# AVR Studio 3.x does not check makes exit code but relies on
# the following magic strings to be generated by the compile job.
begin:
@echo
@echo $(MSG_BEGIN)
end:
@echo $(MSG_END)
@echo

# Display size of file.


HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex
ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf
sizebefore:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \
2>/dev/null; echo; fi
sizeafter:
@if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \
2>/dev/null; echo; fi

# Display compiler version information.


gccversion :
@$(CC) --version

# Program the device.


program: $(TARGET).hex $(TARGET).eep
$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)

# Generate avr-gdb config/init file which does the following:


#
define the reset signal, load the target file, connect to target, and set

34

#
a breakpoint at main().
gdb-config:
@$(REMOVE) $(GDBINIT_FILE)
@echo define reset >> $(GDBINIT_FILE)
@echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
@echo end >> $(GDBINIT_FILE)
@echo file $(TARGET).elf >> $(GDBINIT_FILE)
@echo target remote $(DEBUG_HOST):$(DEBUG_PORT)
ifeq ($(DEBUG_BACKEND),simulavr)
@echo load >> $(GDBINIT_FILE)
endif
@echo break main >> $(GDBINIT_FILE)

>> $(GDBINIT_FILE)

debug: gdb-config $(TARGET).elf


ifeq ($(DEBUG_BACKEND), avarice)
@echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
@$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \
$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
@$(WINSHELL) /c pause
else
@$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \
$(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
@$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)

# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT = $(OBJCOPY) --debugging
COFFCONVERT += --change-section-address .data-0x800000
COFFCONVERT += --change-section-address .bss-0x800000
COFFCONVERT += --change-section-address .noinit-0x800000
COFFCONVERT += --change-section-address .eeprom-0x810000

coff: $(TARGET).elf
@echo
@echo $(MSG_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-avr $< $(TARGET).cof

extcoff: $(TARGET).elf
@echo
@echo $(MSG_EXTENDED_COFF) $(TARGET).cof
$(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof

# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@
%.eep: %.elf
@echo
@echo $(MSG_EEPROM) $@
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0

35

# Create extended listing file from ELF output file.


%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -z $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@

# Create library from object files.


.SECONDARY : $(TARGET).a
.PRECIOUS : $(OBJ)
%.a: $(OBJ)
@echo
@echo $(MSG_CREATING_LIBRARY) $@
$(AR) $@ $(OBJ)

# Link: create ELF output file from object files.


.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS)

# Compile: create object files from C source files.


$(OBJDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(ALL_CFLAGS) $< -o $@

# Compile: create object files from C++ source files.


$(OBJDIR)/%.o : %.cpp
@echo
@echo $(MSG_COMPILING_CPP) $<
$(CC) -c $(ALL_CPPFLAGS) $< -o $@

# Compile: create assembler files from C source files.


%.s : %.c
$(CC) -S $(ALL_CFLAGS) $< -o $@

# Compile: create assembler files from C++ source files.


%.s : %.cpp
$(CC) -S $(ALL_CPPFLAGS) $< -o $@

# Assemble: create object files from assembler source files.


$(OBJDIR)/%.o : %.S
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@

36

# Create preprocessed source for use in sending a bug report.


%.i : %.c
$(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@

# Target: clean project.


clean: begin clean_list end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lss
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.o)
$(REMOVE) $(SRC:%.c=$(OBJDIR)/%.lst)
$(REMOVE) $(SRC:.c=.s)
$(REMOVE) $(SRC:.c=.d)
$(REMOVE) $(SRC:.c=.i)
$(REMOVEDIR) .dep

# Create object files directory


$(shell mkdir $(OBJDIR) 2>/dev/null)

# Include the dependency files.


-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)

# Listing of phony targets.


.PHONY : all begin finish end sizebefore sizeafter gccversion \
build elf hex eep lss sym coff extcoff \
clean clean_list program debug gdb-config

Circuito de teste

O circuito da Figura 12 utilizado por alguns exemplos desta nota tcnica para ilustrar funcionalidades
do ATmega8. O mesmo pode ser montado em protoboard aproveitando-se o circuito de referncia da
Seo 3.1.2.

37

Figura 12: Circuito de teste com o microcontrolador, interface serial para PC e acionador por modulao em largura de pulso para motor de corrente contnua com escovas

38

Você também pode gostar