Sunteți pe pagina 1din 8

Interrupciones

37

4 INTERRUPCIONES
Un microcontrolador puede poseer una gran variedad de mdulos dentro del mismo chip, por ejemplo: puertos de comunicaciones, convertidores ADC y DAC, comparadores, moduladores de ancho de pulso, etc. Estos mdulos comnmente trabajan independientemente del CPU del microcontrolador para reducir su carga de trabajo. Sin embargo llega el momento en que los mdulos necesitan comunicarse con el CPU, ya sea para transferencia de datos a memoria, procesamiento matemtico o transferencia de informacin de un mdulo a otro. La manera en que los mdulos se comunican con el CPU es interrumpindolo. De aqu el nombre de interrupciones. Cuando ocurre una interrupcin, el CPU deja pendiente lo que estaba haciendo para atender al mdulo que lo interrumpi; una vez atendido, el CPU regresa al punto donde fue interrumpido para continuar lo que estaba haciendo. En los PIC18 USB, la mayora de los mdulos y perifricos pueden generar interrupciones. Una interrupcin siempre va acompaada de una rutina de servicio de interrupcin, llamada, la cual llamaremos RSI (o ISR por sus siglas en ingles). Esta rutina, es la que indica lo que debe de hacer el microcontrolador al ser interrumpido, por lo tanto en la RSI escribimos el cdigo que queremos que el microcontrolador ejecute al ocurrir la interrupcin.

4.1 Funcionamiento de una Interrupcin sin prioridades


Cuando ocurre una interrupcin pasan los siguientes eventos: 1. Se activa una bandera de interrupcin, la cual es un bit que se pone en 1 indicando que ocurri una interrupcin. 2. El procesador deja pendiente lo que estaba haciendo y salta a la localidad 08 de la memoria de programa (respalda el PC en la pila y escribe un 08 en el PC). Esta localidad es llamada Vector de Interrupcin.

Ing. Juan Ramon Terven Salinas

Interrupciones

38

Es a partir de esta localidad donde nosotros debemos escribir el cdigo que queremos que se ejecute cuando ocurre una interrupcin. Comnmente lo que se hace es poner una llamada a una funcin dentro del Vector de Interrupcin y dicha funcin est definida en otra parte del programa.

Para generar el Vector de Interrupcin en la localidad 08 en C18 se hace de la siguiente manera:


#pragma code Interrupcion = 0x8 void VectorInterrupcion (void) { _asm GOTO FuncionInterrupcion _endasm }

En el cdigo se muestra con azul el cdigo que nunca cambia, las palabras de color negro pueden variar al gusto del programador. Observe que dentro de la funcin VectorInterrupcion est un salto a la funcin denominada FuncionInterrupcion.

Una vez creado el Vector de Interrupcion ahora creamos la funcin a la que salta (FuncionInterrupcion) de la siguiente manera:
#pragma code #pragma interrupt FuncionInterrupcion void FuncionInterrupcion(void) { // Aqui ponemos nuestro cdigo // que queremos que se ejecute al ocurrir la interrupcin

// Antes de salir de la rutina de interrupcin debemos // limpiar la bandera de interrupcin que se activ }

La directiva #pragma interrupt indica al compilador que la funcin es una rutina de interrupcin.

A continuacin veremos la interrupcin externa INT.

Ing. Juan Ramon Terven Salinas

Interrupciones

39

4.2 Interrupciones INTx


Las interrupciones tipo INTx tambin llamadas Interrupciones externas, son interrupciones provocadas por eventos externos; estos eventos pueden ser flancos ascendentes o flancos descendentes. Los PIC18 USB posee 3 fuentes de interrupcin de este tipo: INT0 INT1 INT2 La cuales se encuentran en los pines RB0, RB1 y RB2 respectivamente.

Hay que tener en cuenta que al Reset todas las fuentes de interrupcin se encuentran deshabilitadas.

Para habilitar alguna de estas interrupciones usando el lenguaje C18, se usan las siguientes funciones de la librera portb.h: OpenRB0INT OpenRB1INT OpenRB2INT Las cuales se muestran en la Figura 4-1.

Ing. Juan Ramon Terven Salinas

Interrupciones

40

Figura 4-1. Funciones para activar interrupciones INTx [7]

Ing. Juan Ramon Terven Salinas

Interrupciones

41

Ejemplo 4-1. Interrupcin Externa INT1


Armar el circuito de la Figura 4-2. Escribir, compilar y grabar el Programa 4-1 en su tabla de pruebas.

/* Interrupcin INT1 * * Contador en PORTA * Cada vez que recibe un flanco descendente en INT1 reinicia contador */ #include <p18cxxx.h> #include <portb.h> #include <delays.h> // Prototipo de funcion void FuncionInterrupcion(void); // Seccin de variables globales no inicializadas #pragma udata unsigned char contador; //Cdigo para bootloader extern void _startup (void); #pragma code REMAPPED_RESET_VECTOR = 0x1000 void _reset (void) { _asm goto _startup _endasm } // Seccin de cdigo #pragma code // Aqu inicia el programa void main() { TRISA = 0; // PORTA como salida TRISB = 0xFF; // Configura todo PORTB como entrada

ADCON1 |= 0x0f; // Configura pines como digitales // Configura interrupcin externa del pin RB1 OpenRB1INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_ON); // Habilitacin global de interrupciones INTCONbits.GIE = 1; // Inicia contador de pulsos contador = 0;

Ing. Juan Ramon Terven Salinas

Interrupciones
while(1) { LATA = contador; contador ++; Delay10KTCYx(10); //retardo de 10,000 TCYs } } // Vector de Interrupcin (direccin 0x1008 si usamos bootloader) #pragma code Interrupcion = 0x1008 // Si no se usa bootloader es 0x8 void VectorInterrupcion(void) { _asm GOTO FuncionInterrupcion _endasm } /****** Rutina de Interrupcin INT1 *****/ #pragma interrupt FuncionInterrupcion void FuncionInterrupcion(void) { /* Reinicia el contador */ contador = 0; // Limpia la bandera de interrupcin INTCON3bits.INT1IF = 0; } Programa 4-1. INT1 modo compatibilidad

42

Figura 4-2. Circuito uso de INT1

Ing. Juan Ramon Terven Salinas

Interrupciones

43

Ejemplo 4-2. INT1 e INT2 en modo compatibilidad


En el siguiente ejemplo se usan 2 interrupciones externas, INT1 e INT2 con la intencin de mostrar como se procesan 2 interrupciones en el mismo vector de interrupcin en modo compatibilidad. En este ejemplo, al recibir un flanco descendente por INT1 el contador se reinicia y al recibir un flanco descendente por INT2 el contador se detiene o se reanuda. Al circuito de la Figura 4-2 agregue otro pulsador de RB2 a tierra. Escribir, compilar y grabar el Programa 4-2 en su tabla de pruebas.
/* * * * * */ Interrupciones INT1 e INT2 Contador en PORTA Cada vez que recibe un flanco descendente en INT1 reinicia contador cuando recibe flanco descendente en INT2 detiene o reanuda contador

#include <p18cxxx.h> #include <portb.h> #include <delays.h> // Prototipo de funcion void FuncionInterrupcion(void); // Seccin de variables globales no inicializadas #pragma udata char contador; char cuenta; //Cdigo para bootloader extern void _startup (void); #pragma code REMAPPED_RESET_VECTOR = 0x1000 void _reset (void) { _asm goto _startup _endasm } // Seccin de cdigo #pragma code // Aqu inicia el programa void main() { TRISA = 0; // PORTA como salida TRISB = 0xFF; // Configura todo PORTB como entrada

ADCON1 |= 0x0f; // Configura pines como digitales // Configura interrupcin externa del pin RB1

Ing. Juan Ramon Terven Salinas

Interrupciones
OpenRB1INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_ON); // Configura interrupcin externa del pin RB2 OpenRB2INT(PORTB_CHANGE_INT_ON & FALLING_EDGE_INT & PORTB_PULLUPS_ON); // Habilitacin global de interrupciones INTCONbits.GIE = 1; // Inicia contador de pulsos contador = 0; cuenta = 1; while(1) { LATA = contador; if(cuenta) contador ++; Delay10KTCYx(30); } } // Vector de Interrupcin (direccin 0x1008 si usamos bootloader) #pragma code Interrupcion = 0x1008 // Si no se usa bootloader es 0x8 void VectorInterrupcion(void) { _asm GOTO FuncionInterrupcion _endasm } // Seccin de cdigo #pragma code #pragma interrupt FuncionInterrupcion void FuncionInterrupcion(void) { // Si se dispar INT1 if(INTCON3bits.INT1IF) { contador = 0; // reinicia contador INTCON3bits.INT1IF = 0; } // Si se dispar INT2 else if(INTCON3bits.INT2IF) { cuenta = 1-cuenta; // pausa o reanuda contador INTCON3bits.INT2IF = 0; } } Programa 4-2. INT1 e INT2 modo compatibilidad

44

Ing. Juan Ramon Terven Salinas

S-ar putea să vă placă și