Hola. El motivo por el cual el programa no sale de la interrupcion, es porque tenes habilitadas dos interrupciones en el mismo pin(GP2).
La primer interrupcion que tenes habilitada es la del INTCON.4 (INTE), que es una interrupcion exclusiva del pin GP2(parecida a la del RB0 de un pic16F84).Cuando GP2 cambia de estado, se produce la interrupcion y se setea el flag INTCON,INTF.
La segunda es la interrupt on change(IOC), en la cual seteas el pin GP2 para que produzca la interrupcion.Cuando GP2 cambia de estado, se produce la interrupcion y se setea el flag INTCON,GPIF.
Por lo tanto, dentro de la interrupcion, solo limpiabas 1 flag: el GPIF. Mientras que el otro flag(INTF) tambien se habia seteado, y no era limpiado por soft(en el programa).
El problema sucedio justo por utilizar el GP2 como bit de interrupcion.Como seteaste ambas interrupciones, ambas seteaban sus flags a la vez cuando GP2 cambiaba de estado, y uno de los dos flags(INTF) no era limpiado en el programa, provocando que una vez que el RETFIE habilitaba el INTCON,GIE, se vuelva a producir inmediatamente la interrupcion nuevamente, debido al flag "sucio"(INTF) que no era limpiado por soft.
Por lo tanto:
Modifique el programa para que utilice solo 1 de las 2 interrupciones en GP2. Dejé el INTE, es decir, la interrupcion exclusiva del pin GP2, y elimine el IOC en GP2 para que no se produzcan dos interrupciones por el mismo motivo.
Si bien es posible utilizar ambas interrupciones a la vez, en ese caso, el soft deberia limpiar ambos flags(el INTF y el GPIF) dentro de la rutina de interrupcion.
Tambien es posible utilizar el IOC solo, modificando facilmente el programa que aca te paso.
Espero haya quedado claro.
#include <p12f629.inc>
LIST p=12F629
PDel0 equ 21h ; variable de temporizacion
PDel1 equ 22h ; variable de temporizacion
PDel2 equ 23h ; variable de temporizacion
contador equ 24h ; variable que cuenta los minutos que faltan
;W_TEMP equ 25h
;PCLATH_TEMP equ 26h
;STATUS_TEMP equ 27h
org 0000h ; Origen de reset
goto inicio
org 04h ; origen de interrupcion
; MOVWF W_TEMP
; SWAPF STATUS,W
; CLRF STATUS
; MOVWF STATUS_TEMP
; MOVF PCLATH, W
; MOVWF PCLATH_TEMP
; CLRF PCLATH
movlw b'00000010'
movwf GPIO
bcf INTCON,INTF ;limpiar flag de interrupcion GP2(¡GP2 posee interr exclusiva!)
tmp ; tiempo de 1 segundo para que permanezca encendido el led antes de irse de la interrupcion
movlw .14 ; 1 set number of repetitions (C)
movwf PDel0 ; 1 |
PLoop0 movlw .72 ; 1 set number of repetitions (B)
movwf PDel1 ; 1 |
PLoop1 movlw .247 ; 1 set number of repetitions (A)
movwf PDel2 ; 1 |
PLoop2 clrwdt ; 1 clear watchdog
decfsz PDel2,1 ; 1 + (1) is the time over? (A)
goto PLoop2 ; 2 no, loop
decfsz PDel1,1 ; 1 + (1) is the time over? (B)
goto PLoop1 ; 2 no, loop
decfsz PDel0,1 ; 1 + (1) is the time over? (C)
goto PLoop0 ; 2 no, loop
PDelL1 goto PDelL2 ; 2 cycles delay
PDelL2 clrwdt ; 1 cycle delay
; MOVF PCLATH_TEMP, W
; MOVWF PCLATH
; SWAPF STATUS_TEMP,W
; MOVWF STATUS
; SWAPF W_TEMP,F
; SWAPF W_TEMP,W
retfie
;********** Declaracion de entradas y salidas **********
inicio
movlw 0x07
movwf CMCON ;GP<2:0> digitales
bsf STATUS,RP0 ; cambia a banco 1
movlw b'10010000' ; habilito la interrupcion
movwf INTCON
movlw b'00110100' ; 0,1 y 3 como salidas. 2,4 y 5 como entradas
movwf TRISIO
bcf STATUS,RP0 ; regresa al banco 0
bucle
clrf GPIO
goto bucle
end
Exitos!