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:
Gracias!
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!