Академический Документы
Профессиональный Документы
Культура Документы
02/2011
1 2
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
3 4
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
Tab. 4 - Registradores de I/O que não são funcionalmente iguais aos seus
equivalentes. A tabela mostra onde encontrar os bits dos registradores de I/O que
não estão na mesma posição entre os ATmega.
5 6
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
Tab. 5 - Bits nos registradores de I/O que tiveram seus nomes alterados, mas
preservaram a mesma funcionalidade.
Registradores de controle da USART
No ATmega8, UCSRC e UBRRH dividem o mesmo endereço 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
endereços separados e devem ser acessados como dois registradores
individuais. O bit MSB no registrador UCSRC, que contém o bit de seleção
(URSEL) no ATmega8, é usado para outro propósito no ATmegaX8.
Tab. 6 – Bits dos registradores da USART que tiveram sua funcionalidade alterada.
7 8
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
int main()
Tensão de Operação {
DDRB = 0x00; //pinos do PORTB como entrada
PORTB = 0xFF; //habilita pull-ups do PORTC
DDRD = 0xFF; //PORTC como saída
Tab. 8 – Tensões e velocidades de operação.
UCSR0B = 0x00; //desabilitar RX e TX (para usar os pinos PD0 e PD1)
//pode ser desnecessário
PCICR = 1<<PCIE0;//habilita interrupção por qualquer mudança de sinal no
//Pino PCINT0..PCINT7 (PB0..PB7)
PCMSK0 = 0xFF; //habilita todos os pinos para gerar a interrupção
for(;;);
}
//---------------------------------------------------------------------------
ISR(PCINT0_vect)//quando houver mais de um pino que possa gerar a interrupção,
{ //é necessário 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))
EXEMPLOS cpl_bit(PORTD,PD2);
else if(!tst_bit(PINB,PB3))
cpl_bit(PORTD,PD3);
else if(!tst_bit(PINB,PB4))
Arquivo trata_bits.h utilizado nos programas abaixo. cpl_bit(PORTD,PD4);
else if(!tst_bit(PINB,PB5))
//------------------------------------------------------------------------// cpl_bit(PORTD,PD5);
//Definições de macros para trabalho com bits else if(!tst_bit(PINB,PB6))
cpl_bit(PORTD,PD6);
#define set_bit(adress,bit)(adress|=(1<<bit)) else if(!tst_bit(PINB,PB7))
#define clr_bit(adress,bit)(adress&=~(1<<bit)) cpl_bit(PORTD,PD7);
#define tst_bit(adress,bit)(adress&(1<<bit))
#define cpl_bit(adress,bit)(adress^=(1<<bit)) _delay_ms(50);
//------------------------------------------------------------------------// }
//---------------------------------------------------------------------------
//==========================================================================//
//Cada vez que um botão é pressionado o LED correspondente troca de estado //
// //
//Todos os pinos do ATmegaX8 permitem interrupções externas //
//Entretanto, eles possuem apenas um vetor de interrupção (endereço) //
//Caso exista mais de um pino habilitado, o programador deve verificar qual //
//pino gerou a interrupção. //
//=========================================================================//
//Autor: Charles Borges de Lima - 02/02/2011 //
//=========================================================================//
ISR(PCINT0_vect);
9 10
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
//T/C0
TCCR0B = (1<<CS02)|(1<<CS00); //prescaler = 1024 4 – USO DO AD COM O SENSOR DE TEMPERATURA LM35
TIMSK0 = 1<<TOIE0; //habilita interrupção por estouro
//T/C1
TCCR1B = 1<<CS11; //prescaler = 8 Arquivo LCD.c utilizado no programa abaixo.
TIMSK1 = 1<<TOIE1; //habilita interrupção por estouro
//========================================================================= //
//T/C2 //FUNÇÕES PARA TRABALHO COM LCD 16x2 (controlador HD44780) //
TCCR2B = (1<<CS22)|(1<<CS21); //prescaler = 256 //========================================================================= //
TIMSK2 = 1<<TOIE2; //habilita interrupção por estouro //Autor: Charles Borges de Lima - 04/02/2011 //
//========================================================================= //
sei(); //habilita as interrupções #define DADOS_LCD PORTD //4 bits de dados do LCD na porta D
#define CONTR_LCD PORTD //para facilitar a troca dos pinos do
for(;;); //hardware e facilitar a re-programação
} #define RS PD2 //pino de instrução ou dado para o LCD
//------------------------------------------------------------------------ #define E PD3 //pino de enable do LCD
ISR(TIMER0_OVF_vect){cpl_bit(PORTC,PC0);}
//------------------------------------------------------------------------ //sinal de habilitação para o LCD
ISR(TIMER1_OVF_vect){cpl_bit(PORTC,PC1);} #define pulso_enable _delay_us(1); set_bit(CONTR_LCD,E); _delay_us(1);
//------------------------------------------------------------------------ clr_bit(CONTR_LCD,E); _delay_us(45)
ISR(TIMER2_OVF_vect){cpl_bit(PORTC,PC2);} //----------------------------------------------------------------------------
//------------------------------------------------------------------------
11 12
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
//Sub-rotina para enviar caracteres e comandos, com via de dados de 4 bits //Sub-rotina de escrita no LCD
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void cmd_LCD(unsigned char c, char cd) void escreve_LCD(char *c)
{ {
unsigned char i=2; for (; *c!=0;c++) cmd_LCD(*c,1);
}
DADOS_LCD=(DADOS_LCD & 0x0F)|(c & 0xF0);//primeiro os 4 MSB. //---------------------------------------------------------------------------
//(PD4-PD5-PD6-PD7) -> (D4-D5-D6-D7 LCD)
do
{ Lendo o sensor de temperatura LM35
if(cd==0)
clr_bit(CONTR_LCD,RS);
else //========================================================================= //
set_bit(CONTR_LCD,RS); //LEITURA DO SENSOR DE TEMPERATURA LM32 COM INTERFACE LCD //
//========================================================================= //
pulso_enable; //Autor: Charles Borges de Lima - 04/02/2011 //
//========================================================================= //
if((cd==0) && (c<4)) //se for instrução de retorno ou limpeza, #include "definicoes.h"
//gasta mais tempo #include "LCD.c"
_delay_ms(2);
//------------------------------------------------------------------------
DADOS_LCD = (DADOS_LCD & 0x0F) | (c<<4);//segundo nibble, 4 LSB unsigned int temp; //variável para o valor da temperatura
unsigned char digitos[4]; //variável global para no máximo 5 dígitos
i--;
ISR(ADC_vect);
}while(i>0); void ident_num(unsigned int valor);
} //------------------------------------------------------------------------
//--------------------------------------------------------------------------- int main()
//Sub-rotina para inicialização do LCD com via de dados de 4 bits {
//--------------------------------------------------------------------------- DDRD = 0xFF;
void inic_LCD_4bits() //sequência ditada pelo fabricando do circuito DDRC = 0x00;
{ // integrado HD44780
//o LCD será só escrito então R/W é sempre zero inic_LCD_4bits(); //inicialização do LCD
clr_bit(CONTR_LCD,RS); //RS em zero indicando que o dado para o LCD será escreve_LCD("LEITURA = ");
//uma instrução
clr_bit(CONTR_LCD,E); //pino de habilitação em zero //Configuração do AD
ADMUX = (1<<REFS1)|(1<<REFS0);//referência interna (1,1V), canal 0
_delay_ms(20); //tempo para estabilizar a tensão do LCD, ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);
//após VCC ultrapassar 4.5 V. Como não se sabe o tempo //liga o AD, inicia a conversão, habilita a interrupção, habilita auto-trigger
//que a tensão leva para alcançar 4.5 V , na prática //prescaler=128 para o clock do AD. Deve-se ter cuidado ao selecionar o prescaler
//este tempo pode necessitar ser alterado para centenas //para não utilizar uma frequência acima do limite do AD (de acordo com a
//de milissegundos. //frequência de trabalho da CPU).
ADCSRB = 0x00; //modo de conversão contínuo
DADOS_LCD = (DADOS_LCD & 0x0F) | 0x30; //interface 8 bits DIDR0 = 1<<ADC0D; //desabilita a entrada digital do pino PC0
13 14
Técnicas de Projetos Eletrônicos com os Microcontroladores AVR Técnicas de Projetos Eletrônicos com os Microcontroladores AVR
ISR(ADC_vect)
{ OBSERVAÇÕES
temp = ADC + (ADC*19)/256;
Quando for necessário configurar algum periférico do ATmegaX8 é
/* O LM35 apresenta uma saída de 10mV/oC
O valor de leitura do AD é dado por ADC = Vin*1024/Vref, imprescindível a consulta ao seu manual. Apesar das semelhanças entre
como Vref = 1,1V, para converter o valor do AD para graus Celsius, é
necessário multiplicar o valor ADC por 1100/1024 os microcontroladores da família AVR, sempre existem diferenças.
(considerando um digito decimal antes da vírgula)
Utilizando a simplificação matemática e mantendo a variável temp com 16
bits, resulta: 1100/1024 = 1 + 19/256 */ A programação do ATmega8 é diretamente portável aos outros
} ATmegaX, tais como: o ATmega16 e o ATmega32 (estes possuem mais
//-------------------------------------------------------------------------
void ident_num(unsigned int valor)//converte um número decimal nos seus pinos de I/O, incluem o PORTA).
{ //dígitos individuais no formato ASCII
unsigned char k=0; Este material foi desenvolvido como complemento ao livro Técnicas
digitos[0]=0; digitos[1]=0; digitos[2]=0; digitos[3]=0;
de Projetos Eletrônicos com os Microcontroladores AVR. Neste são
do
{
apresentados os detalhes para a programação do ATmega8. Maiores
digitos[k] = valor%10 + 48; //pega o resto da divisão/10 e salva no
//dígito correspondente.
detalhes também podem ser encontrados no sítio da ATMEL.
valor /= 10; //pega o inteiro da divisão/10
k++; Para os aficionados do Arduino, a nota é que ele pode ser comandado
}while (valor!=0); por um ATmega8 ou qualquer ATmegaX8 (o Uno, mais atual, emprega o
}
//-------------------------------------------------------------------------- ATmega328).
BIBLIOGRAFIA
Application Note
• AVR094: Replacing ATmega8 by ATmega88
Manuais
• ATmega48A, ATmega48PA, ATmega88A, ATmega88PA, ATmega168A,
ATmega168PA, ATmega328, ATmega328P.
• ATmega8, ATmega8L.
ISBN 978-85-911400-0-8
Fig. 3 – Exemplo 4.
15 16