Curiosity – Explore o 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:
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:
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:

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:

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.
Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
