Y el mio, que estaba más arriba, pero que se le ha debido de pasar a Enigma:
No se emplean decimales para la temporización del TMR0, ya que lo hago girar una vuelta completa, sin precargarlo y al no haber precarga no se pierde tiempo en la instrucción de precarga (no hay set_timer0()).
Tampoco entra en la interrupción con lo que tampoco se pierde tiempo.
Para esta técnica es necesario usar un cristal de 3,2768MHz ó otro cualquiera de forma que no aparezcan decimales en el cálculo de la temporización y que aunque el cálculo de la temporización sea exacto no haya que precargar al TMR0 (el de 4MHz no sirve), es decir que la precarga sea de 0.
Como alguién habrá deducido esta es la técnica para programar un reloj con un PIC que funcione bien, sin retrasos ni adelantos.
Este es el programa:
Código:
#include <16f876.h>
#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use fast_io(B)
#use delay(clock=3276800) //Para conseguir 1s sin precargar (retrasos) al TMR0
#include <lcd.c>
#include <math.h>
#bit T0IF=0x0B.2
#define radios 4 //Encoder de 4 radios
main()
{
float n;
int16 pulsos;
int8 cuenta_interrupciones;
int16 velocidad_s,velocidad_m;
lcd_init();
lcd_putc('\f');
set_tris_c(0x01); //Entrada de pulsos por RC0
setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_128);
// El TMR0 se desbordará cada: Temp=(256-0)·(4·128)/3,2768=40ms (40ms · 25 = 1s)
setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RTCC);
cuenta_interrupciones=0;
set_timer1(0);
set_timer0(0);
T0IF=0;
while(1)
{
if(T0IF)
{
T0IF=0;
cuenta_interrupciones++;
if(cuenta_interrupciones==25) // 40ms · 25 = 1s
{
pulsos=get_timer1();
n=pulsos/radios;
velocidad_s=floor(n+(n-floor(n))); //Redondea n, por si recibe algún pulso
//de más ó de menos
velocidad_m=velocidad_s*60;
lcd_putc('\f'); //Borra display
lcd_gotoxy(1,1);
printf(lcd_putc,"%lu rev/s %uradios",velocidad_s,radios); //rev/s
lcd_gotoxy(1,2);
printf(lcd_putc,"%lu r.p.m.",velocidad_m); //r.p.m.
cuenta_interrupciones=0;
set_timer1(0);
set_timer0(0);
}
}
}
}
La técnica es no utilizar rutina de interrupción para que no se pierda tiempo.
Un saludo