Imagina que estás cocinando, ya colocaste agua a hervir, ya licuaste todo lo necesario y de repente tocan el timbre de tu casa, te están interrumpiendo, entonces tu función en ese momento será ir a abrir la puerta, atender a la persona y cerrar la puerta, cuando terminas, regresas a cocinar, pero no vuelves a empezar, sino que sigues cocinando desde donde te quedaste.
Cuando se activa una interrupción, el microcontrolador dejará de hacer lo que está haciendo para realizar la función de interrupción que se haya declarado anteriormente, para después regresar a donde se había quedado.
Una interrupción puede verse como un aviso que puede ser activado tanto por algún proceso específico del microcontrolador (final de conversión del ADC, recepción de datos del módulo EUSART, desborde de timer, etc) o por un cambio externo al mismo (cambio en algún puerto específico, cambio de un pin, etc.).
En este caso analizaremos la interrupción externa, en la sección 9 de la hoja de datos puedes encontrar más información de las interrupciones. Las interrupciones pueden ser de dos tipos, alta prioridad o baja prioridad, en la siguiente práctica se explicará con más detalle esto.
Las interrupciones externas se llaman así por que se activan cuando se recibe un pulso externo al PIC, esto puede ser en los pines RB0/INT0, RB1/INT1, RB2/INT2 o RB3/INT3, podemos configurar si queremos que se disparen al recibir un flanco de subida o un flanco de bajada, mediante el pin INTEDGx en el registro INTCON2.
Cuando se recibe el pulso correspondiente en el bit RBx/INTx se activa un bit bandera correspondiente en INTxIF, esta interrupción se puede desactivar limpiando el bit correspondiente INTxIE. El bit bandera INTxIF debe ser limpiado mediante software en la Rutina de Servicio de interrupción (Interrupt Service Routine ISR) antes de volver a activar las interrupciones.
;INICIALIZACIÓN DE INTERRUPCIÓN EXTERNA bsf INTCON,INT0IE ;Habilitamos bit enable bcf INTCON,INT0IF ;Limpiamos bit bandera bsf INTCON2,INTEDG0 ;Habilitamos interrupcion en flancos de subida bsf INTCON,7 ;Habilita interrupciones de alta prioridad
ISR bcf INTCON,INT0IF ;Limpiar bandera de interrupción externa movlw 0xFF movwf PORTJ ;Encendemos led verde call RETARDO1s ;Esperamos 1 segundo movlw 0x00 movwf PORTJ ;Apagamos led verde bsf INTCON,7 ;Activo interrupciones alta prioridad retfie
En este caso vamos a dejar nuestra función principal con un bucle vacío que se va a repetir infinitamente, en el momento en que se reciba un cambio en el pin de la interrupción externa (RB0/INT0) nuestro programa saltará a la función de interrupción donde se declaró que un led va a encenderse durante un segundo y luego se va a apagar, para posteriormente regresar a nuestro bucle infinito.
Será necesario definir el vector dónde estará ubicada nuestra interrupción, esto se realizará con la siguiente línea:
ORG 0x0008 ;Vector de las interrupciones goto ISR
Crearemos el siguiente código:
LIST P = 18F87J50 ;PIC a utilizar
INCLUDE <P18F87J50.INC>
;************************************************************
;Configuración de fusibles
CONFIG FOSC = HS
CONFIG DEBUG = OFF
CONFIG XINST = OFF
;***********************************************************
;Código
CBLOCK 0x000
recibido
ret1 ;variables para crear un retardo de 1 segundo
ret2
ret3
ENDC
ORG 0x00 ;vector de reset
goto INICIO
ORG 0x0008 ;Vector de las interrupciones
goto ISR
INICIO
;INICIALIZACIÓN DE PUERTOS A UTILIZAR
movlw 0xFF
movwf TRISB ;Puerto B como entrada
movlw 0x00
movwf TRISJ ;Puerto E como salida
;INICIALIZACIÓN DE INTERRUPCIÓN EXTERNA
bsf INTCON,INT0IE ;Habilitamos bit enable
bcf INTCON,INT0IF ;Limpiamos bit bandera
bsf INTCON2,INTEDG0 ;Habilitamos interrupcion en flancos de subida
bsf INTCON,7 ;Habilita interrupciones de alta prioridad
BUCLE
goto BUCLE ;Bucle infinito
ISR
bcf INTCON,INT0IF ;Limpiar bandera de interrupción externa
movlw 0xFF
movwf PORTJ ;Encendemos led verde
call RETARDO1s ;Esperamos 1 segundo
movlw 0x00
movwf PORTJ ;Apagamos led verde
bsf INTCON,7 ;Activo interrupciones alta prioridad
return
RETARDO1s ;Se crea un retardo de 1 segundo
movlw D'255'
movwf ret1
movlw D'255'
movwf ret2
movlw D'11'
movwf ret3
Ret1s
decfsz ret1, F
goto Ret1s
decfsz ret2, F
goto Ret1s
decfsz ret3, F
goto Ret1s
return
END