2.2 Interrupciones 2.2.1Descripción general
Uno de los recursos de gran aplicación de los procesadores embebidos embebidos son las interrupciones. Éstas forman parte de de un mecanismo de que disponen los dispositivos e incluso los procesos para hacerle saber a la CPU de la aparición de alguna circunstancia que requiera su intervención. De este modo, los dispositivos pueden provocar que la CPU deje por el momento la tarea que estaba realizando y atienda la interrupción. Una vez atendida, seguirá con su labor anterior. Si no existiesen las interrupciones, el controlador debería estar continuamente comprobando el estado del dispositivo para atenderlo cuando éste lo necesite. Todo el tiempo consumido por el controlador en realizar el sondeo del estado de los dispositivos, es tiempo que se desperdicia en la realización de tareas principales de procesamiento, disminuyendo así el rendimiento rendimiento del sistema. Cuando al controlador le llega un pedido de interrupción, lo atiende inmediatamente poniendo una pausa en la ejecución del programa que está corriendo mientras ejecuta una función de interrupción denominada rutina de servicio de interrupción (ISR). Una vez terminado el tratamiento de la interrupción, el controlador vuelve al lugar donde fue interrumpido y retoma la ejecución . Para ello el el microcontrolador guarda el contenido del contador de programa (PC) en una pila; y de esta forma, al terminar la rutina de interrupción se restaura dicho valor.
Se pueden distinguir dos tipos de interrupciones: interrupciones por software e interrupciones por hardware. Interrupciones por software
Son aquellas programadas por el usuario, es decir, el usuario decide cuándo y dónde ejecutarlas. 1
Interrupciones por Hardware
Son aquellas que son provocadas por dispositivos externos al procesador. Su característica es que no son programadas, esto es, pueden ocurrir en cualquier momento del programa. Existen dos clases de interrupciones por hardware: Enmascarables: aquellas que el usuario decide si quiere o no ser interrumpido. (Ej. Timer1 Overflow). No enmascarables: aquellas que siempre interrumpen el programa. (Ej. vector reset): Las interrupciones por hardware pueden ser útiles para procesar eventos esporádicos, tales como pulsadores o entradas de alarmas. También pueden ser útiles en situaciones donde se requiera una baja latencia fija, como por ejemplo, cuando se procesan entradas desde un encoder. 2.2.2 Vectores de interrupción en el ATmega328
El Atmega328 puede ser interrumpido desde varias fuentes de interrupción diferentes. Cada una de estas fuentes de interrupción tiene asociada una dirección en el espacio de memoria del programa. Estas direcciones se conocen con el nombre de vectores de interrupción. La dirección más baja por defecto le corresponde al vector de interrupción por RESET. Todas las interrupciones tienen asignadas un bit individual de habilitación Para habilitar una interrupción dicho bit y el bit Global Interrupt Enable (I) del Status Register (SREG) deben estar en uno. En la tabla siguiente aparece la lista de las 26 fuentes de interrupción del Atmega328. La lista está ordenada por nivel de prioridad. Cuanto menor es la dirección de una interrupción mayor es su prioridad Cuando ocurre una interrupción se pone a cero el bit I y todas las interrupciones son deshabilitadas. El programador puede escribir un uno en el bit I durante la ejecución de la ISR permitiendo el anidado de interrupciones. Todas las interrupciones habilitadas pueden entonces interrumpir la ISR en ejecución
2
328
La tabla siguiente muestra la ubicación del reset y los vectores de interrupción para varias combinaciones de seteo de BOOTRST e IVSEL. Si el programa nunca habilita una fuente de interrupción, el vector de interrupciones no se usa, y se puede ubicar código de programa en estas locaciones.
3
328
Descripción de Registros MCUCR – Registro de control MCU
El registro MCU controla la ubicación de la tabla de vectores de interrupción.
IVSEL: Selección del vector de interrupción
Cuando el bit IVSEL es clareado (0), el vector de interrupciones se ubica al comienzo de la memoria Flash. Cuando es seteado (1), el vector de interrupciones es movido a la sección Boot Loader de la Flash. La dirección real del comienzo de la sección Boot Flash está determinada por los fuses BOOTSZ. Para evitar cambios no intencionales en la tabla de vectores de interrupción, un procedimiento especial de escritura debe seguirse para cambiar el bit IVSEL: a. Escribir el Interrupt Vector Change Enable ( IVCE) en 1. b. Con cuatro ciclos, escribir el valor deseado de IVSEL mientras se escribe un cero en IVCE. IVCE: Habilitación de Cambio de Vector de Interrupciones
El bit IVCE debe setearse en 1 para habilitar el cambio del bit IVSEL. IVCE se clarea por hardware después de los cuatro ciclos de haberse escrito o cuando el IVSEL es escrito.
4
2.2.3Interrupciones externas
Las interrupciones externas se disparan con los pines INT0 e INT1 o con cualquier pin PCINT23..0. Observar que, si están habilitados, las interrupciones dispararán aún cuando dichos pines estén configurados como salidas. Esta característica provee una forma de generar una interrupción por software. El pin de interrupción por cambio PCI2 se disparará si cualquier pin PCINT23..16 cambia de estado (toggles). El pin de interrupción por cambio PCI1 se disparará si cualquier pin PCINT14..8 cambia de estado. El pin PCI0 hará lo mismo si algún pin PCINT7..0 cambia de estado. Los registros PCMSK2, PCMSK1 y PCMSK0 controlan cuales pines contribuyen a las interrupciones de cambio de estado. Estas interrupciones son detectadas asincrónicamente. Las interrupciones INT0 e INT1 pueden ser disparadas por flanco ascendente, descendente, o nivel bajo. La interrupción de nivel bajo es detectada asincrónicamente, no así para el caso de la detección por flanco, ya que hace uso del I/O clock. Descripción de registros EICRA – Registro A de Control de Interrupciones Externas
Bit 7..4 – Res: Reservados Bit 3, 2 – ISC11, ISC10: Control de Sensado de Interrupción 1 Bit 1 y Bit 0
Bit 1, 0 – ISC01, ISC00: Control de Sensado de Interrupción 0 Bit 1 and Bit 0
5
EIMSK – Registro de Máscara de Interrupción Externa
Bit 7..2 – Res: Reservados. Bit 1 – INT1: Habilitación Pedido de Interrupción Externa 1
Cuando INT1 bit está seteado (1) y el bit I del registro de estado (SREG) está seteado (1), la interrupción externa queda habilitada. Bit 0 – INT0: Habilitación Pedido de Interrupción Externa 0
Cuando INT0 bit está seteado (1) y el bit I del registro de estado (SREG) está seteado (1), la interrupción externa queda habilitada. EIFR – Registro de Bandera de Interrupción Externa
Bit 7..2 – Res: Reservados. Bit 1 – INTF1: Bandera de Interrupción Externa 1
Cuando un flanco o un cambio de estado dispara un pedido de interrupción por el pin INT1, INTF1 se pone en 1. Si el bit I en SREG y el bit INT1 en el EIMSK está seteado, el MCU saltará al correspondiente vector de interrupción. La bandera es clareada cuando la rutina de interrupción se haya ejecutado. Alternativamente, la bandera puede clarearse escribiendo un uno lógico en el mismo bit. Bit 0 – INTF0: Bandera de Interrupción Externa 0
Cuando un flanco o un cambio de estado dispara un pedido de interrupción por el pin INT0, INTF0 se pone en 1. Si el bit I en SREG y el bit INT0 en el EIMSK está seteado, el MCU saltará al correspondiente vector de interrupción. La bandera es clareada 6
cuando la rutina de interrupción se haya ejecutado. Alternativamente, la bandera puede clarearse escribiendo un uno lógico en el mismo bit. PCICR – Registro de Control de Interrupción por Cambio de Estado de Pin
Bit 7..3 - Res: Reservados. Bit 2 - PCIE2: Habilitación de Interrupción por Cambio 2 Cuando el bit PCIE2 es seteado (1) y el bit I del SREG está seteado (1), la interrupción
por cambio de estado en el pin se habilita. Cualquier cambio en algún pin PCINT23..16 causará una interrupción. Los pines PCINT23..16 se habilitan individualmente en el registro PCMSK2. Bit 1 – PCIE1: Habilitación de Interrupción por Cambio 1 Cuando el bit PCIE1 es seteado (1) y el bit I del SREG está seteado (1), la interrupción
por cambio de estado en el pin se habilita. Cualquier cambio en algún pin PCINT14..8 causará una interrupción. Los pines PCINT14..8 se habilitan individualmente en el registro PCMSK1. Bit 0 – PCIE0: Habilitación de Interrupción por Cambio 0 Cuando el bit PCIE0 es seteado (1) y el bit I del SREG está seteado (1), la interrupción
por cambio de estado en el pin se habilita. Cualquier cambio en algún pin PCINT7..0 causará una interrupción. Los pines PCINT7..0 se habilitan individualmente en el registro PCMSK0. PCIFR – Registro de Banderas de Interrupción por Cambio de Estado de Pin
Bit 7..3 - Res: Reservados Bit 2 - PCIF2: Bandera 2 de Interrupción por Cambio de estado de Pin
Cuando un cambio lógico en cualquier pin PCINT23..16 dispara un pedido de interrupción , PCIF2 se convierte en uno lógico (1). Si el bit I en SREG y el bit PCIE2 en PCICR están seteados (1), el MCU saltará al vector de interrupción correspondiente. La bandera se clarea cuando se haya ejecutado la rutina de interrupción. Alternativamente, se puede clarear escribiendo un uno lógico en él. Bit 1 – PCIF1: Bandera 1 de Interrupción por Cambio de estado Pin
Cuando un cambio lógico en cualquier pin PCINT14..8 dispara un pedido de interrupción , PCIF1 se convierte en uno lógico (1). Si el bit I en SREG y el bit PCIE1 en 7
PCICR están seteados (1), el MCU saltará al vector de interrupción correspondiente. La bandera se clarea cuando se haya ejecutado la rutina de interrupción. Alternativamente, se puede clarear escribiendo un uno lógico en él. Bit 0 – PCIF0: Bandera 0 de Interrupción por Cambio de estado Pin
Cuando un cambio lógico en cualquier pin PCINT7..0 dispara un pedido de interrupción , PCIF0 se convierte en uno lógico (1). Si el bit I en SREG y el bit PCIE0 en PCICR están seteados (1), el MCU saltará al vector de interrupción correspondiente. La bandera se clarea cuando se haya ejecutado la rutina de interrupción. Alternativamente, se puede clarear escribiendo un uno lógico en él.
PCMSK2 – Registro 2 de Máscara de Cambio de Estado de Pin
Bit 7..0 – PCINT23..16: Máscara de Cambio de Estado en Pin 23..16
Cada bit PCINT23..16 selecciona si la interrupción se habilita para el pin correspondiente de E/S. Si PCINT23..16 está seteado y el bit PCIE2 en PCICR está seteado, la interrupción por cambio de estado de pin se habilita. Si PCINT23..16 está clareado, la correspondiente interrupción está deshabilitada. PCMSK1 – Registro 1 de Máscara de Cambio de Estado de Pin
Bit 7 – Res: Reservado Bit 6..0 – PCINT14..8: Máscara de Cambio de Estado en Pin 14..8
Cada bit PCINT14..8 selecciona si la interrupción se habilita para el pin correspondiente de E/S. Si PCINT14..8 está seteado y el bit PCIE1 en PCICR está seteado, la interrupción por cambio de estado de pin se habilita. Si PCINT14..8 está clareado, la correspondiente interrupción está deshabilitada. PCMSK0 – Registro 0 de Máscara de Cambio de Estado de Pin
8
Bit 7..0 – PCINT7..0: Máscara de Cambio de Estado en Pin 7..0
Cada bit PCINT7..0 selecciona si la interrupción se habilita para el pin correspondiente de E/S. Si PCINT7..0 está seteado y el bit PCIE0 en PCICR está seteado, la interrupción por cambio de estado de pin se habilita. Si PCINT7..0 está clareado, la correspondiente interrupción está deshabilitada.
9
2.2.4 Manejo de Interrupciones
De acuerdo a lo analizado anteriormente, para que se dispare un llamado a una ISR, deben cumplirse tres condiciones: 1 Estar habilitada la interrupción global Interrupts Enable bit (I) en el registro SREG del MCU. Por defecto este bit se encuentra deshabilitado. 2 Estar habilitado el bit particular de la fuente de interrupción tratada. Cada fuente de interrupción tiene un bit de habilitación asociado al registro de control de cada periférico, el cual dispara la ISR para esa interrupción. 3 Producirse la condición de interrupción – por ejemplo: un overflow en el timer1. Para el manejo de interrupciones se hace uso de la función ISR (en versiones anteriores Signal) incluída en
. Hay funciones particulares: sei();
//habilita interrupción global (I)
cli();
//deshabilita interrupción global (I)
La forma de llamar a la interrupción es ISR(vector_de_interrupcion , atributos ) { …código rutina de interrupción…. }
Donde vector_de_interrupcion puede ser uno de los indicados en la tabla siguiente para el ATmega328: Prioridad Nombre del vector
Descripción
1
-
Reset
2
INT0_vect
External Interrupt 0
3
INT1_vect
External Interrupt 1
4
PCINT0_vect
Pin Change Interrupt Request 0
5
PCINT1_vect
Pin Change Interrupt Request 1
6
PCINT2_vect
Pin Change Interrupt Request 2
7
WDT_vect
Watchdog Timeout Interrupt
8
TIMER2_COMPA_vect Timer/Counter2 Compare Match A
9
TIMER2_COMPB_vect Timer/Counter2 Compare Match A
10
TIMER2_OVF_vect
Timer/Counter2 Overflow
11
TIMER1_CAPT_vect
Timer/Counter Capture Event 10
12
TIMER1_COMPA_vect Timer/Counter1 Compare Match A
13
TIMER1_COMPB_vect Timer/Counter1 Compare MatchB
14
TIMER1_OVF_vect
15
TIMER0_COMPA_vect TimerCounter0 Compare Match A
16
TIMER0_COMPB_vect Timer/Counter0 Compare Match B
17
TIMER0_OVF_vect
Timer/Counter0 Overflow
18
SPI_STC_vect
Serial Transfer Complete
19 20
USART_RX_vect USART_UDRE_vect
USART, Rx Complete USART Data Register Empty
21
USART_TX_vect
USART, Tx Complete
22
ADC_vect
ADC Conversion Complete
23
EE_READY_vect
EEPROM Ready
24
ANALOG_COMP_vect Analog Comparator
25
TWI_vect
2-wire Serial Interface
26
SPM_READY_vect
Store Program Memory Read
Timer/Counter1 Overflow
Atributos puede tomar uno de los siguientes valores: ISR_BLOCK : Idéntica a una ISR sin atributos especificados. Las interrupciones globales
son inicialmente deshabilitadas por el hardware AVR cuando entran en la rutina de interrupción, sin que el compilador modifique el estado. ISR_NOBLOCK : la rutina de interrupción corre con I (interrupción global) inicialmente
habilitado. El flag de habilitación de interrupción es activado por el compilador tan pronto como sea posible para asegurar un retardo mínimo para interrupciones anidadas. Este método puede usarse para crear ISR anidadas, sin embargo debe tenerse la precaución de evitar overflow del stack, o evitar entrar indefinidamente a la ISR para esos casos donde el hardware AVR no limpia el flag de interrupción antes de entrar a la ISR. ISR_NAKED : Aquí el usuario es responsable de la preservación del estado de la
máquina incluyendo el registro SREG, como en poner al final de la rutina la función reti(). ISR_ALIASOF(target_vector) : la ISR es enlazada a otra ISR, especificada en target_vector . Esto es compatible con GCC 4.2 o superior.
11