Hola.
Tengo un problema que no sé a qué se deba. Estoy intentando hacer un reloj en tiempo real (RTC) usando el TIMER0 del pic 16F877. Pero sucede que cuando el programa atiende la rutina de interrupción, éste nunca sale de ella, la instrucción RETFIE siempre me manda hacia el inicio de la rutina de interrupción (0x04). Realmente no sé por qué se da esto, en el inicio de la rutina pongo a cero el bit T0IF del registro INTCON, que es lo que se recomienda para una rutina de interrupción del TIMER0. Ya he revisado los procedimientos a seguir, y todo parece estar bien.
Les agradeceré sus comentarios y sugerencias.
Este es el programa que hice en el MPLAB:
;***Reloj en tiempo real (RTC)***
List p=16F877
#include "p16F877.inc"
RuS equ 0x23
RmS equ 0x24
RdmS equ 0x25
RSeg equ 0x26
RMin equ 0x27
RHrs equ 0x28
org 0x00
goto Inicio
org 0x04
Microsegundos
bcf INTCON,T0IF
incf RuS
movlw 0x04
subwf RuS,0
btfss STATUS,Z
retfie
Milisegundos
bcf STATUS,Z
clrf RuS
incf RmS
movlw 0x0a
subwf RmS,0
btfss STATUS,Z
retfie
Decenas_de_milisegundos
bcf STATUS,Z
clrf RmS
incf RdmS
movlw 0x64
subwf RdmS,0
btfss STATUS,Z
retfie
Segundos
bcf STATUS,Z
clrf RdmS
incf RSeg
movlw 0x3c
subwf RSeg,0
btfss STATUS,Z
retfie
Minutos
bcf STATUS,Z
clrf RSeg
incf RMin
movlw 0x3c
subwf RSeg,0
btfss STATUS,Z
retfie
Horas
bcf STATUS,Z
clrf RMin
incf RHrs
movlw 0x19
subwf RHrs,0
btfss STATUS,Z
goto AM_PM
retfie
AM_PM
bcf STATUS,Z
btfss RHrs,5
bsf RHrs,5
clrf RHrs
return
Inicio
clrf RuS
clrf RmS
clrf RdmS
clrf RSeg
clrf RMin
clrf RHrs
Main
bsf STATUS,RP0 ;Acceso al banco1.
movlw b'00000111' ;Selecciono el clk source y el
movwf OPTION_REG ;valor del prescaler (1:256).
bcf STATUS,RP0 ;Acceso al banco0.
clrf TMR0 ;Limpio el TMR0 y el prescaler.
bsf STATUS,RP0 ;Acceso al banco1.
movlw b'00001111' ;Selecciono el WDT sin
movwf OPTION_REG ;cambiar el valor del prescaler.
clrwdt ;Limpio el WDT y el prescaler.
movlw b'00001110' ;Selecciono el nuevo
movwf OPTION_REG ;valor del prescaler.
bcf STATUS,RP0 ;Acceso al banco0.
movlw b'10100000' ;Habilito la interrupción
movwf INTCON ;del TMR0.
movlw 0x0f ;Cargo el TMR0
movwf TMR0 ;a 18 decimal.
Espera
movlw b'10100000' ;Habilito la interrupción
movwf INTCON ;del TMR0.
nop
nop
nop
nop
goto Espera
end
Tengo un problema que no sé a qué se deba. Estoy intentando hacer un reloj en tiempo real (RTC) usando el TIMER0 del pic 16F877. Pero sucede que cuando el programa atiende la rutina de interrupción, éste nunca sale de ella, la instrucción RETFIE siempre me manda hacia el inicio de la rutina de interrupción (0x04). Realmente no sé por qué se da esto, en el inicio de la rutina pongo a cero el bit T0IF del registro INTCON, que es lo que se recomienda para una rutina de interrupción del TIMER0. Ya he revisado los procedimientos a seguir, y todo parece estar bien.
Les agradeceré sus comentarios y sugerencias.
Este es el programa que hice en el MPLAB:
;***Reloj en tiempo real (RTC)***
List p=16F877
#include "p16F877.inc"
RuS equ 0x23
RmS equ 0x24
RdmS equ 0x25
RSeg equ 0x26
RMin equ 0x27
RHrs equ 0x28
org 0x00
goto Inicio
org 0x04
Microsegundos
bcf INTCON,T0IF
incf RuS
movlw 0x04
subwf RuS,0
btfss STATUS,Z
retfie
Milisegundos
bcf STATUS,Z
clrf RuS
incf RmS
movlw 0x0a
subwf RmS,0
btfss STATUS,Z
retfie
Decenas_de_milisegundos
bcf STATUS,Z
clrf RmS
incf RdmS
movlw 0x64
subwf RdmS,0
btfss STATUS,Z
retfie
Segundos
bcf STATUS,Z
clrf RdmS
incf RSeg
movlw 0x3c
subwf RSeg,0
btfss STATUS,Z
retfie
Minutos
bcf STATUS,Z
clrf RSeg
incf RMin
movlw 0x3c
subwf RSeg,0
btfss STATUS,Z
retfie
Horas
bcf STATUS,Z
clrf RMin
incf RHrs
movlw 0x19
subwf RHrs,0
btfss STATUS,Z
goto AM_PM
retfie
AM_PM
bcf STATUS,Z
btfss RHrs,5
bsf RHrs,5
clrf RHrs
return
Inicio
clrf RuS
clrf RmS
clrf RdmS
clrf RSeg
clrf RMin
clrf RHrs
Main
bsf STATUS,RP0 ;Acceso al banco1.
movlw b'00000111' ;Selecciono el clk source y el
movwf OPTION_REG ;valor del prescaler (1:256).
bcf STATUS,RP0 ;Acceso al banco0.
clrf TMR0 ;Limpio el TMR0 y el prescaler.
bsf STATUS,RP0 ;Acceso al banco1.
movlw b'00001111' ;Selecciono el WDT sin
movwf OPTION_REG ;cambiar el valor del prescaler.
clrwdt ;Limpio el WDT y el prescaler.
movlw b'00001110' ;Selecciono el nuevo
movwf OPTION_REG ;valor del prescaler.
bcf STATUS,RP0 ;Acceso al banco0.
movlw b'10100000' ;Habilito la interrupción
movwf INTCON ;del TMR0.
movlw 0x0f ;Cargo el TMR0
movwf TMR0 ;a 18 decimal.
Espera
movlw b'10100000' ;Habilito la interrupción
movwf INTCON ;del TMR0.
nop
nop
nop
nop
goto Espera
end