AVR: Timer0
Características:
- Contador de 8 bits (TCNT0).
- Duas Unidades de Comparação Independentes (OCR0A e OCR0B).
- PWM variável.
- Gerador de Frequência.
- Três fontes de interrupção independente (OCF0B, OCF0A, TOV0).
REGISTROS PRINCIPAIS:
TCCR0A - Timer/Counter Control Register A
TCCR0B - Timer/Counter Control Register B
FONTE DE CLOCK
O Timer0 pode ser incrementado ou decrementado por uma fonte de clock interna ou externa (pino T0). É selecionado através dos bits CS2:CS0, do registro TCCR0B. Através desses bits também é escolhido o prescaler ( somente para clock interno ).
INTERRUPÇÕES
Clique AQUI
MODOS DE OPERAÇÃO:
Normal Mode ( WGM02:WGM00 = 000 )
Este é o modo mais simples, o temporizador(TCNT0) conta até MAX ( 255 ) e depois transborda para 0 continuando a mesma sequência novamente. Neste modo, o valor do temporizador pode ser alterado a qualquer momento. Quando o temporizador transbordar pode ser configurado para gerar a interrupção TOV0.
Exemplo: Gerar interrupção a cada 1ms, com Clock de 16MHz
MikroC PRO AVR
//ATMEGA328
//T = (1 / 16MHz) * 64 * 250
//T = 1000us
void ISR_Timer0() iv IVT_ADDR_TIMER0_OVF
{
//Recarrega o valor do timer
TCNT0 = 5;
//Alterna as saidas da PORTD
PIND = 255;
}
void Init_Timer0()
{
//Normal Mode
WGM00_Bit = 0;
WGM01_Bit = 0;
WGM02_Bit = 0;
//configura prescaler 1:64
TCCR0B.CS00 = 1;
TCCR0B.CS01 = 1;
TCCR0B.CS02 = 0;
// habilita interrupção por overflow
TIMSK0.TOIE0 = 1;
//Carrega valor do timer
TCNT0 = 5;
//habilita int. global
asm sei;
}
void main()
{
DDRD = 255; //PORTD como saida
PORTD = 0;
Init_Timer0();
}
CTC Mode ( WGM02:WGM00 = 010 )
Ao contrário do Modo Normal, onde tivemos que repor o valor temporizador a cada vez que ocorrer um estouro, tendo que gerar uma interrupção e alternar o valor do pino, tudo isso em software. Isso pode ser feito apenas em hardware usando o modo CTC. Neste modo o temporizador limpa o seu valor a cada vez que ele atinja o valor armazenado no registrador OCR0A.
Quando o valor de TCNT0 for igual a OCR0A, será gerado uma interrupção ( caso esteja ativada, e a flag OCF0A será setada ) e a saída do pino OC0A operará da seguinte forma:
T[us] = ( 1/ Fosc[MHz] ) * 2 * Prescaler * ( 1 + OCR0A)
Exemplo: Gerar uma onda quadrada de 1KHz no pino OC0A
MikroC PRO AVR
//ATMEGA328
// T = 1/Fosc * 2 * Prescaler * (1+OCR0A)
//T = 1/16 * 2 * 64 * (1+124)
//T = 1000us
void Init_Timer0()
{
//CTC Mode
WGM00_Bit = 0;
WGM01_Bit = 1;
WGM02_Bit = 0;
//toggle Pino OC0A
COM0A1_Bit = 0;
COM0A0_Bit = 1;
//configura prescaler 1:64
TCCR0B.CS00 = 1;
TCCR0B.CS01 = 1;
TCCR0B.CS02 = 0;
OCR0A = 124;
}
void main()
{
DDRD = 255; //PORTD como saida
PORTD = 0;
Init_Timer0();
}
Fast PWM Mode ( WGM02:WGM00 = 011 ou 111 )
Neste modo pode ser gerado uma onda PWM de alta frequência. O temporizador(TCNT0) conta de BOTTOM até TOP, compara com OCR0A, e depois retorna a BOTTOM ( 0x00 ). TOP será igual á 255 quando WGM2:0 = 3. TOP será igual à OCR0A quando WGM2:0 = 7. Quando TCNT0 = OCR0A, a saída do pino OC0A = 0 ou 1. Quando TCNT0 = 255 ou TOP, a saída do pino OC0A = 1 ou 0. Veja mais detalhes abaixo:
F[Hz] = Fosc[Hz] / ( Prescaler * ( 1 + TOP ) )
Exemplo: Gerar um sinal PWM de 976Hz e 50%, no pino OC0A
MikroC PRO AVR
//ATMEGA328
//F = Fosc / ( Prescaler * ( 1 + TOP ) )
//F = 16000000 / ( 64 * ( 1 + 255 ) )
//F = 976 Hz
void Init_Timer0()
{
//Fast PWM Mode 1 //TOP = 255
WGM00_Bit = 1;
WGM01_Bit = 1;
WGM02_Bit = 0;
//OC0A = 0, TCNT0 = OCR0A
//OC0A = 1, TCNT0 = 0
COM0A1_Bit = 1;
COM0A0_Bit = 0;
//configura prescaler 1:64
TCCR0B.CS00 = 1;
TCCR0B.CS01 = 1;
TCCR0B.CS02 = 0;
OCR0A = 128; //duty Cycle 50%
}
void main()
{
DDRD = 255; //PORTD como saida
PORTD = 0;
Init_Timer0();
}
Phase Correct PWM Mode ( WGM02:00 = 001 ou 101 )
O temporizador (TCNT0) conta de BOTTOM até TOP, compara com OCR0A, depois de TOP até BOTTOM e compara com OCR0A. TOP será igual à 255 quando WGM2:0 = 1 e igual à OCR0A quando WGM2:0 = 5. Quando ++TCNT0 = OCR0A, a saída do pino OC0A será 0 ou 1 e a flag OCF0A será setada. Quando --TCNT0 = OCR0A, a saída do pino OC0A será 1 ou 0 e a flag OCF0A será setada. Quando TCNT0 = 0 a flag TOV0 será setada. Veja mais detalhes na tabela abaixo:
F[Hz] = Fosc[Hz] / ( 2 * Prescaler * TOP )
Exemplo: Gerar um sinal PWM de 490HZ e 50% no pino OC0A
MikroC PRO AVR
//ATMEGA328
//F = Fosc / ( 2 * Prescaler * TOP )
//F = 16000000 / ( 2 * 64 * 255 )
//F = 490 Hz
void Init_Timer0()
{
//Phase Correct PWM Mode 1 //TOP = 255
WGM00_Bit = 1;
WGM01_Bit = 0;
WGM02_Bit = 0;
//OC0A = 0, ++TCNT0 = OCR0A
//OC0A = 1, --TCNT0 = OCR0A
COM0A1_Bit = 1;
COM0A0_Bit = 0;
//configura prescaler 1:64
TCCR0B.CS00 = 1;
TCCR0B.CS01 = 1;
TCCR0B.CS02 = 0;
OCR0A = 128; //duty Cycle 50%
}
void main()
{
DDRD = 255; //PORTD como saida
PORTD = 0;
Init_Timer0();
}
TABELA DOS MODOS DE FUNCIONAMENTO













esse nao precisa limpar a flag ???
ResponderExcluirNao precisa limpar a flag. O Atmega faz isso automaticamente.
Excluir