06 – Interrupción de Cambio en Puerto B del PIC18F4550

Las interrupciones son muy importantes en los sistemas electrónicos microcontrolados ya que proveen un canal a través del cual los dispositivos periféricos solicitan la atención del microprocesador (que se encuentra dentro del encapsulado) ante eventos tales como: finalización de conversión A/D, desbordamiento de un Timer, click o movimiento de un puntero (ej. ratón), presión de teclas de un teclado, etc.

Todos los dispositivos de hardware de una computadora tienen asignada una interrupción (IRQ) para comunicar al microprocesador que deben ser atendidos. De esta manera el CPU puede pausar momentáneamente la ejecución de un proceso para atender otros y así sucesivamente.

El PIC18F4550 cuenta con las siguientes interrupciones:

  • Externas: en este tipo de interrupciones, el microcontrolador utiliza uno de sus pines I/O para recibir la interrupción desde un dispositivo externo. Estas a su vez pueden ser: INT: denominadas “Edge-Triggered” debido a que se pueden programar para activarse en su flanco de subida o flanco de bajada. Son las interrupciones idóneas para controlar dispositivos externos. De cambio en PORTB: “Interrupt-On-Change”, es un tipo de interrupción que utiliza los bits RB4:RB7 del PIC, la interrupción se activará cuando en alguno de estos pines se produzca un cambio de estado de 1 a 0 o viceversa.
  • Periféricas: son interrupciones que se originan en los módulos periféricos internos (dentro del encapsulado) del microcontrolador, tales como: TIMER, ADC, EUSART, CCPx, etc.

 

Interrupciones de Cambio de PORTB.

La interrupciones más simples son las de “Cambio en PORTB”, cuando están habilitadas el microcontrolador monitorea constantemente los pines KBI0, KBI1, KBI2 y KBI3 que corresponden a RB4, RB5, RB6 y RB7 respectivamente. Cualquier cambio de estado en estos pines activará una interrupción.

El registro INTCON, se utiliza para configurar y habilitar la interrupción de cambio en PORTB, su estructura es la siguiente:

INTCON

  • El bit RBIE: habilita la interrupción de cambio en PORTB al asignarle un valor de 1.
  • RBIF: es la bandera de interrupción de PORTB, se pondrá en 1 cada vez que se produzca un cambio en PORTB. Después de atender la interrupción debe ser inicializada en 0.
  • GIE: Es el bit de habilitación de interrupciones globales, debe activarse asignándole un valor de 1.

Cada vez que se produzca una interrupción, el microcontrolador ejecutará un método, cuya firma típica es: void interrupt isr(void) {}. Inicialmente, dentro de este método se debe verificar que bandera de interrupción está activada para así poder atenderla por medio del código correspondiente. El siguiente segmento de código muestra la estructura básica del método.


void interrupt isr(void)
{
 if(RBIF) //Si hay cambio de estado en PORTB
 {
 //Código de atención de la interrupción
 RBIF = 0; //Desactivar bandera...
 }
}

Siempre se debe verificar si la bandera de interrupción deseada está activada ya que en una aplicación real se tienen varias interrupciones habilitadas.

Ejemplo de implementación

Para demostrar cómo utilizar la interrupción de cambio en puerto B, utilizaremos el siguiente circuito:

10_INT_PORTB

El funcionamiento es simple, el microcontrolador mostrará constantemente un conteo de 0 a 255 en el puerto B. Si se produce un cambio en el puerto B, se detendrá el conteo y se mostrará en los leds en que bit se ha producido el cambio. Ej. Si se cambió el estado de KBI0, se mostrará 00000011, si el cambio sucedió en KBI1 se mostrará 00001100 y así sucesivamente. Pasado un segundo, se continuará con el conteo. El código es el siguiente:


#include <xc.h>;

//BITS DE CONFIGURACION.....
#pragma config PLLDIV = 5, CPUDIV = OSC1_PLL2, USBDIV = 2
#pragma config FOSC = HSPLL_HS, FCMEN = OFF, IESO = OFF
#pragma config PWRT = OFF, BOR = OFF, VREGEN = OFF
#pragma config WDT = OFF, WDTPS = 32768
#pragma config MCLRE = ON, LPT1OSC = OFF, PBADEN = OFF
#pragma config STVREN = ON, LVP = OFF, ICPRT = OFF, XINST = OFF

#define _XTAL_FREQ 48000000

void retardo(int t);
int KBIx;
int old_PORTB = 0B11110000;

void main()
{
 ADCON1 = 0x0F;
 TRISB = 0xFF;
 TRISD = 0;
 PORTD = 0;


 INTCONbits.RBIE = 1; //Habilitar interrupciones de puerto B.
 INTCONbits.RBIF = 0; //Bandera desactivada.
 INTCONbits.GIE = 1; //Interrupciones globales habilitadas.

 while(1)
 {
 for(int i = 0; i <= 255;i++)
 {
 PORTD = i;
 retardo(10);
 }
 }
}

void interrupt isr(void)
{
 if(RBIF) //Si hay cambio de estado en PORTB
 {
 //==============================================
 //Según datasheet debe incorporarse esto...
 if(PORTB)
 {
 asm("nop");
 }
 //==============================================
 KBIx = PORTB ^ old_PORTB; //Hacemos una operación XOR
 old_PORTB = PORTB;
 KBIx = KBIx >> 4;
 switch(KBIx)
 {
 case 1:
 PORTD = 0B00000011;
 break;
 case 2:
 PORTD = 0B00001100;
 break;
 case 4:
 PORTD = 0B00110000;
 break;
 case 8:
 PORTD = 0B11000000;
 break;
 }
 retardo(100);
 RBIF = 0; //Desactivar bandera...
 }
}

void retardo(int t)
{
 for(int i = 0; i <= t; i++)
 {
 __delay_ms(10);
 }
}

El microcontrolador detectará cambios en el puerto B cuando se hace una transición de 0 a 1 y viceversa, esto último podemos comprobarlo manteniendo presionado el botón por más de un segundo y posteriormente soltarlo.

En conclusión, este tipo de interrupción es muy simple y nos ha servido como base para que en futuros artículos podamos abordar las interrupciones de los módulos internos del microcontrolador (nuestro principal objetivo). Volveré posteriormente abordando el tema de las interrupciones externas. Saludos a tod@s desde El Salvador.

Acerca de jjguevara09

Me gusta la electrónica
Esta entrada fue publicada en Uncategorized y etiquetada , , , , . Guarda el enlace permanente.

Una respuesta a 06 – Interrupción de Cambio en Puerto B del PIC18F4550

  1. Tony dijo:

    Gracias ingeniero por su trabajo muy bien explicado.

    Me gusta

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s