26.12.13

ATmega16 - Interrupciones

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

Esto tiene una seria desventaja, por ejemplo, supongamos que el uC esta 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 otro tipo de procesamiento de datos es por interrupciones que 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 terminarla 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 USART (transmisión, recepción, buffer vacío).
- Termino 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 solo 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 como 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.






Update 10.09.2014:
Recomendaciones importantes que se deben tomar en cuenta al usar interrupciones:
- Mantener la rutina de interrupción lo mas 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 desabilitar las interrupciones.
- Se debe procurar usar variables "flag" y/o "mailbox" para manejar las interrupciones.


Descargas:
Datasheet ATmega16A
AVR Instruction Set
Source Code

6 comments:

  1. Anonymous23.1.15

    no se donde configuras los puertos de entrada y salida el sph no me da error pero no se para que sirve y GICR me da error y no se para que sirve?, uso el teensy++2.0 que tiene un microcontrolador at90usb1286

    ReplyDelete
    Replies
    1. Hola, bueno en este post programo un ATmega16 y los registros varian dependiendo del microcontrolador que uses, una recomendacion es que tomes de referencia el datasheet, alli encontraras información detallada y muy bien explicada.

      Saludos

      Delete
  2. Pienso hacer un dispensador de papel y necesito ya sea en pic o atmega8, que un sensor que detecta el paso de una moneda me envie una
    señal al micro y este a su vez ponga a mover un motor DC, luego la duracion del movimiento del motor estara sujeta a un timer del micro que tendra determinado
    tiempo configurado y cuando este tiempo se acabe el motor se detiene, entregando una determinada cantidad de papel higienico, hasta que el sensor vuelva a detectar otra moneda y se repite el ciclo. podrias ayudarme? mi correo es david.ife@hotmail.com

    ReplyDelete
    Replies
    1. Hola Ordearte, por favor haz las preguntas especificas en las que necesites ayuda después de ya haber investigado en Google.

      Delete
  3. hola amigo saludos me podrias decir cuando se debe usar flanco de subida, flanco de bajada o cualquier flanco. gracias por compartir tus conocimientos.

    ReplyDelete
    Replies
    1. Hola,

      Todo depende de la aplicacion que quieras realizar, supongamos que quieres detectar cuando un dispositivo 'X' conectado al pin de interrupcion se apaga; lo que se usaria es deteccion por flanco de bajada, ya que el voltaje en el pin de interrupcion cambiaria de 5v a 0v.

      Delete