Interrupciones

Las interrupciones son eventos que le notifican al microcontrolador que una situación excepcional ha sucedido, esta situación puede estar prevista, pero no se puede determinar en qué momento va a suceder, como por ejemplo la pulsación de un botón por parte del usuario, la llegada de un mensaje por el puerto serial o la finalización de una conversión análoga a digital.

En cualquiera de todos los casos se tiene el microcontrolador operando normalmente en su programa principal hasta que cualquiera de estos (u otros) eventos dispara la interrupción.

Por tratarse de situaciones excepcionales, es de suponerse que en el mayor de los casos vamos a querer atender esos eventos que las disparan y escribir algunas líneas de código que se ejecuten como respuesta, pero antes debemos entender qué pasa en el momento que ocurre una interrupción.

Primero debemos aclarar que existen varios tipos de origen de interrupción, y cada uno de ellos tiene una prioridad, o sea que al momento de presentarse dos al tiempo, se atenderá la de mayor importancia. Otro aspecto que debemos tener muy en cuenta es que no existen las interrupciones anidadas, es decir, una vez se esté atendiendo una interrupción no habrá posibilidad de que otra sea atendida, sin importar que sea de mayor prioridad que la actual.

Habilitadas las interrupciones, una vez se presente una, el microcontrolador terminara de ejecutar la última instrucción en la que se encontraba en ese momento y realizara el reconocimiento de la interrupción, que consiste en suspender el programa principal.

Luego se pasa a la arbitración donde se determina el tipo de interrupción y su prioridad, acto seguido se almacena (Stacking) el punto del programa donde se suspendió, con el fin de volver ahí una vez se atienda la excepción.

Posteriormente se pasa a la Determinación del Vector, aquí es donde la función que determina el tipo de interrupción lleva al microcontrolador a ejecutar la rutina correspondiente que atiende el evento que generó la interrupción.

Durante el proceso de arbitración se activa (pasa a estado lógico 1) la bandera correspondiente al tipo de interrupción, con la detección de esa bandera es que dentro de la Determinación del Vector podemos enviar al programa a ejecutar las líneas de código que necesitemos. Una vez atendida la interrupción debemos poner la bandera en estado lógico 0.

Como dijimos anteriormente, una vez se dispare una interrupción no se podrá atender otra hasta que la primera haya sido finalizada, es por esto que es una buena práctica usar el mínimo código posible y salir lo más pronto de cada interrupción, con el fin de no correr el riesgo de  ignorar alguna otra de mayor importancia o que suponga un punto crítico dentro del funcionamiento de nuestro programa.

Así como es importante ser lo más eficientes posible al atender y salir de una interrupción, también es importante identificar los puntos críticos donde nuestro microcontrolador realiza una tarea que no puede ser interrumpida. Una vez sean identificados se deben deshabilitar las interrupciones al momento de llegar a tales puntos y habilitarlas nuevamente cuando se termine de ejecutar el código.

Anteriormente indicamos que existen distintos tipos de origen de interrupción, estos son:

  • Reset del microcontrolador
  • Pin externo
  • Cambio de estado en un puerto
  • Desbordamiento del Timer0
  • Periféricos

El Reset tiene mayor prioridad sobre cualquier otra interrupción, y como su nombre lo indica, reinicia el programa del microcontrolador.

En la lista parece que hay pocas fuentes de interrupción, pero cuando hablamos de periféricos nos referimos a que podemos obtener una por cada periférico que tiene nuestro microcontrolador, a continuación listamos algunos, cabe aclarar que la lista se puede alargar o acortar dependiendo de la referencia que estemos usando, por eso siempre es bueno tener a mano la hoja de datos:

  • Finalización de conversión análogo a digital
  • Recepción por puerto serial
  • Transmisión por puerto serial
  • Desborde del Timer1
  • Comparación, Captura o PWM
  • Falla en el oscilador
  • Escritura completa en memoria EEPROM
  • Colisión de datos

En próximos ejemplos explicaremos la configuración y funcionamiento de cada interrupción, al final de este artículo aparecerán los enlaces a cada uno conforme estén disponibles.

En estos enlaces puedes encontrar ejemplos de cómo funcionan las interrupciones: