Curiosity – Explore o TIMER0

Explore os recursos do TIMER0, periférico presente nos microcontroladores PIC. É apresentada a teoria e um exemplo prático na placa Curiosity.
timer0

Continuando a sequência de artigos que exploram os recursos da placa Curiosity, nesse artigo vamos explorar o TIMER0.

Timers da Curiosity

A placa Curiosity vem por padrão com o PIC16F1619. Este microcontrolador de 8 bits possui 4 TIMERs de 8 bits e 5 timers de 16 bits. A seguir vamos apresentar as características do TIMER0.

O TIMER0 foi um dos primeiros periféricos presentes nos microcontroladores PIC e está presente até hoje, com as mesmas características. Este periférico possui as seguintes características:

  • Temporizador/Contador de 8 bits;
  • Leitura ou escrita;
  • Prescaler selecionável;
  • Fonte de clock interna ou externa;
  • Seleção de borda para fonte de clock externa;
  • Interrupção para overflow.

A figura 1 exibe o diagrama de blocos do TIMER0:

curiosity-timer0-blocos
Figura 1 – Diagrama de blocos do TIMER0

Analisando o diagrama de blocos do TIMER0 podemos notar que o mesmo apresenta uma estrutura bem simples. Através da selação da fonte de clock (TMR0CS) pode ser configurado como temporizador ou como um contador de pulsos externos. O sinal de clock pode passar, ou não, por um prescaler e o valor da contagem é armazenado no registrador TMR0. Se habilitada a interrupção, quando houver um overflow da contagem o flag será ligado.

O registrador TMR0 apresenta o valor da contagem. Esse valor pode ser lido, porém também é permitida a escrita de um valor, caso seja necessário iniciar a contagem com um valor. Para configuração do funcionamento do TIMER0 é utilizado o registrador OPTION_REG, conforme exibido na figura 2:

curiosity-timer0-option_reg
Figura 2 – Registrador OPTION_REG bits de configuração do TIMER0

Usando o TIMER0 para contagem de pulsos externos

Para exemplificar, vamos imaginar uma aplicação que necessite ler pulsos externos. O incremento deve ocorrer a cada borda de subida e o TMR0 será efetivamente incrementado a cada 4 pulsos externos.

Como solução podemos seguir os seguintes passos:

  • Configura o pino de entrada de clock externo como entrada digital;
  • Colocar o bit TMR0CS em 1, para incremento do Timer por pulso externo;
  • Colocar o bit TMR0SE em 0, para incremento por borda de subida;
  • Colocar o bit PSA em 1, para habilitar o Prescaler;
  • Configurar os bits PS<2:0> para 001, selecionando o prescaler de 1:4
  • Zerar o registrador TMR0;
  • Iniciar a leitura do sinal externo.

O código a seguir exibe os passos descritos acima:

void main(void) {
    TRISA4 = 1;                //configura pino de clock como entrada
    OPTION_REG = 0B00101001;   //configura o TIMER0:
                               //entrada de clock externo
                               //borda de subida
                               // prescaler de 1:4  
    TMR0 = 0x00;               //zera valor de contagem
    TMR0IF = 0;                //limpa flag
      
    while(1){
        //código da aplicação
    }
}

Usando o TIMER0 como temporizador

Para exemplificar vamos imaginar uma determinada situação onde é necessária uma temporização precisa de 10 ms. Supondo que o circuito está trabalhando com um oscilador externo de 4 MHz, qual seria a configuração do TIMER0?

Para configuração seguimos os seguintes passos:

  • Colocar o bit TMR0CS em 0, para incremento do timer por clock interno;
  • Colocar o bit PSA em 1, para habilitar o prescaler;
  • Configurar os bits PS<2:0>;
  • Iniciar registrador TMR0.

O tempo total de estouro do timer pode ser calculado pela seguinte equação:

[math] t = ciclo de maquina*prescaler*contagem[/math]

Para um tempo de 10 ms temos:

[math] t = 1*10^-6*64*156 = 9,98 ms[/math]

Resumindo:

Para esta solução, selecionamos um prescaler de 64 e o timer deve ter 156 contagens até o seu overflow. Para ter 156 incrementos no TMR0, o mesmo deve ser iniciado com a diferença: 256 – 156 = 100.

Para uso do TIMER0 como temporizador e sem a interrupção habilitada, deve-se monitorar o bit TMR0IF durante o loop. Quando este bit for para nível alto significa que aconteceu o overflow do timer. Imediatamente após o overflow, deve-se iniciar o Timer com o valor inicial e limpar o flag de estouro do timer.

O código a seguir exibe os passos descritos acima:

void main(void) {
             
    OPTION_REG = 0B00001101;  //configura o TIMER0:
                              //clock interno
                              //prescaler de 1:64  
    TMR0 = 100;               //inicia o timer com 100
    TMR0IF = 0;               //limpa flag
      
    while(1){
        if(TMR0IF){
            TMR0 = 100;               //inicia timer com 100
            TMR0IF = 0;                //limpa flag
            
            //aplicação
        }
    }
}

Vamos a um exemplo na placa Curiosity. O exemplo a seguir exibe como usar o TIMER0 para piscar um LED na placa.

Exemplo – Usando o TIMER0 para piscar um LED na placa Curiosity

O exemplo a seguir exibe como piscar o LED D4 da placa Curiosity, utilizando o TIMER0 como temporizador. O LED inverterá o seu estado em aproximadamente 500 ms. O código foi gerado utilizando o MCC. A figura 3 exibe a configuração do TIMER0 no MCC:

Curiosity-timer0-mcc-03
Figura 3 – Configuração do TIMER0 no MCC

O código a seguir, gerado pelo MCC, faz a configuração do TIMER0:

void TMR0_Initialize(void) {
    // Set TMR0 to the options selected in the User Interface

    // PSA assigned; PS 1:256; TMRSE Increment_hi_lo; mask the nWPUEN and INTEDG bits
    OPTION_REG = (OPTION_REG & 0xC0) | 0xD7 & 0x3F;

    // TMR0 12; 
    TMR0 = 0x0C;

    // Load the TMR value to reload variable
    timer0ReloadVal = 12;

    // Clearing IF flag
    INTCONbits.TMR0IF = 0;
}

O loop principal da aplicação é exibido no código abaixo:

while (1) {
    while (!TMR0IF);   //enquanto não ocorrer o estouro do timer
                       //o intervalo de estouro será de aprocimadamente 0,5 s
    TMR0_Reload();     //reinicia timer
    TMR0IF = 0;        //limpa flag de estouro do timer  
    D4_Toggle();       //inverte os estado do led
}

A figura 4 exibe o funcionamento do código acima na placa Curiosity:

Curiosity-timer0-resultado
Figura 4 – Resultado Final da aplicação

Você pode acessar o projeto apresentado acima, clicando aqui.

Entender o funcionamento dos timers é fundamental para as aplicações com microcontroladores. Nos próximos artigos iremos explorar os outros timers.

Caso tenha alguma dúvida ou sugestão, deixe seu comentário abaixo.

Notificações
Notificar
guest
0 Comentários
Inline Feedbacks
View all comments

WEBINAR

Visão Computacional para a redução de erros em processos manuais

DATA: 23/09 ÀS 17:00 H