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.









