Necesito incrementar un cronómetro a 10 hz usando el timer1 en un PIC16F628. El reloj externo es 1Mhz, suministrado por un oscilador empaquetado (EPSON sg8002db). Sin preescalador, el valor para configurar el temporizador en (creo) debería ser:
tics de reloj en 1 segundo: 1000000
el temporizador marca en 1 segundo: 250000 (reloj / 4)
tics del temporizador en 1/10 de segundo: 25000 (tics del temporizador / 10)
Entonces: 65536 - 25000 = 40536
pero debo tener en cuenta la latencia desde el desbordamiento del temporizador hasta cuando se restablece el valor del reloj: este es el número de ciclos que toma desde el desbordamiento que se produce hasta que configuro el valor del temporizador.
El código IRQ es:
irq movwf w_temp ; save state
swapf STATUS, w
clrf STATUS
movwf status_temp
movf PCLATH, w
movwf pclath_temp
clrf PCLATH
btfss PIR1,TMR1IF ; timer1 IRQ?
goto notimer1
bcf PIR1,TMR1IF ; yes, clear it
movLw T1SPEED >> 8 ; reset timer1
movwf TMR1H
movLw T1SPEED & 0xff
movwf TMR1L ; timer1 is off and running again
call timer ; increment clock
notimer1 btfss INTCON, T0IF ; timer0 IRQ?
goto notimer0
bcf INTCON, T0IF ; yes, clear it
call led_set ; update display
btfss PORTA,6 ; button pressed?
goto nobut
clrf digit0 ; yes, reset clock
clrf digit1
clrf digit2
clrf digit3
nobut
notimer0 movf pclath_temp, w ; restore state
movwf PCLATH
swapf status_temp, w
movwf STATUS
swapf w_temp, f
swapf w_temp, w
retfie
Lo que me parece un lugar en la región de unos 14 ciclos, por lo que LATENCY = 14
65536 - (25000 - LATENCIA) = 40550
pero esto da un reloj que es demasiado lento, perdiendo varios segundos por minuto. Si cambio el valor de LATENCIA a ~ 200 (por ejemplo, configurar el temporizador 1 a 40736), está cerca, dentro de 1 segundo por minuto, pero aún no es exacto. De hecho, con LATENCY = 199, es demasiado rápido y con LATENCY = 200, es lento.
No puedo ver dónde se están gastando estos ciclos adicionales: establece el valor del reloj a primera hora en la rutina IRQ. No puedo encontrar nada en la hoja de datos acerca de que el temporizador 1 se haya detenido durante una rutina de interrupción, ¿no es así? Si es así, eso sería un fastidio, porque la rutina toma una cantidad variable de ciclos dependiendo de los dígitos que se desborden.
¿Es necesario elegir 2 valores de recarga diferentes y alternar entre ellos para alcanzar exactamente 10 hz?