Ensamblador 6: Interrupciones externas

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 o RB2/INT2, 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 Rx/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      ;Rutina de interrupción
  bcf	INTCON,INT0IF	;Limpiar bandera de interrupción externa
  movlw	0x06		
  movwf	PORTE		;Encendemos led verde
  call	RETARDO1s	;Esperamos 1 segundo
  movlw	0x07
  movwf	PORTE		;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

Tendremos el siguiente código:

    LIST    P = 18F4550	;PIC a utilizar
    INCLUDE <P18F4550.INC>

;************************************************************
;Configuración de fusibles
    CONFIG  FOSC = HS
    CONFIG  PWRT = ON
    CONFIG  BOR = OFF
    CONFIG  WDT = OFF
    CONFIG  MCLRE = ON
    CONFIG  PBADEN = OFF
    CONFIG  LVP = OFF
    CONFIG  DEBUG = OFF
    CONFIG  XINST = OFF

;***********************************************************
;Código
    CBLOCK  0x000
    recibido
  ret1	;variables para crear un retardo de 1 segundo
  ret2
  ret3
    ENDC
    
    ORG 0x0000    ;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	TRISE	;Puerto E como salida
  movlw	0x07
  movwf	PORTE	;Apagamos el led rgb
  ;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	0x06		
  movwf	PORTE		;Encendemos led verde
  call	RETARDO1s	;Esperamos 1 segundo
  movlw	0x07
  movwf	PORTE		;Apagamos led verde
  bsf	INTCON,7	;Activo interrupciones alta prioridad
  retfie


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
Menú