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