Rutina de interrupción infinita.

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
 
hola

Revise rapido tu programa y como sugrencia te digo que no utilices tantos RETFIE a veces eso trae problemas, utiliza algo asi

.............
goto fin_int

...........
goto fin_int
......

fin_int
RETFIE

y para solucionar tu problema prueba el borrar la bandera de interrupcion al final cuando vas ya a salir de la secuencia de interrupcion, justo antes del retfie, porque a lo mejor no recuerdo pero nose si vale detener ese timer, y si hay como detenerlo haslo cuando hagas las sentencias de interrupcion, porque si esta corriendo, se puede producir un desboradmiento dentro de la interrupcion entonces la bandera se pondria de nuevo en 1

ademas verifica si no estan activadas otras interru`ciones y espero haber solucionado tu problema

Saludos

Jairo
 
Atrás
Arriba