ATmega16 – Interrupciones

Existe dos formas de procesar datos ingresados hacia el uC, uno es por consulta, que como se vio en el post de GPIO el uC siempre está realizando la lectura de los pines y actualiza la acción de cada pin.

Esto tiene una seria desventaja, por ejemplo, supongamos que el uC está realizando la actualización de pines ubicados en el puerto C y en ese mismo momento ocurre un cambio en un pin del puerto A, es obvio que pasará un tiempo hasta que el uC llegue a leer nuevamente los pines del puerto A, por lo tanto se habrá realizado un cambio pero no será detectado.

El procesamiento de datos por interrupciones consiste en que cada vez que se produzca un cambio en alguno de ciertos pines este avise al uC para que deje lo que estaba realizando y proceda al procesamiento de la interrupción, luego de terminar regresa al programa principal y continua lo que estaba ejecutando el antes de producirse la interrupción.

Este tipo de procesamiento tiene la ventaja de dejar al uC realizando otras actividades hasta que se produzca una interrupción.

Entonces podemos definir a una interrupción como un procedimiento que se lleva a cabo en determinado momento.

Las fuentes de interrupción son:

  • Inicialización o reset.
  • Tres interrupciones externas.
  • Ocho interrupciones de los timers (comparación, captura, desbordamiento).
  • Al completar una transmisión serial por el SPI.
  • Tres por el UART (transmisión, recepción, buffer vacío).
  • Término de conversión ADC.
  • Finalización de escritura EEPROM.
  • Comparador Analógico.
  • Interfaz serial TWI.
  • Escritura en memoria de programa.

Al inicializar el uC las interrupciones están deshabilitadas por defecto.

Cada ISR (Rutina de Servicio de Interrupciones) tiene un habilitador individual, además existe un habilitador global.

Cuando comienza a ejecutarse un ISR se desactiva el habilitador global para evitar aceptar más ISR.

Toda ISR termina con una instrucción de retorno, esta instrucción recupera la dirección de retorno al programa principal y activa el habilitador global.

Las interrupciones ocupan 2 words (16 bits) en la memoria flash, debido a que el ISR es bastante extensa y no entrarían en dos words, se utilizan instrucciones de salto.

Si dos o más interrupciones se activan al mismo tiempo y debido a que solo puede ejecutarse sólo una de ellas, las interrupciones se realizarán tomando la siguiente prioridad:

El RESET es el de mayor prioridad.

Las interrupciones se ejecutan de la siguiente manera:

  • Ocurre el evento.
  • Setea el flag de interrupción.
  • Verifica las interrupciones.
  • Termina la instrucción que se estaba ejecutando.
  • Se guarda la dirección de retorno.
  • Carga el PC de la ISR.
  • Desactiva el habilitador global de interrupciones (I=0)
  • Se desarrolla la interrupción.
  • La instrucción de retorno se encarga de activar el habilitador global y obtener la dirección de retorno.

Interrupciones Externas:

Las interrupciones externas se activan cada vez que existe un cambio de nivel en el pin correspondiente a la interrupción, tiene aplicaciones como un contador de flancos o un contador de eventos externos.

El uC ATmega16 cuenta con tres interrupciones externas INT0, INT1, INT2 que se ubican en los pines 16, 17 y 3 respectivamente.

Los registros que configuran estas interrupciones son los siguientes:

MCUCR: Se encarga de configurar las INT0 e INT1 ya sea por nivel bajo, cambio lógico, flanco de bajada o flanco de subida.

ISC11 Y ISC10 controlan como va ha ser activada la INT1.

ISC01 Y ISC00 controlan como va ha ser activada la INT0.

MCUCSR: Se encarga de configurar INT2 que solo puede ser por flanco de bajada o flanco de subida.

ISC2 controla cómo va ha ser activada la INT2, si es cero se activa con flanco de bajada y si es uno se activa con flanco de subida.

GICR: Se encarga de habilitar las interrupciones, con uno habilitamos las interrupciones y con cero las deshabilitamos.

GIFR: Nos muestra las banderas de estado de las Interrupciones Externas, cada vez que ocurre el evento toma valor uno, además sirve como solicitud de interrupción, es decir, organiza las interrupciones.

Ejemplo:

Recomendaciones importantes que se deben tomar en cuenta al usar interrupciones:

  • Mantener la rutina de interrupción lo más corta posible.
  • Evitar en lo posible de usar rutinas de delay dentro de las rutinas de interrupción.
  • El software de la rutina de interrupción no debe habilitar o deshabilitar las interrupciones.
  • Se debe procurar usar variables “flag” y/o “mailbox” para manejar las interrupciones.