Fork me on GitHub

Microcontrolandos

O Blog está passando por uma fase de mudanças. Todos os posts estão sendo atualizados, códigos, links e imagens estão sendo arrumados. Conteúdos novos ainda estão por vir.

AVR: Timer0

Share:

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.


T[us] = ( 1/ Fosc[MHz] ) * Prescaler * TCNT0





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 ) )




ExemploGerar 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 )




ExemploGerar 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

2 comentários: