Timer1, a pesar de cálculos, hay desface grande.

Hola a todos!

He estado usando el Timer1 del pic 16F628, para contar 0,5 segundos (dejo que se sobrepase dos veces, para que cuente 1 segundo). Con esto estoy haciendo un relój de tiempo real.

Ya he configurado el relój, con oscilador interno, prescaler 1:8 y precarga 0Bh (high) y DCh (low timer).

Esto sale según los cálculos hechos con esta fórmula:

TempTMR1 = [(65536 - precarga)*PS]*Tinstr

Donde he dicho:
TempTmr1 = 0,5 (segs)
PS (Prescaler) = 8
Tinstr = 4/4.000.000 = 0.000001 seg = 1uS.

Resultado:
Precarga = 3036 (en Hex es 0BDC)

Pero en la cruda realidad.... esta cosa tiene un desface de 5 segundos más (+) en un minuto. Es demasiado.

En la función de interrupción, el primer código que hay, es el que recarga al Timer, de manera que no hay más código que esté "alargando" la recarga del Timer, atrasándolo y alargando la cuenta.

Me puede decir alguien, qué pasa aquí?
Si alguien ha hecho esto, ¿Qué precarga usó para el Timer1?

Les agradezco mucho!

Publico a continuación la parte del código que respecta al tema:


Código:
list		p=16F628A			; list directive to define processor
#include	<p16F628A.inc>		; processor specific variable definitions
	
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT & _BOREN_OFF & _DATA_CP_OFF & _LVP_OFF & _MCLRE_ON

;RECORDAR HACER POR SOFTWARE QUE SE EVITE EL GOLPE DE ARIETE EN CAÑERÍAS

;Variables de programa:
SEGUNDOS	EQU	0x20
MINUTOS		EQU	0x21
HORAS		EQU	0x22
AUX_SEG		EQU	0x23
PDel0		EQU	0x24
PDel1		EQU	0x25
PDel2		EQU	0x26

org	0x00
	goto	INICIO				;Ir al inicio del programa

org	0x04
	goto	ISR					;Se atiende a interrupción


INICIO
	bsf		STATUS,RP0			;Pasamos de Banco 0 a Banco 1.-
	movlw 	B'00000000'			; Entradas y salidas de PORTs
	movwf	TRISA
	movlw 	B'00000000'
	movwf	TRISB
	bcf		STATUS,RP0			;Pasamos de Banco 1 a Banco 0.-
	movlw	B'00110001'			; TMR1 Enable, 1:8 Prescaler
	clrf	        PORTB				;Limpiar puerto B
	movwf	T1CON				; Registro de configuración TMR1
	movlw	0x0A				; Cargamos 3036 en TMR1 para lograr 500ms.- 0B y DC
	movwf	TMR1H				;  Byte alto de TMR1.-
	movlw	0F
	movwf	TMR1L				;  Byte bajo de TMR1.-
	bsf		STATUS,RP0			;Pasamos de Banco 0 a Banco 1.-
	bsf		PIE1,TMR1IE			; Activar interrupción por TMR1.
	bsf		INTCON,GIE			; Habilitación general de interrupciones.-
	bsf		INTCON,PEIE			; Habilitación de Interrupcion por perifericos.-
	bcf		STATUS,RP0			;Pasamos de Banco 1 a Banco 0.-

	clrf	        SEGUNDOS
	clrf	        MINUTOS
	movlw	D'21'				;Serán las 21:00 horas, 0 minutos y 0 segundos al resetear
	movwf	HORAS
	clrf	        AUX_SEG

LOOP
	goto	        LOOP

ISR
			; Actualizo TMR1:
	movlw	0x0A				; Cargamos 3036 en TMR1.-
	movwf	TMR1H				; Byte alto de TMR1.-
	movlw	0F
	movwf	TMR1L				; Byte bajo de TMR1.-
	bcf		PIR1,TMR1IF			; Borro bandera de control de Interrupcion.-

	incf	        AUX_SEG				;Timer1 contará siempre 500 mS, de manera que debe
	movlw	0x02				; sobrepasarse dos veces para contar un segundo.
	subwf	AUX_SEG,W
	btfss	        STATUS,Z
	goto  	END_ISR

	bsf		PORTA,0				;Led de control que parpadeará cada un segundo.
	call	        DEMOR2
	bcf		PORTA,0

	clrf	        AUX_SEG
	incf	        SEGUNDOS,F			;Incrementar segundos

	movlw	D'60'				;Revisar si contador de SEGs es 60 para inc. minutos
	subwf	SEGUNDOS,W
	btfsc	        STATUS,Z
	call	        INC_MINUTOS		;Incrementar minutos y borrar segundos a cero.

	movlw	D'60'				;Revisar si contador de MINs es 60 para inc. horas
	subwf	MINUTOS,W
	btfsc	        STATUS,Z
	call      	INC_HORAS			;Incrementar horas y borrar a cero minutos

	movlw	D'24'
	subwf	HORAS,W
	btfsc	        STATUS,Z
	clrf         	HORAS				;Pasó un día = 24 horas, horas a cero.

	call	ACTUADOR        ;En fin...

Gracias!
 
el oscilador interno del UC no es preciso, ami tambien me paso esto. Si lo quieres hacer mas preciso utiliza cristales, de preferencia de 4.19Mhz o de 32Khz adaptandolos propiamente.
 
Hm! Por qué 4,19 MHz exactamente?

En verdad ningún cristal es preciso... de eso ya me han advertido los Datasheets de los relojes DS (como el DS1302 por ejemplo).

Que tontería... y cómo es que hay gente que hace relojes de tiempo real con PIC .... me imagino que cada uno de ellos se habrá cabeceado con este problema?

Gracias por tu respuesta.
 
Hm! Por qué 4,19 MHz exactamente?
bueno el valor completo es 4194304 Hz = 2²²


En verdad ningún cristal es preciso
depende de que grado de precision requieras, pero sí es mucho mas preciso y estable que sistemas basados solo en RC

Que tontería... y cómo es que hay gente que hace relojes de tiempo real con PIC .... me imagino que cada uno de ellos se habrá cabeceado con este problema?
lo mismo pienso yo; solo de dan un cierto grado de precision o tolerancia
 
Matibui, muchísimas gracias!

Finalmente conecté un cristal externo de 4,000 MHz y hasta ahora (ya han pasado varios minutos de prueba, y todavía no parece haber desface.

Esto no estaba contemplado en mi circuito impreso, pero por suerte todavía no lo fabriqué.

Gracias por el dato de los "bueno el valor completo es 4194304 Hz = 2²² "

Saludooos!
 
Atrás
Arriba