Você está na página 1de 8

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR


02/2011

Migrando do ATmega8 para o ATmega88/168/328

Vetores de Interrupo
Todos os vetores de interrupo do ATmega8 so equivalentes no

(o Microcontrolador do Arduino)

ATmegaX8. Como o ATmegaX8 possui mais interrupes, os vetores foram


deslocados para outras posies de memria. Algumas interrupes
mudaram de nome, mas suas funcionalidades so as mesmas.

Apesar de serem pino a pino compatveis com o ATmega8, os


ATmegaX8

possuem

outros

perifricos,

registradores

diferentes

Tab. 1 Comparao entre os vetores (endereos) das interrupes.

caractersticas eltricas. Em resumo:

Trabalho at a frequncia de 20 MHz.


Interrupo externa em todos os pinos.
Contador/temporizador 0-2 com funes estendidas (PWM).
SPI pela USART.
Sada de clock em um pino de I/O (PB0).
Sensor de temperatura do chip com +/- 10 C de preciso.
Debug Wire.

Nos ATmegaX8 o X significa o tamanho da memria flash. Assim,


ATmega88/168/328 possuem, respectivamente, 8, 16 e 32 kbytes de flash.
O ATmega328 possui o dobro de memria EEPROM e RAM que os demais,
o que significa 1 kbyte de EEPROM e 2 kbytes de RAM.
Na Fig. 1 apresentada a pinagem para o encapsulamento PDIP do
ATmegaX8, o mesmo usado no Arduino.

Fig. 1 Pinagem do ATmegaX8.


1

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Registradores de I/O e Bits


O ATmegaX8 tem mais registradores de I/O que o ATmega8. Os
registradores de I/O fora expandidos. Quase todos os registradores do
ATmega8 foram reorganizados para as novas posies de memria no
ATmegaX8.
Tab. 2 - Registradores do ATmega8 com seus equivalentes do ATmgeaX8.
Registradores em negrito no possuem funes equivalentes (ver Tab. 4).

.
3

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tab. 4 - Registradores de I/O que no so funcionalmente iguais aos seus


equivalentes. A tabela mostra onde encontrar os bits dos registradores de I/O que
no esto na mesma posio entre os ATmega.

Tab. 3 - Registradores que mudaram de nome, mas preservaram a mesma


funcionalidade.

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tab. 5 - Bits nos registradores de I/O que tiveram seus nomes alterados, mas
preservaram a mesma funcionalidade.

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Registradores de controle da USART


No ATmega8, UCSRC e UBRRH dividem o mesmo endereo nos
registradores de I/O, e deve-se ter cuidado no uso do bit URSEL para
acessar o registrador desejado. No ATmegaX8, UCSRC e UBRRH possuem
endereos separados e devem ser acessados como dois registradores
individuais. O bit MSB no registrador UCSRC, que contm o bit de seleo
(URSEL) no ATmega8, usado para outro propsito no ATmegaX8.
Tab. 6 Bits dos registradores da USART que tiveram sua funcionalidade alterada.

Referncia Interna de Tenso


Tab. 7 Valores das tenses internas de referncia.

Byte de Calibrao do Oscilador RC Interno


O ATmega8 tem quatro diferentes valores de calibrao, onde
especiais aes so necessrias para carregar os valores no registrador de
calibrao (OSCCAL) quando o microcontrolador est em funcionamento.
O ATmegaX8 tem apenas um valor de calibrao, e este valor carregado
automaticamente durante a inicializao do microcontrolador. O prescaler
do clock pode, ento, ser utilizado para mudar a velocidade da MCU.

Tempo de Escrita da EEPROM


No ATmega8 tWD_EEPROM, da CPU, tipicamente de 8.5 ms.
No ATmegaX8 tWD_EEPROM, da CPU, tipicamente de 3.4 ms.
7

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

int main()
{
DDRB = 0x00; //pinos do PORTB como entrada
PORTB = 0xFF; //habilita pull-ups do PORTC
DDRD = 0xFF; //PORTC como sada

Tenso de Operao
Tab. 8 Tenses e velocidades de operao.

UCSR0B = 0x00; //desabilitar RX e TX (para usar os pinos PD0 e PD1)


//pode ser desnecessrio
PCICR = 1<<PCIE0;//habilita interrupo por qualquer mudana de sinal no
//Pino PCINT0..PCINT7 (PB0..PB7)
PCMSK0 = 0xFF; //habilita todos os pinos para gerar a interrupo
sei();

//habilita as interrupes

for(;;);

EXEMPLOS
Arquivo trata_bits.h utilizado nos programas abaixo.
//------------------------------------------------------------------------//
//Definies de macros para trabalho com bits
#define set_bit(adress,bit)(adress|=(1<<bit))
#define clr_bit(adress,bit)(adress&=~(1<<bit))
#define tst_bit(adress,bit)(adress&(1<<bit))
#define cpl_bit(adress,bit)(adress^=(1<<bit))
//------------------------------------------------------------------------//

}
//--------------------------------------------------------------------------ISR(PCINT0_vect)//quando houver mais de um pino que possa gerar a interrupo,
{
// necessrio testar qual foi.
if(!tst_bit(PINB,PB0))
cpl_bit(PORTD,PD0);
else if(!tst_bit(PINB,PB1))
cpl_bit(PORTD,PD1);
else if(!tst_bit(PINB,PB2))
cpl_bit(PORTD,PD2);
else if(!tst_bit(PINB,PB3))
cpl_bit(PORTD,PD3);
else if(!tst_bit(PINB,PB4))
cpl_bit(PORTD,PD4);
else if(!tst_bit(PINB,PB5))
cpl_bit(PORTD,PD5);
else if(!tst_bit(PINB,PB6))
cpl_bit(PORTD,PD6);
else if(!tst_bit(PINB,PB7))
cpl_bit(PORTD,PD7);
_delay_ms(50);
}
//---------------------------------------------------------------------------

1 INTERRUPO POR TROCA DE ESTADO DOS PINOS DO PORTB

//==========================================================================//
//Cada vez que um boto pressionado o LED correspondente troca de estado //
//
//
//Todos os pinos do ATmegaX8 permitem interrupes externas
//
//Entretanto, eles possuem apenas um vetor de interrupo (endereo)
//
//Caso exista mais de um pino habilitado, o programador deve verificar qual //
//pino gerou a interrupo.
//
//=========================================================================//
//Autor: Charles Borges de Lima - 02/02/2011
//
//=========================================================================//
#define F_CPU 8000000UL
//frequncia de trabalho
#include <avr/io.h>
//definies do componente especificado
#include <avr/interrupt.h> //define algumas macros para as interrupes
#include <util/delay.h>
//biblioteca para o uso das rotinas de delay
#include "trata_bits.h"
//inclui macros para trabalho com bits

Fig. 2 Exemplo 1.

ISR(PCINT0_vect);

10

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

3 - HABILITANDO SINAIS PWM


2 UTILIZANDO OS TEMPORIZADORES

Arquivo definicoes.h utilizado nos programas abaixo.


//------------------------------------------------------------------------//
#define F_CPU 20000000UL
//frequncia de trabalho
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "trata_bits.h"
//------------------------------------------------------------------------//

//==========================================================================//
//MODO CTC PWM RPIDO PWM COM FASE CORRIGIDA
//
//==========================================================================//
//Autor: Charles Borges de Lima - 03/02/2011
//
//==========================================================================//
#include "definicoes.h"
//--------------------------------------------------------------------------int main()
{
DDRB = 0xFF;
DDRD = 0xFF;
//T/C0 - MODO CTC
TCCR0A = (1<<COM0A0)|(1<<WGM01); //modo CTC (no PWM)
OCR0A = 100;
//determinao do perodo do sinal gerado
TCCR0B = 1<<CS00;
//liga T/C0 sem prescaler

Habilitando a interrupo dos temporizadores

//T/C1 - MODO PWM RPIDO DE 10 BITS


TCCR1A = (1<<COM1A1)|(1<<COM1B1)|(1<<WGM11)|(1<<WGM10);
//PWM no invertido e habilita pino OC1A de sada
TCCR1B = (1<<WGM12)|(1<<CS10);//modo do PWM 10, liga T/C1 sem prescaler
OCR1A = 950; //ajuste do ciclo ativo

//==========================================================================//
//Habilitando todos os T/Cs para gerar interrupo por estouro para
//
//gerar formas de onde quadrada nos pinos PC0, PC1 e PC2
//
//==========================================================================//
//Autor: Charles Borges de Lima - 03/02/2011
//
//==========================================================================//
#include "definicoes.h"
ISR(TIMER0_OVF_vect);
ISR(TIMER1_OVF_vect);
ISR(TIMER2_OVF_vect);
//-----------------------------------------------------------------------int main()
{
DDRC = 0xFF;
//T/C0
TCCR0B = (1<<CS02)|(1<<CS00);
TIMSK0 = 1<<TOIE0;

//prescaler = 1024
//habilita interrupo por estouro

//T/C1
TCCR1B = 1<<CS11; //prescaler = 8
TIMSK1 = 1<<TOIE1; //habilita interrupo por estouro
//T/C2
TCCR2B = (1<<CS22)|(1<<CS21);
TIMSK2 = 1<<TOIE2;
sei();

//prescaler = 256
//habilita interrupo por estouro

//habilita as interrupes

for(;;);
}
//-----------------------------------------------------------------------ISR(TIMER0_OVF_vect){cpl_bit(PORTC,PC0);}
//-----------------------------------------------------------------------ISR(TIMER1_OVF_vect){cpl_bit(PORTC,PC1);}
//-----------------------------------------------------------------------ISR(TIMER2_OVF_vect){cpl_bit(PORTC,PC2);}
//------------------------------------------------------------------------

11

//T/C2 - MODO PWM COM FASE CORRIGIDA


TCCR2A = (1<<COM2A1)|(1<<WGM20); //seleo do modo PWM
TCCR2B = 1<<CS20;
//liga T/C2 sem prescaler
OCR2A = 20;
//ajuste do ciclo ativo
for(;;);
}
//==========================================================================//

4 USO DO AD COM O SENSOR DE TEMPERATURA LM35

Arquivo LCD.c utilizado no programa abaixo.


//=========================================================================
//FUNES PARA TRABALHO COM LCD 16x2 (controlador HD44780)
//=========================================================================
//Autor: Charles Borges de Lima
- 04/02/2011
//=========================================================================
#define DADOS_LCD
PORTD
//4 bits de dados do LCD na porta D
#define CONTR_LCD
PORTD
//para facilitar a troca dos pinos do
//hardware e facilitar a re-programao
#define RS
PD2
//pino de instruo ou dado para o LCD
#define E
PD3
//pino de enable do LCD

//
//
//
//
//

//sinal de habilitao para o LCD


#define pulso_enable
_delay_us(1); set_bit(CONTR_LCD,E); _delay_us(1);
clr_bit(CONTR_LCD,E); _delay_us(45)
//----------------------------------------------------------------------------

12

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

//Sub-rotina para enviar caracteres e comandos, com via de dados de 4 bits


//--------------------------------------------------------------------------void cmd_LCD(unsigned char c, char cd)
{
unsigned char i=2;
DADOS_LCD=(DADOS_LCD & 0x0F)|(c & 0xF0);//primeiro os 4 MSB.
//(PD4-PD5-PD6-PD7) -> (D4-D5-D6-D7 LCD)
do
{
if(cd==0)
clr_bit(CONTR_LCD,RS);
else
set_bit(CONTR_LCD,RS);
pulso_enable;
if((cd==0) && (c<4))

//se for instruo de retorno ou limpeza,


//gasta mais tempo

_delay_ms(2);
DADOS_LCD = (DADOS_LCD & 0x0F) | (c<<4);//segundo nibble, 4 LSB
i--;
}while(i>0);
}
//--------------------------------------------------------------------------//Sub-rotina para inicializao do LCD com via de dados de 4 bits
//--------------------------------------------------------------------------void inic_LCD_4bits()
//sequncia ditada pelo fabricando do circuito
{
// integrado HD44780
//o LCD ser s escrito ento R/W sempre zero
clr_bit(CONTR_LCD,RS); //RS em zero indicando que o dado para o LCD ser
//uma instruo
clr_bit(CONTR_LCD,E);
//pino de habilitao em zero
_delay_ms(20);

//tempo para estabilizar a tenso do LCD,


//aps VCC ultrapassar 4.5 V. Como no se sabe o tempo
//que a tenso leva para alcanar 4.5 V , na prtica
//este tempo pode necessitar ser alterado para centenas
//de milissegundos.

DADOS_LCD = (DADOS_LCD & 0x0F) | 0x30;


pulso_enable;
_delay_ms(5);
pulso_enable;
_delay_us(200);
pulso_enable;

//interface 8 bits

//enable respeitando os tempos de resposta do LCD

//at aqui ainda uma interface de 8 bits

DADOS_LCD = (DADOS_LCD & 0x0F) | 0x20;//interface de 4 bits, deve ser


//enviado duas vezes (a outra esta abaixo)
pulso_enable;
cmd_LCD(0x28,0);//interface de 4 bits 2 linhas (aqui se habilita as 2 linhas)
//so enviados os 2 nibbles (0x2 e 0x8)
cmd_LCD(0x08,0);
//desliga o display
cmd_LCD(0x01,0);
//limpa todo o display
cmd_LCD(0x0C,0);
//mensagem aparente cursor ativo no piscando
cmd_LCD(0x80,0);
//escreve na primeira posio a esquerda - 1a linha

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

//Sub-rotina de escrita no LCD


//--------------------------------------------------------------------------void escreve_LCD(char *c)
{
for (; *c!=0;c++) cmd_LCD(*c,1);
}
//---------------------------------------------------------------------------

Lendo o sensor de temperatura LM35


//=========================================================================
//LEITURA DO SENSOR DE TEMPERATURA LM32 COM INTERFACE LCD
//=========================================================================
//Autor: Charles Borges de Lima
- 04/02/2011
//=========================================================================
#include "definicoes.h"
#include "LCD.c"
//-----------------------------------------------------------------------unsigned int temp;
//varivel para o valor da temperatura
unsigned char digitos[4];
//varivel global para no mximo 5 dgitos
ISR(ADC_vect);
void ident_num(unsigned int valor);
//-----------------------------------------------------------------------int main()
{
DDRD = 0xFF;
DDRC = 0x00;
inic_LCD_4bits();
//inicializao do LCD
escreve_LCD("LEITURA = ");
//Configurao do AD
ADMUX = (1<<REFS1)|(1<<REFS0);//referncia interna (1,1V), canal 0
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//liga o AD, inicia a converso, habilita a interrupo, habilita auto-trigger
//prescaler=128 para o clock do AD. Deve-se ter cuidado ao selecionar o prescaler
//para no utilizar uma frequncia acima do limite do AD (de acordo com a
//frequncia de trabalho da CPU).

ADCSRB = 0x00;
DIDR0 = 1<<ADC0D;
sei();

//modo de converso contnuo


//desabilita a entrada digital do pino PC0

//habilita a interrupo

for(;;)
{
ident_num(temp);//converte o valor lido para seus dgitos individuais
cmd_LCD(0x89,0);
cmd_LCD(digitos[3],1);
cmd_LCD(digitos[2],1);
cmd_LCD(digitos[1],1);
cmd_LCD(',',1);
cmd_LCD(digitos[0],1);
cmd_LCD(0xDF,1);
cmd_LCD('C',1);
}
}
//---------------------------------------------------------------------------

13

//
//
//
//
//

14

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

ISR(ADC_vect)
{
temp = ADC + (ADC*19)/256;

Tcnicas de Projetos Eletrnicos com os Microcontroladores AVR

OBSERVAES

/* O LM35 apresenta uma sada de 10mV/oC


O valor de leitura do AD dado por ADC = Vin*1024/Vref,
como Vref = 1,1V, para converter o valor do AD para graus Celsius,
necessrio multiplicar o valor ADC por 1100/1024
(considerando um digito decimal antes da vrgula)
Utilizando a simplificao matemtica e mantendo a varivel temp com 16
bits, resulta: 1100/1024 = 1 + 19/256 */
}
//------------------------------------------------------------------------void ident_num(unsigned int valor)//converte um nmero decimal nos seus
{
//dgitos individuais no formato ASCII
unsigned char k=0;

Quando for necessrio configurar algum perifrico do ATmegaX8


imprescindvel a consulta ao seu manual. Apesar das semelhanas entre
os microcontroladores da famlia AVR, sempre existem diferenas.
A programao do ATmega8 diretamente portvel aos outros
ATmegaX, tais como: o ATmega16 e o ATmega32 (estes possuem mais
pinos de I/O, incluem o PORTA).
Este material foi desenvolvido como complemento ao livro Tcnicas

digitos[0]=0; digitos[1]=0; digitos[2]=0; digitos[3]=0;

de Projetos Eletrnicos com os Microcontroladores AVR. Neste so

do
{

apresentados os detalhes para a programao do ATmega8. Maiores


digitos[k] = valor%10 + 48; //pega o resto da diviso/10 e salva no
//dgito correspondente.
valor /= 10;
//pega o inteiro da diviso/10
k++;

detalhes tambm podem ser encontrados no stio da ATMEL.


Para os aficionados do Arduino, a nota que ele pode ser comandado
por um ATmega8 ou qualquer ATmegaX8 (o Uno, mais atual, emprega o

}while (valor!=0);
}
//--------------------------------------------------------------------------

ATmega328).

BIBLIOGRAFIA
Application Note

AVR094: Replacing ATmega8 by ATmega88


Manuais

ATmega48A, ATmega48PA, ATmega88A, ATmega88PA, ATmega168A,


ATmega168PA, ATmega328, ATmega328P.

ATmega8, ATmega8L.

Lima, Charles Borges de. Tcnicas de Projetos


Eletrnicos com os Microcontroladores AVR.
Edio do autor - Clube de Autores, 1 ed. Nov/2010.
ISBN 978-85-911400-0-8

Fig. 3 Exemplo 4.

15

16

Você também pode gostar