Envío Gratis en compras mínimas de $1200 mxn Enviamos a toda la Republica Mexicana
Buscar

Ensamblador 6: Interrupciones externas (Miuva Pro)

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