Interrupciones externas

Los PICs tienen la habilidad de crear interrupciones en el código cuando cambia el estado de una entrada y así se le ha indicado.

La interrupción se definiría como decirle al PIC "deja absolutamente todo lo que estés haciendo y atiende a la función que he escrito para cuando ésto ocurra". Dicha función es la ISR.

Las patas de interrupción externa de un PIC suelen ser la RB0/INT (Lo de INT ya da una pista) y las patas de RB4 a RB7. Normalmente las patas RB4-7 se deben activar todas a la vez y cuando se crea el cambio de estado la ISR no distingue cuál ha sido la patilla responsable, a no ser que lo hagas distinguir mediante código.

Por manías mías, yo no utilizo las funciones del CCS para crear interrupciones, sino que creo las mías propias para el mismo programa, pero podríais verlas en la librería del PIC correspondiente y usarlas al gusto.

El mundillo de las interrupciones se encuentra en el registro INTCON del PIC, que normalmente se encuentra en la dirección 0x0B. De dicho registro, para las interrupciones externas, nos interesan 5 bits:

  • GIE: Global Interrupt Enable. Habilita o deshabilita las interrupciones globalmente, es decir, afecta a todas
  • INTE: Habilita o deshabilita la interrupción por cambio de estado en el pin INT (Rb0)
  • INTF: Es la llamada "bandera", cuando ha ocurrido la interrupción en INT, se pone en 1, debe ser bajada a 0 mediante código.
  • RBIE: Habilita o deshabilita la interrupción por cambio de estado en los pines RB4-RB7
  • RBIF: Es la bandera de cambio en RBIE, también hay que bajarla mediante código.

La función de habilitar una interrupción, ocurre de la siguiente forma:

  • Ocurre la interrupción o se inicializa el PIC
  • Se habilita GIE
  • Se habilita INTE o RBIE
  • Se baja la bandera INTF o RBIF
  • Se espera a que ocurra la interrupción, se lleva a cabo la ISR, se vuelve a configurar la interrupción y se continúa desde el punto del programa en el que estaba el PIC cuando le dijimos que lo dejase todo.

Para ello definimos al principio del código los bits de la configuración

#Bit GIE=0x0B.7
#Bit INTE=0x0B.4
#Bit INTF=0x0B.1
#Bit RBIE=0x0B.3
#Bit RBIF=0x0B.0

Automáticamente después escribimos las funciones que habilitan la interrupción y bajan la bandera en cuestión:

void intenab(){
GIE=1;
INTE=1;
INTF=0;
}
void rbienab(){
GIE=1;
RBIE=1;
RBIF=0;
}

Lo siguiente antes del main es escribir la ISR. ¿Cómo indicamos qué ISR se debe llevar a cabo cuando ocurra la interrupción en INT o RB4-7? Mediante una directiva del preprocesador:

#INT_EXT
//Ésta ISR se llevará a cabo cuando la interrupción ocurra en INT/RB0
void isrint(){
...
intenab();
}
#INT_RB
//Y ésta cuando la interrupción ocurra en RB4-7
void rbisr(){
...
rbienab();
}

Como veis, ya he incluido la función de habilitar la interrupción justo al final de ésta, para que pueda volver a ocurrir otras veces.

Por último, ya escribimos la función main, en la que incluiremos también las de habilitar interrupción, sin olvidar que se debe configurar aquellos pines que queramos que produzcan interrupción como entradas:

void main(){
//Configuración y limpieza de puertos
//Otras configuraciones
...
intenab();
rbienab();
while(1){
   ...
}
}

De ésta forma, una vez esté todo configurado, al cambiar el estado de un pin se producirá la interrupción correspondiente.

También podemos configurar si queremos que la interrupción se produzca por flanco de bajada o de subida, es decir, si se debe producir cuando el pin pase de 0 a 1 lógico o al contrario, para el pin INT. Ésto se hace mediante el registro OPTION_REG (0x81h), concretamente el bit 6, INTEDG. Poniendole un 1 la interrupción se hará cuando el flanco suba (de 0 a 1), y con un 0 ocurrirá lo contrario.

Extra: el extraño caso del PIC12F675

Éste pequeño, pero matón, PIC trae un pin de INT y además podemos activar la interrupción por cambio de flanco entre los pines GP0 y GP5 (es decir, todos...), pero trae consigo la genialidad de poder seleccionar cuáles de ellos crean interrupción y cuáles no, mediante el registro IOC (0x96h), en el que escribiremos como si se tratase de un TRIS cuáles de los pines crearán interrupción con un 1.

En éste caso la directiva de preprocesador a usar para la ISR será #INT_RA

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *