2. Interrupciones
Introducción
En los 16F877 hay 14 fuentes posibles de interrupción.
Cuando se da un evento en un determinado módulo, el flag asociado se
pone a 1 y, si las máscaras global (GIE) y particular (y en algunos casos
la de periféricos (PEIE)) están habilitadas, se acepta la interrupción.
En ese caso, el hardware interno del PIC ejecuta varias acciones.
1. Se pone GEIE a cero para no aceptar otra interrupción.
2. Se almacena la dirección de retorno en la pila.
3. El contador de programa se carga con la dirección 0x0004 (que es
la dirección común para todas las interrupci ones).
El programador debe asegurarse de que el código se encarga de
identificar la fuente de la interrupción, guardar y recuperar el contexto
existente antes de producirse la interrupción y poner a cero el flag
asociado a la misma para permitir posteriores identificaciones.
Estas tareas quedan enormemente simplificadas usando directivas
y funciones del lenguaje C del compilador de CCS.
Interrupciones
Las directivas #INT_xxxx
Indican que la función que aparece a continuación corresponde al
tratamiento de una interrupción (no tiene ni necesita parámetros).
En el caso de los PIC 16F877 hay 14 posibles directivas.
#INT_RTCC
#INT_RB
#INT_EXT
#INT_AD
#INT_TBE
#INT_RDA
#INT_TIMER1
#INT_TIMER2
#INT_CCP1
#INT_CCP2
#INT_SSP
#INT_PSP
#INT_BUSCOL
#INT_EEPROM
Desbordamiento de TMR0.
(T0IF)
Cambio en los pines RB<4:7>.
(RBIF)
Flanco en pin RB0.
(INTF)
Fin de conversión A/D.
(ADIF)
Buffer de transmisión USART vacío.
(TXIF)
Dato recibido en USART.
(RCIF)
Desbordamiento de TMR1.
(TMR1IF)
Desbordamiento de TMR2.
(TMR2IF)
Captura / Comparación en módulo CCP1.
(CCP1IF)
Captura / Comparación en módulo CCP2. (CCP2IF)
Envío / Recepción de dato serie síncrono. (SSPIF)
Dato entrante en puerto esclavo paralelo. (PSPIF)
Colisión de bus I2C.
(BCLIF)
Escritura completa en EEPROM de datos. (EEIF)
1
3. Interrupciones
La directiva #INT_DEFAULT
Indica que la función que viene a continuación será llamada si se
dispara una interrupción y ninguno de los flags está activo.
La directiva #INT_GLOBAL
Indica que la función que va a continuación sustituye todas las
acciones que inserta el compilador al aceptarse una interrupción. Sólo
se ejecuta lo que vaya en dicha función.
Ventajas de usar las directivas de interrupciones
El compilador genera el código necesario para saltar a la función
que va tras esta directiva en el momento de la interrupción.
También genera código para salvar al principio y restituir al final el
contexto, y borrará el flag que se activó con la interrupción.
El programador debe seguir encargándose de habilitar las
interrupciones.
Interrupciones
Funciones para gestión de interrupciones
El compilador C de CCS incluye algunas funciones integradas
destinadas a manejar interrupciones.
enable_interrupts (nivel);
nivel es una constante definida en 16F877.h y genera el
código necesario para activar las máscaras necesarias.
Etiquetas de nivel definidas para el 16F877:
GLOBAL
INT_RTCC
INT_RB
INT_EXT
INT_AD
INT_TBE
INT_RDA
INT_TIMER1
INT_TIMER2
INT_CCP1
INT_CCP2
INT_SSP
INT_PSP
INT_BUSCOL
INT_EEPROM
La máscara global (la que hace GIE=1) debe activarse de
manera independiente. Las otras sólo activan la máscara
particular y el PEIE si es necesario.
disable_interrupts (nivel);
Hace la acción contraria a la función anterior, poniendo a
0 las máscaras relacionadas con la interrupción indicada.
2
4. Interrupciones
Existe también una función adicional destinada a configurar el
flanco activo que genera la interrupción externa (en RB0).
ext_int_edge (H_TO_L);
Selecciona flanco de bajada para activar el flag INTF.
ext_int_edge (L_TO_H);
Selecciona flanco de subida para activar el flag INTF.
#INT_EXT
ext_isr() {
......}
enable_interrupts (INT_EXT); // Activa máscara INTE
ext_int_edge (H_TO_L);
// Flag INTF si flanco de bajada.
enable_interrupts (GLOBAL);
// Habilita máscara global de int.
/* Si entra una interrupción por flanco de bajada en RB0, se irá a la
función que aparece tras la directiva #INT_EXT
*/
disable_interrupts (INT_EXT); // Desactiva interrupciones en RB0.
disable_interrupts (GLOBAL); // Desactiva todas las interrupciones.
3