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…
.
.
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.