Follow along with the video below to see how to install our site as a web app on your home screen.
Nota: This feature currently requires accessing the site using the built-in Safari browser.
Publica tu programa para ver que hicisteEstoy trabajando con un pic 16f648a con interrupciones por cambios en el port B (4,5,6,7) el problema es que al producir una interrupción el pc salta correctamente a la dirección 0004H y ejecuta la ISR pero al ejecutar la RETFIE no regresa inmediatamente al programa principal sino que se queda, supongo, en un bucle que toma como 52 segundo y después de eso recién continua con el programa principal, lo más raro es que probando el programa en la simulación que hice en MPLAB SIM funciona perfectamente, ¿alguien tiene un explicación sobre esto?
#include <p16f648A.inc>
__CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF
errorlevel -302; suppress message 302 from list file
W_TEMP EQU 0X20
STATUS_TEMP EQU 0X21
CONT1 EQU 0X22
CONT2 EQU 0X23
CONT3 EQU 0X24
ORG H'0'
Inicio goto begin ;
ORG H'4'
int clrf PORTA ;clear porta
clrf PORTB ;clear portb
bcf INTCON,0 ;clear flag rbif el indicador de int de change in portb(7,6,5,4)
bcf INTCON,7 ;clear GIE General enable bit
movwf W_TEMP ;W(A,B)-->W_TEMP(A,B)
swapf STATUS,w ;STATUS(A,B) -*->W(B,A)
movwf STATUS_TEMP ;W(B,A)-->STATUS_TEMP(B,A)
bsf PORTA,6 ;
call dex500ms ;
bcf PORTA,6 ;
call dex500ms ;
swapf STATUS_TEMP,w ;STATUS_TEMP(B,A)-*-> W(A,B)
movwf STATUS ;W(A,B)-->STATUS(A,B)
swapf W_TEMP,f ;W_TEMP(A,B)-*->W_TEMP(B,A)
swapf W_TEMP,w ;W_TEMP(B,A)-*-> W
retfie ;regresa al programa principal
;------------------------------------------------------------------------------------------------------------
begin clrf PORTA ;clear porta,0 call chtobk1
clrf PORTA ;clear porta,0
bcf OPTION_REG,7 ;pull up resistores
clrf VRCON ;deshabilita voltaje de referencia y libera el pin ra(2)
movlw 0x00 ;'00000000' (1e) --> w
movwf PIE1 ;disable periferel interrupts
movwf TRISA ; w-->trisa, pins a(7,6,5,0)salidas, pins a(4,3,2,1)entradas
movlw 0xf0 ;'11110000' (00) --> w
movwf TRISB ;w --> trisb, pins b(7,6,5,4)entradas, pins b(3,2,1,0) salidas
call chtobk0 ;banco 0
movlw 0x07 ;'00000111' --> w
movwf CMCON ;deshabilita comparad. y desconecta ra(0,1,2 y 3) de los comparadores
bcf INTCON,RBIF ;desabilita flag de RB
bsf INTCON,GIE ;habilita interrupciones globales
bsf INTCON,RBIE ;habilita interrupcions RB
loop bsf PORTA,7 ;prende led portb(0)
call dex500ms ;delay 500ms
bcf PORTA,7 ;apaga led portb(0)
call dex500ms ;delay 500ms
goto loop ;
chtobk0 bcf STATUS,RP0;cambia a banco 0
bcf STATUS,RP1;
return;
chtobk1 bsf STATUS,RP0;cambia a banco 1
bcf STATUS,RP1;
return;
chtobk2 bcf STATUS,RP0;cambia a banco 2
bsf STATUS,RP1;
return;
chtobk3 bsf STATUS,RP0;cambia a banco 3
bsf STATUS,RP1;
return;
dex500ms movlw 0x01
movwf CONT3
sigue3 movlw 0xff
movwf CONT2
sigue2 movlw 0xff
movwf CONT1
sigue1 decfsz CONT1,1
goto sigue1;
decfsz CONT2,1
goto sigue2
decfsz CONT3,1
goto sigue3
return
end
#include <p16f648A.inc>
__CONFIG _INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF
errorlevel -302 ; suppress message 302 from list file
;--------------------------DEFINICIONES----------------------------------------------------------
W_TEMP EQU 0X20
STATUS_TEMP EQU 0X21
CONT1 EQU 0X22
CONT2 EQU 0X23
CONT3 EQU 0X24
CONT1_int EQU 0X25 ; <<<--- Variables para otro delay
CONT2_int EQU 0X26 ;
CONT3_int EQU 0X27 ;
;--------------------------PROGRAMA--------------------------------------------------------------
ORG H'0'
ORG H'0'
Inicio goto begin
ORG H'4'
;--------------------------RUTINA DE INTERRUPCION------------------------------------------------
int
movwf W_TEMP ;W(A,B)-->W_TEMP(A,B)
swapf STATUS,w ;STATUS(A,B) -*->W(B,A)
movwf STATUS_TEMP ;W(B,A)-->STATUS_TEMP(B,A)
;-----------------------
; clrf PORTA ;clear porta
; clrf PORTB ;clear portb
bsf PORTA,6
call dex500ms_int
bcf PORTA,6
call dex500ms_int
movf PORTB,w ; <<<--- Hay que leer el puerto
bcf INTCON,0 ;clear flag rbif el indicador de int de change in portb(7,6,5,4)
; bcf INTCON,7 ; <<<--- RETFIE se encarga de esto
;-----------------------
swapf STATUS_TEMP,w ;STATUS_TEMP(B,A)-*-> W(A,B)
movwf STATUS ;W(A,B)-->STATUS(A,B)
swapf W_TEMP,f ;W_TEMP(A,B)-*->W_TEMP(B,A)
swapf W_TEMP,w ;W_TEMP(B,A)-*-> W
retfie ; <<<--- Por favor, no termines las interrupciones de otra manera.
;---------------------------PRINCIPAL------------------------------------------------------------
begin call chtobk1
bcf OPTION_REG,7 ;pull up resistores
clrf VRCON ;deshabilita voltaje de referencia y libera el pin ra(2)
movlw 0x00 ;'00000000' (1e) --> w
movwf PIE1 ;disable periferel interrupts
movwf TRISA ; w-->trisa, pins a(7,6,5,0)salidas, pins a(4,3,2,1)entradas
movlw 0xf0 ;'11110000' (00) --> w
movwf TRISB ;w --> trisb, pins b(7,6,5,4)entradas, pins b(3,2,1,0) salidas
call chtobk0 ;banco 0
clrf PORTA ; <<<--- Para que arranque los leds apagados
movlw 0x07 ;'00000111' --> w
movwf CMCON ;deshabilita comparad. y desconecta ra(0,1,2 y 3)
bcf INTCON,RBIF ;desabilita flag de RB
bsf INTCON,GIE ;habilita interrupciones globales
movf PORTB,w ; <<<--- Hay que leer el puerto
bcf INTCON,0 ; <<<--- Se limpia la interrupcion porque si no cuando se
; habilite RBIE se genera una interrupcion.
bsf INTCON,RBIE ;habilita interrupcions RB
loop bsf PORTA,7 ;prende led portb(0)
call dex500ms ;delay 500ms
bcf PORTA,7 ;apaga led portb(0)
call dex500ms ;delay 500ms
goto loop
;---------------------------CAMBIO DE BANCOS-----------------------------------------------------
chtobk0 bcf STATUS,RP0 ;cambia a banco 0
bcf STATUS,RP1
return
chtobk1 bsf STATUS,RP0 ;cambia a banco 1
bcf STATUS,RP1
return
chtobk2 bcf STATUS,RP0 ;cambia a banco 2
bsf STATUS,RP1
return
chtobk3 bsf STATUS,RP0 ;cambia a banco 3
bsf STATUS,RP1
return
;---------------------------DELAY----------------------------------------------------------------
dex500ms
movlw 0x03
movwf CONT3
sigue3 movlw 0xff
movwf CONT2
sigue2 movlw 0xff
movwf CONT1
sigue1 decfsz CONT1,1
goto sigue1
decfsz CONT2,1
goto sigue2
decfsz CONT3,1
goto sigue3
return
dex500ms_int ; <<<--- No se puede usar la misma rutina de retardo
movlw 0x03 ; en la interrupcion.
movwf CONT3_int ;
sigue3_int ;
movlw 0xff ;
movwf CONT2_int ;
sigue2_int ;
movlw 0xff ;
movwf CONT1_int ;
sigue1_int ;
decfsz CONT1_int,1 ;
goto sigue1_int ;
decfsz CONT2_int,1 ;
goto sigue2_int ;
decfsz CONT3_int,1 ;
goto sigue3_int ;
return ;
end