Timer de precisão com TIMER1

O post anterior mostrou o principio básico do funcionamento dos Timers.

Este post mostra um exemplo de desenvolvimento de um Timer, utilizando o TIMER1.

Dois fatores fazem esse exemplo contar com maior precisão, se comparado ao post anterior (TIMER0), o primeiro é o fato do TIMER1 ser um contador de 16 bits, ao passo que o TIMER0 é de 8 bits. Isso eleva o nivel de precisão de 2^8 para 2^16, ou seja de 256, para 65536, a saber 25.600% mais preciso!!! Outro ponto que contribui um pouco para o aumento da precisão neste exemplo, é o fato de que nele, não utilizamos variáveis do programa C para contagem do tempo, ou melhor, as utilizamos apenas para ligar e desligar o “tick” que é o pulso de contagem.

Anexo existe um excel que é utilizado para setar as diversas variaveis do modelo, a serem programadas no Mikroc, tais variaveis que influem no “tick” são, o tempo do prescaler, o tamanho da variavel de controle do Mikroc (contador), e o valor inicial a ser atribuido para os 2 bytes do contador.

Este exemplo utiliza o mesmo hardware do post anterior, porem é feito a tecnica de atualizar o valor do contador com um subtotal inicial, conforme planilha de calculo que anexaremos. Com esta planilha podemos calcular com precisão, qualquer valor de tempo para o “tick” do nosso temporizador. Obviamente o caso mais comum é de contagem de 1 segundo. Mas podemos por exemplo definir a contagem com 1 milissegundo, ou microssegundo, etc…

ScreenShot

.

.

Calculo do Timer 1 (anexo para calculo dos valores do timer1)

E aqui o exemplo funcional, mesmo hardware do post anterior, bom uso.

// LCD module connections
sbit LCD_RS at RD0_bit; //pino 4 do lcd
 sbit LCD_EN at RD1_bit; //pino 6 do lcd
 sbit LCD_D4 at RD2_bit; //pino 11 do lcd
 sbit LCD_D5 at RD3_bit; //pino 12 do lcd
 sbit LCD_D6 at RD4_bit; //pino 13 do lcd
 sbit LCD_D7 at RD5_bit; //pino 14 do lcd
 sbit LCD_RS_Direction at TRISD0_bit;
 sbit LCD_EN_Direction at TRISD1_bit;
 sbit LCD_D4_Direction at TRISD2_bit;
 sbit LCD_D5_Direction at TRISD3_bit;
 sbit LCD_D6_Direction at TRISD4_bit;
 sbit LCD_D7_Direction at TRISD5_bit;
 // End LCD module connections

unsigned char txt[15]; // variavel para lcd out imprimir numeros
 unsigned cnt_seg2; //contador de segundos timer1
 unsigned int contagem; //contador do timer1

void interrupt() //interrupcao do timer1
 {
 //timer 1
 if (TMR1IF_bit){ //se overflow esse if e redundante pois se esta nesta funcao ocorreu o overflow mantive so para fins didaticos
 TMR1IF_bit = 0; //reseta o overflow
 TMR1H = 0x0B; //atualiza o valor de ajuste no contador vide excel
 TMR1L = 0xDC; //atualiza o valor de ajuste no contador vide excel
 contagem++; //conta 1 estouro, pelo calculo cada estouro corresponde a X segundos
 }
 //timer1 final

}

<span style="line-height: 1.5em;"> </span>

void main(){

<span style="line-height: 1.5em;">TRISA = 0b00000001; //ra0 input analogico lm35, demais outputs</span>

TRISB = 0b00000000; // PORTB todas saidas
 TRISC = 0b00000000; //PORTC todas saidas
 TRISD = 0b11000000; //PORTD rd7 e rd6 botao, demais saidas do lcd

//termometro porta analogicas
 ADCON1 = 0b01000000; // 0- left justif 1- opcao osc, , 00-void, 0000 portA toda analogica, vdd e vss como ref.
 CMCON = 0x07; // Disable Comparators

//TIMER1 inicio
 cnt_seg2 = 0; //contador de segundos timer1
 contagem =0; //contador de interrupcoes timer 1
 PORTB.F2 =0; //led pisca timer1
 T1CON = 0b00111101; // configuracao inicial timer 1 prescaler 8, osc enabled, ver no datasheet
 PIR1.TMR1IF =0; //limpa overflow
 TMR1H = 0x0B; //update no valor inicial do contador ajuste fino
 TMR1L = 0xDC; //update no valor inicial do contador ajuste fino
 TMR1IE_bit = 1; //habilita a interrupcao do timer1;
 INTCON = 0b11000000; //configurador geral de interrupcoes - vide datasheet
 //TIMER 1 FIM
 Lcd_Init(); // Initialize LCD
 Lcd_Cmd(_LCD_CLEAR); // Clear LCD display
 Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off

*/
 //================= loop principal - inicio =================//
 //================= loop principal - inicio =================//
 //================= loop principal - inicio =================//

Lcd_Out(2,1,"Timer1");

while(1)
 {

// tratamento do TIMER1
 if(contagem > 10){ //10 == 5 sec, 20 == 10 sec
 portb.F2=~portb.F2; //inverte status do led - pisca
 cnt_seg2++; //contador de ticks incrementa, ex 1 tick = 1 segundo
 inttostr(cnt_seg2,txt);
 Lcd_Out(2,8,txt);
 contagem =0; //zera contador de estouros
 }

}
<pre>

Exemplo de calculo na planilha (anexa) para definir cada “tick” em 1 centesimo de segundo (centi-segundo), ou 0,01 segundos.

ScreenShot