Interrupción en el controlador AVR en Atmel AVR Studio. Interrupciones - Estudiar AVR - Catálogo de artículos - Microcontroladores: ¡es fácil! ¿En qué entorno programar las interrupciones del microcontrolador?

Los sistemas de interrupción son una parte importante de cualquier sistema de control.

La eficiencia con la que el sistema de microprocesador realiza sus funciones depende en gran medida de su funcionamiento. La estructura general del sistema de interrupción MK-51 se muestra en la Fig. 14.3.

Los microcontroladores de la familia MK-51 brindan soporte para cinco fuentes de interrupción:

* dos interrupciones externas que llegan a través de las entradas INT0 e INT1 (líneas de puerto P3: P3.2 y P3.3, respectivamente);

* dos interrupciones de los temporizadores/contadores T/C0 y T/C1;

* interrupción del puerto serie.

Las solicitudes de interrupción se registran en los registros de funciones especiales del microcontrolador: los indicadores IE0, IE1, TF0, TF1, las solicitudes de interrupción de INT0, INT1, T/C0 y T/C1 están contenidos en el registro de control TCON (Tabla 14.4), y los indicadores RI y TI solicita una interrupción del puerto serie, en el registro SCON para controlar el puerto serie.

Tabla 14.4. Formato de registro TCON

0 IT0 Configuración del tipo de interrupción INT0

1 IE0 Indicador de solicitud de interrupción INT0

2 IT1 Configuración del tipo de interrupción INT1

3 IE1 Indicador de solicitud de interrupción INT1

4 TR0 Habilitar temporizador/contador 0

5 TF0 Temporizador/contador de indicador de desbordamiento (solicitud de interrupción) 0

6 TR1 Habilitar temporizador/contador 1

7 TF1 Bandera de desbordamiento (solicitud de interrupción) del temporizador/contador 1

Los indicadores TF0 y TF1 se configuran por hardware cuando el temporizador/contador correspondiente se desborda (más precisamente, cuando T/Cx pasa del estado "todos unos" al estado "todos ceros").

Los indicadores IE0 e IE1 los establece el hardware desde las interrupciones externas IT0 e IT1, respectivamente. Una solicitud externa puede hacer que el indicador se establezca cuando el nivel de señal en la entrada correspondiente es bajo o cuando esta señal cambia de nivel alto a bajo (con una frecuencia que no excede la mitad de la frecuencia del reloj externo del MK).

El tipo de solicitud se configura mediante software que configura los bits IT0 e IT1 en el registro de control TCON. Establecer ITx = 0 configura el sistema de interrupción para solicitar un nivel de señal bajo, ITx = 1: configura la interrupción para solicitar un nivel de señal bajo.

Los indicadores TI y RI los establece el hardware de la interfaz serie después del final de la transmisión o después del final de la recepción, respectivamente.

Todos los indicadores de solicitud de interrupción especificados están disponibles mediante programación para configurarlos y restablecerlos. Configurar el indicador de solicitud de interrupción en el software da como resultado la misma respuesta del microcontrolador que configurar el mismo indicador en el hardware.

Los indicadores TF0 y TF1 se restablecen mediante hardware cuando el control se transfiere a la rutina de interrupción correspondiente.

El restablecimiento de los indicadores IEx se realiza en el hardware cuando se da servicio a la interrupción solo si la interrupción se ha configurado para detectar la caída de la señal INTx. Si la interrupción se ha configurado para detectar el nivel de la señal de solicitud, el programa de servicio de interrupción debe restablecer el indicador IEx, actuando sobre la fuente de interrupción para eliminar la solicitud.

Los indicadores TI y RI solo se pueden restablecer mediante software.

Cada tipo de interrupción se habilita o deshabilita individualmente configurando o borrando los bits correspondientes del registro de habilitación de interrupciones de IE. Este registro también contiene un bit de desactivación general para todas las interrupciones. El formato del registro IE se proporciona en la tabla. 14.5.

Tabla 14.5. Asignación de bits de registro IE

Posición de registro

mnemónicos de bits

Función

Deshabilitar las interrupciones de todas las fuentes.

No utilizado

No utilizado

Deshabilitar la interrupción de Puerto serial

Deshabilitar la interrupción del temporizador/contador T/C1

Deshabilitar la interrupción de fuente externa INT1

Deshabilitar temporizador/contador de interrupción T/C0

Deshabilitar interrupción de fuente externa INT0

A cada tipo de interrupción se le puede asignar mediante programación una de dos prioridades posibles: 0 - la más baja o 1 - la más alta.

Las prioridades se configuran estableciendo o borrando el bit correspondiente en el registro de prioridad de interrupción IP. El formato de este registro se da en la tabla. 14.6.

Cuando se reciben simultáneamente solicitudes de interrupción de fuentes que tienen diferentes prioridades, la solicitud de la fuente de mayor prioridad se procesa primero.

En el caso de la recepción simultánea de varias solicitudes de interrupción con la misma prioridad, el orden de su procesamiento lo determina el hardware del microcontrolador y no puede modificarse mediante el software. Este orden corresponde a la secuencia de indicadores de solicitud de interrupción de sondeo, que se ve así:

IT0 -> TF0 -> IT1 -> TF1 -> (RI, TI)

Tabla 14.6. Asignaciones de bits de registro IP

Posición de registro Bit mnemotécnico Función

7 - No utilizado

6 - No utilizado

5 - No utilizado

Prioridad de interrupción del puerto serie de 4 PS

3 PT1 Temporizador/Contador Prioridad de interrupción T/C1

2 PX1 Prioridad de interrupción desde fuente externa INT1

1 PT0 Temporizador/Contador Prioridad de interrupción T/C0

0 PX0 Prioridad de interrupción desde fuente externa INT0

Una llamada a un controlador de interrupciones implementado por hardware consta de las siguientes acciones:

* guardar el valor del contador del programa en la pila;

Los puntos de entrada del controlador de interrupciones para cada fuente de interrupción están fijos en el hardware. Sus valores se dan en la tabla. 14.7.

Tabla 14.7. Direcciones de puntos de entrada para controladores de interrupciones

fuente de interrupción

Direcciones de puntos de entrada para controladores de interrupciones

interrupción externa ( ITO)

Contador temporizador (TFO)

Interrupción externa (IT1)

Contador temporizador (TF1)

Puerto serie (R1 o T1)

El primer comando del controlador de interrupciones debe ubicarse en la dirección especificada. Como regla general, dicho comando es un comando para saltar incondicionalmente al lugar del programa donde se encuentra realmente el controlador.

Al cambiar a la rutina de manejo de interrupciones, automáticamente, independientemente del estado del registro IE, todas las interrupciones que tienen un nivel de prioridad igual al nivel de prioridad de la interrupción atendida se deshabilitan, es decir, las interrupciones anidadas con el mismo nivel de prioridad se deshabilitan. . Por lo tanto, una interrupción de baja prioridad (que tiene un "0" en el bit correspondiente del registro IP) puede ser interrumpida por una interrupción de alta prioridad (que tiene un "1" en el bit correspondiente del registro IP), pero no una uno de baja prioridad. Otra fuente no puede interrumpir el servicio de una interrupción de alta prioridad.

El regreso del controlador de interrupciones se logra usando la instrucción RETI, que restaura desde la pila el valor del contador del programa de PC almacenado allí en el momento en que se llamó al controlador de interrupciones, y la lógica de prioridad de interrupción.


Hablemos de interrupciones. La palabra interrupción habla por sí sola; un proceso se detiene durante un tiempo para realizar acciones adicionales. Las interrupciones pueden ser externas o internas. Déjame darte un ejemplo sencillo que escuché de mi amigo...

Se dispuso a lavar los platos en la cocina, comenzó emocionado, arremangándose... pero los platos resultaron estar grasosos y se vio obligado a detenerse para encontrar un detergente para lavar platos grasosos en uno de los estantes de la cocina. , tras lo cual continuó nuevamente con su tarea. Pero en algún momento sonó el teléfono y volvió a hacer una pausa en su trabajo, cogió el teléfono, llamó su suegra y le dijo que vendría de visita, por lo que tenía que ir a la tienda a comprar comida antes de que ella llegó. Fui a la tienda y solo entonces lavé los platos.

Este ejemplo muestra dos tipos de interrupciones, la primera está asociada con la ejecución del trabajo principal - buscar detergente para platos grasosos - una interrupción interna, la segunda - llamada telefónica– interrupción externa.
En un microcontrolador, las interrupciones externas surgen debido a señales provenientes de otras fuentes, las interrupciones internas surgen debido a dispositivos integrados en el propio microcontrolador. ¿Por qué las interrupciones son tan atractivas?
La primera es que podemos detener el proceso principal para realizar alguna otra función y luego continuar con este proceso.
El segundo, y probablemente en muchos casos el principal, se considera la aceleración del proceso de realización de todas las funciones, debido a factores internos. dispositivos adicionales. Volvamos a nuestro ejemplo. Digamos que mi amigo empezó a lavar los platos cuando su esposa ya había llegado a casa. Al ver los platos grasientos, le pide que busque líquido para lavar platos, y mientras él lava, ella ya le traerá este líquido. Pero entonces sonó el teléfono, mi esposa cogió el teléfono, habló con su madre y fue a la tienda. ¡Juntos, todo se hizo muy rápido!
Y es aún más fácil quedarse estancado, es decir, No hay ningún programa principal.
Mi amigo se sienta en el sofá y no hace nada, el ama de llaves ve los platos sucios, se lo cuenta y, habiendo recibido permiso, comienza a lavarse. Cuando suena el teléfono, le dice a su esposa que levante el teléfono, la esposa está hablando por teléfono y la conversación va al supermercado... ¡Belleza! En este caso, varios dispositivos de E/S funcionan simultáneamente en el microcontrolador (en los microcontroladores modernos puede haber muchos) y el rendimiento general del procesador aumenta muchas veces, pero las interrupciones de los dispositivos se procesan secuencialmente una tras otra (no simultáneamente). ), dependiendo de la prioridad (en nuestro ejemplo, la esposa tiene mayor prioridad que el ama de llaves).

Varios registros son responsables de gestionar las interrupciones.
SREG – registro de estado(estados). Nos fijamos en la tabla de dispositivos de entrada/salida. El séptimo bit del registro SREG es el indicador I (interrupción), que se denomina indicador de habilitación de interrupción global. Si se omite el indicador (el séptimo bit es cero), todas las interrupciones están deshabilitadas. Si se levanta la bandera (establezca I en 1), habilitamos las interrupciones.

La bandera I se configura y restablece con los comandos:
SEI - habilitar interrupciones
CLI: deshabilitar interrupciones
Las interrupciones que funcionarán se establecen mediante registros llamados: interrumpir mascarillas.
Las máscaras de interrupción se designan de la siguiente manera:
TIMSK,..,...,.. – gestión de interrupciones de temporizadores y otros dispositivos integrados.
GIMSK (GIKR en la familia Mega): gestión de todas las interrupciones externas.
Las máscaras de interrupción a su vez dependen de indicadores de interrupción:
TIFR y GIFR respectivamente(no debe confundirse con el indicador de habilitación de interrupción global).

Secuencia de ejecución de interrupción:
Cuando se enciende el microcontrolador, todos los indicadores de interrupción se restablecen a 0. Para habilitar las interrupciones, el programa debe establecer el indicador I del registro SREG en 1. Después de esto, registre los registros de máscara con las interrupciones locales configuradas (las interrupciones que necesitamos) .
Cuando llega una solicitud de interrupción (señal), activa la bandera de interrupción (incluso si la interrupción está deshabilitada, para organizar las interrupciones anidadas y la prioridad entre diferentes interrupciones). Si las interrupciones no están deshabilitadas, el controlador se comunicará con el (Vectores de interrupción) - vector de interrupción, pausando el programa actual.
vector de interrupción Es una línea fija en el área del programa a donde va el programa cuando ocurre una interrupción.
La lista completa de vectores de interrupción se llama tabla de vectores de interrupción, El cual está localizado al comienzo del código del programa.
Entonces, en el momento en que se accede al vector de interrupción, el indicador I del registro SREG y el indicador que causó la interrupción se restablecen a 0, deshabilitando otras interrupciones. Si se producen otras solicitudes de interrupción mientras se ejecuta la interrupción, las banderas de esas interrupciones permanecen activas. Al finalizar la interrupción actual, se levanta el indicador I del registro SREG, lo que permite que se ejecute la siguiente. Si llegan varias solicitudes y se activan sus banderas, entonces se ejecutará primero la interrupción cuyo vector sea más pequeño en la dirección de la tabla, más cercana al comienzo de la memoria. Sigue el segundo y así sucesivamente. Además, el programador puede organizar la llamada interrupción anidada, cuando se produce otra interrupción durante la ejecución del programa de interrupción. Luego se detiene la ejecución de la interrupción actual y se ejecuta una nueva, después de lo cual se reanuda la ejecución de la interrupción detenida.

Como ejemplo, se proporciona la tabla de vectores de interrupción para ATtiny2313.

La tabla de vectores de interrupción para Atmega16 es la siguiente:

Al compararlas, las tablas no coinciden en absoluto.
En la familia ATtiny, la línea del vector de interrupción ocupa 16 bits, y en la familia Mega, 32 bits (preste atención a las direcciones de los vectores de interrupción; permítame recordarle que la línea de dirección en el área del programa está representada por un 16 -palabra de bits).

El código del programa para ATtiny2313 puede verse así:
.cseg .org 0 rjmp Restablecer rjmp INT_0 rjmp INT_1 rjmp Timer1_capt1 rjmp Timer1_comp1 rjmp Timer1_OVF1 rjmp Timer0_OVF0 rjmp UART_RX rjmp UART_UDRE rjmp UART_TX rjmp ANA_COMP rjmp PCINT rjmp Timer1_ compB rjmp Timer0_compA rj mp Timer0_compB rjmp USI_START rjmp USI_OVERFLOW rjmp EE_READY rjmp WDT_ OVERFLOW

Como puede ver, el vector de interrupción crea un salto relativo a las etiquetas del programa de interrupción. La siguiente tabla muestra las opciones; 1. Cuando no existan interrupciones; 2, 3. con interrupción externa en la entrada INT_1.
Si las etiquetas están "vacías" (no hay ningún programa debajo de la etiqueta), entonces no sucede nada y el programa "recorre" secuencialmente las etiquetas restantes y llega al comando de manera segura. RETI- Retorno de interrupción - salir del controlador de interrupciones como se muestra en la primera columna de la tabla.

Para ejecutar un programa de interrupción, por ejemplo, en la entrada INT_1, debe eliminar la etiqueta INT_1: de la lista. Esto se muestra esquemáticamente en la segunda columna de la tabla.
Pero es inconveniente para el programador escribir todas las interrupciones y etiquetas separadas para ellas cada vez, especialmente en los últimos modelos, donde la tabla es bastante grande; es más fácil escribir inmediatamente el comando RETI en la línea del vector de interrupción si La interrupción no se utiliza. Entonces el programa tendrá el aspecto que se muestra en la tercera columna de la tabla.

Los controladores AVR, según el modelo, pueden tener de 1 a 8 entradas interrupciones externas.
Consideremos el sistema de gestión de interrupciones externo. Para ello se proporcionan las siguientes combinaciones de registros de E/S según modelo (ver el DataSheet correspondiente):
- GIMSK, EIFR, PCMSK, MCUCR;
- GIKR, GIFR, MCUCR;
- EIMSK, EICR, EIFR;
GIMSK, GIKR, EIMSK - máscaras de interrupción,
EIFR, PCMSK, GIFR, EIFR – indicadores de interrupción
Por permiso o prohibición interrupciones externas Los registros de control están destinados a: GIMSK-(Registro de máscara de interrupción general) (Tiny), GICR- (Registro de control de interrupción general) (Mega), MCUCR – (Registro de control de MCU)




EIFR- Registro de indicador de interrupción externa: 1 - habilitado, 0 - deshabilitado. Cada bit (bandera) permite que el pin correspondiente actúe como fuente de interrupción.

Bits de control del registro GIMSK:
Bit 7 – INT1: Solicitud de interrupción externa 1 habilitada: bit de habilitación de interrupción INT1: 1: habilitado, 0: deshabilitado. La interrupción se generará incluso si el pin INT1 está configurado como salida. El bit INT1 está configurado para interrumpir en el registro de bandera EIFR. El pin INT1 está sincronizado con el generador de reloj.

Bit 6 – INT0: Solicitud de interrupción externa 0 Habilitar: bit de habilitación de interrupción INT0: 1 – habilitado, 0 – deshabilitado. La interrupción se generará incluso si el pin INT0 está configurado como salida. El bit INT0 está configurado para interrumpir en el registro de bandera EIFR. El pin INT10 está sincronizado con el generador de reloj.

Bit 5: PCIE: Habilitación de interrupción de cambio de pin: bit de habilitación de interrupción en los pines PCINT0…7: 1 – habilitado, 0 – deshabilitado. Cualquier cambio en cualquiera de los pines PCINT0...7 generará una interrupción. Los pines PCINT0...7 están configurados para interrupción individualmente, mediante bits en el registro de bandera PCMSK.

PCMSK- Registrador de máscara de cambio de PIN - registro de bandera PCMSK: 1 - permitido, 0 - deshabilitado. Cada bit (bandera) permite que el pin correspondiente actúe como fuente de interrupción. Los pines PCINT0...7 no están sincronizados con el generador de reloj, es decir. Se produce una interrupción cuando se produce un cambio en cualquiera de los pines.

mega8

y el registro de bandera correspondiente


Bit 7

Bit 6 – INT0: Solicitud de interrupción externa 0 Habilitar: bit de habilitación de interrupción INT0: 1 – habilitado, 0 – deshabilitado. La interrupción se generará incluso si el pin INT0 está configurado como salida. El bit INT0 está configurado para interrumpir en el registro de banderas GIFR



GIFR – Registro de bandera de interrupción general: 1 – habilitado, 0 – deshabilitado. Cada bit (bandera) permite que el pin correspondiente actúe como fuente de interrupción.

Bits de control del registro GICR:
Bit 7– : Solicitud de interrupción externa 1 habilitada – bit de habilitación de interrupción INT1: 1 – permitido, 0 – prohibido. La interrupción se generará incluso si el pin INT1 está configurado como salida. El bit INT1 está configurado para interrumpir en el registro de banderas GIFR

Bit 6 – INT0: Solicitud de interrupción externa 0 Habilitar - bit de habilitación de interrupción INT0: 1 – permitido, 0 – prohibido. La interrupción se generará incluso si el pin INT0 está configurado como salida. El bit INT0 está configurado para interrumpir en el registro de banderas GIFR

Bit 5 – INT2: Solicitud de interrupción externa 2 habilitada - bit de habilitación de interrupción INT2: 1 – permitido, 0 – prohibido. La interrupción se generará incluso si el pin INT2 está configurado como salida. El bit INT2 está configurado para interrumpir en el registro de banderas GIFR

Las funciones de las entradas INT0 e INT1 en todos los controladores están controladas por los bits de orden inferior del registro MCUCR.

MCUCR – Registro de control de MCU
Bits de control:
Bits 1, 0 – ISC01, ISC00 (Control de detección de interrupción 0 Bit 1 y Bit 0): el estado de estos bits determina el evento en el pin INT0, que genera una interrupción INT0:
ISC01=0, ISC00=0 – nivel cero lógico;
ISC01=0, ISC00=1 – cualquier cambio de estado lógico;
ISC01=1, ISC00=0 – en un flanco descendente;
ISC01=1, ISC00=1 – en un flanco ascendente.

Bits 3, 2 – ISC11, ISC10 (Control de detección de interrupción 1 Bit 1 y Bit 0): el estado de estos bits determina el nivel de señal en el pin INT1, que genera la interrupción INT1:
ISC11=0, ISC10=0 – nivel cero lógico;
ISC11=0, ISC10=1 – cualquier cambio de estado lógico;
ISC11=1, ISC10=0 – en un flanco descendente;
ISC11=1, ISC10=1 – en un flanco ascendente.

Bueno, parece que hemos hablado mínimo de interrupciones externas.
Está claro que para que las interrupciones funcionen, es necesario registrarlas en consecuencia.
Agreguemos la inicialización de la interrupción en INT1 iniciada por tiny en el flanco ascendente de la señal:

Ldir16.0x80; escribe en r16 el número 0b10000000 ldi r17.0x0C; escriba en r17 el número 0b00001100 fuera MCUCR,r17; la interrupción se generará en el flanco ascendente ISC11=1, ISC10=1 fuera de GIMSK,r16; establecer la máscara INT0 sei
Por cierto, puedes generar una interrupción en tiny2313. en cualquier pin PCINT0…7, en Mega hasta la serie 48 estas características no están disponibles...
Hay operaciones durante las cuales pueden ocurrir interrupciones que pueden causar que el programa falle. En tales casos, antes de iniciar la operación escribimos CLI y después SEI. Estas operaciones se denominan: atómico.
Es deseable que los programas de interrupción sean compactos y se ejecuten a la máxima velocidad, porque el propósito de cualquier interrupción es capturar un evento. Si según varias razones el programa corre lento, basta con registrar el evento y procesarlo un poco más tarde.

Para no saturar el material presentado con información innecesaria, recomiendo a los lectores que utilicen hojas de datos y, si no todo está claro, hagan preguntas con más frecuencia en los foros.
A continuación, consideraremos en detalle las interrupciones internas basadas en temporizadores integrados. lectores. Para participar en la votación, regístrese e inicie sesión en el sitio con su nombre de usuario y contraseña.

Una de las ventajas del microcontrolador ATmega8 es su amplia gama de interrupciones diferentes.

Interrumpir es un evento al ocurrir el cual se suspende la ejecución del programa principal y se llama a una función que maneja una interrupción de cierto tipo.

Las interrupciones se dividen en internas y externas. Las fuentes de interrupciones internas incluyen módulos de microcontroladores integrados (temporizadores, transceptor USART, etc.). Las interrupciones externas ocurren cuando llegan señales externas a los pines del microcontrolador (por ejemplo, señales en los pines RESET e INT). La naturaleza de las señales que conducen a la aparición de una interrupción se establece en el registro de control. MCUCR, en particular en los bits - ISC00 (bit 0) e ISC01 (bit 1) para la entrada INT 0; ISC10 (bit2) e ISC11 (bit3) para entrada INT1.

En el microcontrolador ATmega8, cada interrupción tiene su propia vector de interrupción(dirección al comienzo del área de memoria del programa en la que se almacena el comando para saltar a la rutina de interrupción especificada). En mega8, todas las interrupciones tienen la misma prioridad. Si se producen varias interrupciones simultáneamente, la interrupción con el número de vector más bajo se procesará primero.

Vectores de interrupción en Atmega8

DIRECCIÓN fuente de interrupción Descripción
0x0000 REINICIAR Restablecer señal
0x0001 INT0 Solicitud de interrupción externa en la entrada INT0
0x0002 INT1 Solicitud de interrupción externa en la entrada INT1
0x0003 T/C1 Captura del temporizador T/C1
0x0004 T/C1 Coincidir T/C1 Temporizador Comparar Registro A
0x0005 T/C1 Coincide con el registro de comparación B del temporizador T/C1
0x0006 T/C1 Desbordamiento del contador T/C1
0x0007 T/C0 Desbordamiento del contador T/C0
0x0008 SPI Transferencia de datos SPI completada
0x0009 UART El transceptor UART ha completado la recepción de datos.
0x000A UART El registro de datos UART está vacío
0x000B UART Se completa la transmisión de datos mediante el transceptor UART
0x000C ANA_COMP Interrupción del comparador analógico

Gestión de interrupciones

4 registros son responsables de gestionar las interrupciones en ATmega8:

GIMSK(también conocido como GICR): prohibe/habilita interrupciones basadas en señales en las entradas INT0, INT1

GIFR- gestión de todas las interrupciones externas

TIMSK, TIFR- gestión de interrupciones de temporizadores/contadores

Registro GIMSK(GICR)

INTFx=1: ocurrió una interrupción en la entrada INTx. Al ingresar a la rutina de manejo de interrupciones, INTFx se restablece automáticamente al estado de registro. 0

Registro TIMSK

7 6 5 4 3 2 1 0
TOIE1
OCIE1A
OCIE1B
-
TICIE
-
TOIE0
-

TOIE1=1: Interrupción de desbordamiento T/C1 habilitada

OCIE1A=1: interrupción cuando el registro de comparación A coincide con el contenido del contador T/C1 habilitado

OCIE1B=1: interrupción cuando el registro de comparación B coincide con el contenido del contador T/C1 habilitado

TICIE=1: interrupción habilitada cuando se cumple la condición de captura

TOIE0=1: Interrupción por desbordamiento T/C0 habilitada

Registro TIFR

7 6 5 4 3 2 1 0
TOV1
OCF1A
OCF1B
-
ICF1
-
TOV0
-

TOV1=1: Se produjo un desbordamiento de T/C1

OCF1A=1: el registro de comparación A coincidió con el contenido del contador T/C1 permitido

OCF1B=1: el registro de comparación B coincide con el contenido del contador T/C1 permitido

FCI=1: condiciones de captura cumplidas

TOV0=1: Se produjo un desbordamiento de T/C0

Al ingresar a la subrutina de manejo de interrupciones, el indicador de registro TIFR correspondiente a la interrupción se restablece automáticamente al estado de registro. 0

Las interrupciones solo funcionan cuando las interrupciones generales están habilitadas en el registro de estado SREG (bit 7 = 1). Cuando ocurre una interrupción, este bit se restablece automáticamente a 0, deshabilitando las interrupciones posteriores.

En este ejemplo, el pin INT0 está habilitado en el modo de entrada pull-up. Cuando el pin se pone en cortocircuito a tierra usando un botón, se establece un 0 lógico (el borde de la señal cae del voltaje de suministro a 0) y se activa el controlador de interrupciones, encendiendo la bombilla conectada al pin cero del puerto. B

lámpara vacía ON()
{
PUERTO.0=1;
DDRB.0=1;
}

interrumpir vacío text_int0_isr (vacío)
{
lámpara encendida();
}

DDRD.2=0;
PUERTO.2=1;

SREG|= (1 mientras(1) (

El ejemplo anterior también muestra cómo se configuran los vectores de interrupción en Code Vision AVR (interrupt void ext_int0_isr(void)). Los vectores de interrupción se establecen de manera similar para otros casos:

EXT_INT0 2
EXT_INT1 3
TIM2_COMP 4
TIM2_OVF 5
TIM1_CAPT 6
TIM1_COMPA 7
TIM1_COMPB 8
TIM1_OVF 9
TIM0_OVF 10
SPI_STC 11
USART_RXC 12
USART_DRE 13
USART_TXC 14
ADC_INT 15
EE_RDY 16
ANA_COMP 17
TWI 18
SPM_LISTO 19

Parte microcontroladores AVR incluye una gran cantidad de dispositivos periféricos (ADC, temporizadores/contadores, EXTI, comparador analógico, EEPROM, USART, SPI, I2C, etc.), cada uno de los cuales puede realizar ciertas acciones sobre datos/señales y otra información. Estos dispositivos se integran en el microcontrolador para mejorar la eficiencia de las aplicaciones y reducir costes a la hora de desarrollar todo tipo de dispositivos basados ​​en microcontroladores AVR.

El procesador comunica/controla dispositivos periféricos a través de registros de E/S, que se encuentran en la memoria de datos, lo que permite utilizarlos como variables regulares. Cada dispositivo tiene sus propios registros de E/S.

Todos los registros de E/S se pueden dividir en tres grupos: registros de datos, registros de control y registros de estado.

Mediante registros de control se configura el dispositivo para funcionar en un modo u otro, con una determinada frecuencia, precisión, etc., y mediante Registros de Datos se lee el resultado del trabajo. de este dispositivo(conversión de analógico a digital, datos recibidos, valor del temporizador/contador, etc.). Parecería que aquí no hay nada complicado (de hecho, aquí realmente no hay nada complicado :)), encendimos el dispositivo, indicamos el modo de funcionamiento deseado y luego solo queda recortar cupones, leer los datos ya preparados. y utilizarlos en los cálculos. Toda la cuestión es "cuándo" leer estos datos (el dispositivo ha completado su trabajo o todavía está procesando datos), porque todos los dispositivos periféricos funcionan en paralelo con el núcleo del microcontrolador, e incluso en diferentes frecuencias. y sincronización entre el procesador y dispositivo periférico.

Como probablemente ya habrás adivinado, para implementar la comunicación y sincronización entre el dispositivo y el procesador, se utilizan "Registros de estado", que almacenan el estado operativo actual de un dispositivo en particular. Cada estado en el que puede estar el dispositivo corresponde a un "bit en el estado del registro” (bandera), cuyo valor actual “habla” sobre el estado actual de este dispositivo o su función individual (trabajo completado/no completado, error durante el procesamiento de datos, registro vacío, etc.).

El mecanismo de comunicación entre el procesador y un dispositivo periférico se implementa mediante el sondeo de banderas, que son responsables de una función particular de este dispositivo. Dependiendo del valor de un indicador particular (estado del dispositivo), puede cambiar el flujo de ejecución del programa (ramificación). P.ej:

Comprobando si una determinada bandera está configurada (ha ocurrido algún evento):

si (RegX y (1<< Flag) ) // si la bandera en el registro RegX está configurada
{
// hacer algo
}

Esperando la finalización de alguna acción (evento):

mientras(!(RegX & (1<

Consultar indicadores es una tarea que consume muchos recursos, tanto en términos de tamaño como de velocidad del programa. Dado que el número total de indicadores en los microcontroladores AVR es bastante grande (una ventaja), la implementación de la comunicación entre el procesador y el dispositivo mediante indicadores de sondeo conduce a una disminución en la eficiencia (velocidad del código / tamaño del código) del programa que escribe. Además, el programa se vuelve muy confuso, lo que contribuye a la aparición de errores que son difíciles de detectar incluso con una depuración detallada del código.

Para aumentar la eficiencia de los programas para microcontroladores AVR, así como para facilitar el proceso de creación y depuración de estos programas, los desarrolladores han equipado todos los dispositivos periféricos con "fuentes de interrupción" ( Fuentes de interrupción), algunos dispositivos pueden tener múltiples fuentes de interrupción.

Utilizando fuentes de interrupción, se implementa. mecanismo de sincronización, entre el procesador y el dispositivo periférico, es decir, el procesador comenzará a recibir datos, indicadores de sondeo y otras acciones en el dispositivo periférico solo cuando el dispositivo esté listo para esto (informará la finalización del procesamiento de datos, un error durante procesamiento de datos, el registro está vacío, etc.) etc.), generando una “solicitud de interrupción” ( solicitud de interrupción), dependiendo del valor de algún indicador (dispositivo/función/estado de evento).

En la literatura, muy a menudo, toda la cadena de eventos, desde la "solicitud de interrupción" (IRQ) hasta el "procedimiento de servicio de interrupción" (ISR), se abrevia como interrupción ( Interrumpir).

¿Qué es una interrupción?


Una interrupción es una señal que notifica al procesador sobre la ocurrencia de un evento. En este caso, la ejecución de la secuencia actual de comandos se suspende y el control se transfiere al procedimiento de manejo de interrupciones correspondiente a este evento, después de lo cual la ejecución del código continúa exactamente desde el punto donde fue interrumpido (devolución del control). (wiki)

interrumpir la rutina(Rutina de servicio de interrupción) no es más que una función/subrutina que debe ejecutarse cuando ocurre un determinado evento. Usaremos la palabra "procedimiento" para enfatizar su diferencia con todas las demás funciones.

La principal diferencia entre el procedimiento y las funciones simples es que en lugar del habitual "regreso de la función" (comando de ensamblador RET), debe usar "retorno de la interrupción" (comando de ensamblador RETI) - " Regresar de la interrupción".

Propiedades de interrupción AVR:

  • Cada dispositivo periférico que forma parte de los microcontroladores AVR tiene al menos una fuente de interrupción. Entre todas estas interrupciones cabe incluir también la interrupción de reset, cuya finalidad es diferente a todas las demás.
  • Cada interrupción tiene un vector (enlace) estrictamente asignado que apunta a la rutina del servicio de interrupción. Todos los vectores de interrupción se encuentran al principio de la memoria del programa y juntos forman la "tabla de vectores de interrupción".
  • Cada interrupción está asociada con un "bit de habilitación de interrupción" específico. Por lo tanto, para utilizar una interrupción específica, debe escribir en su "bit de habilitación de interrupción" - registro. unidad. Además, independientemente de si ha habilitado ciertas interrupciones o no, el microcontrolador no comenzará a procesar estas interrupciones hasta que se escriba una lógica en el "bit de habilitación de interrupción global" en el registro de estado SREG. Además, para deshabilitar todas las interrupciones (por un tiempo indefinido), se debe escribir un cero lógico en el bit de habilitación de interrupción general.

La interrupción de reinicio, a diferencia de todas las demás, no se puede desactivar. Estas interrupciones también se denominan interrupciones no enmascarables.

  • Cada interrupción tiene una prioridad estrictamente definida. La prioridad de una interrupción depende de su ubicación en la "tabla de vectores de interrupción". Cuanto menor sea el número de vector en la tabla, mayor será la prioridad de la interrupción. Es decir, la prioridad más alta es la interrupción de reinicio, que se encuentra primero en la tabla, y en consecuencia en los programas de memoria. La interrupción externa INT0, después de la interrupción de Reset en la "tabla de vectores de interrupción", tiene una prioridad menor que la de Reset, pero mayor que la de todas las demás interrupciones, etc.

La tabla de vectores de interrupción, excepto el vector de reinicio, se puede mover al comienzo de la sección de inicio de la memoria Flash configurando el bit IVSEL en el registro GICR. El vector de reinicio también se puede mover al comienzo de la sección de inicio de la memoria Flash programando el bit fusible - BOOTRST.



Fig.1 Tabla de vectores de interrupción ATmega16

Prototipo de rutina de interrupción


Para declarar una función como una rutina de manejo de interrupciones, debe seguir ciertas reglas de creación de prototipos para que el compilador/enlazador pueda identificar y asociar correctamente la interrupción que necesita con su rutina de manejo.

En primer lugar, la rutina del servicio de interrupción no puede aceptar nada como argumento (nulo) y tampoco puede devolver nada (nulo). Esto se debe al hecho de que todas las interrupciones en AVR son asíncronas, por lo que no se sabe dónde se interrumpirá la ejecución del programa, de quién recibir y a quién devolver el valor, y también para minimizar el tiempo de entrada y salir de la interrupción.

vacío isr(vacío)

En segundo lugar, antes del prototipo de la función, debes indicar que se trata de un procedimiento de manejo de interrupciones. Como sabes, en el lenguaje C sólo se ejecuta el código utilizado en la función principal. Dado que el procedimiento de manejo de interrupciones en la función principal no se usa en ninguna parte, para que el compilador no lo "descarte" por considerarlo innecesario, antes del prototipo del procedimiento se debe indicar que esta función es un procedimiento de manejo de interrupciones.

Prototipo de procedimiento de manejo de interrupciones en ambiente AVR Studio

#incluir

ISR (XXX_vector)
{

}

En AVR Studio (AVR GCC), cada rutina de interrupción comienza con una definición de macro ISR, seguida de la siguiente construcción entre paréntesis:

XXX_vector

donde "XXX" es el nombre del vector de interrupción. Todos los nombres de vectores para un microcontrolador AVR específico se pueden encontrar en la "tabla de vectores de interrupción" de la hoja de datos del microcontrolador o en su archivo de encabezado. Por ejemplo, la "tabla de vectores de interrupción" para el microcontrolador ATmega16 se muestra en la Fig. 1, donde en la columna Fuente se enumeran todos los nombres de los vectores de interrupción. Los nombres también se pueden encontrar en el archivo de encabezado de este microcontrolador (C :\Program Files\Atmel\AVR Tools\AVR Toolchain\avr\include\avr\iom16.h), consulte la Fig. 2. Todo lo que necesitamos hacer es encontrar el nombre del vector que necesitamos en la tabla y agregar el sufijo "_vect" a él.


Fig.2 Archivo de encabezado ATmega16 para AVR Studio

Por ejemplo, escribamos un procedimiento de manejo de interrupciones para recibir un byte a través de USART (USART, Rx Complete):

ISR (USART_RXC_vect)
{
// cuerpo del controlador de interrupciones
}

Por cierto: antes de usar cualquier interrupción en AVR Studio, debes incluir los archivos de encabezado io.h e interrupt.h en el proyecto:

#incluir
#incluir

Puede leer más sobre los manejadores de interrupciones en AVR Studio (AVR GCC) en la sección Introducción al manejo de interrupciones de avr-libc.

Prototipo de procedimiento de manejo de interrupciones en el entorno ImageCraft.

#pragma interrupción_handler : iv_XXX
vacío< handler_name>(vacío)
{
// cuerpo del controlador de interrupciones
}

En el entorno ImageCraft, la rutina de interrupción del prototipo tiene este aspecto:

vacío< handler_name>(vacío)

Dónde , este es el nombre que quieras darle a este controlador de interrupciones. Uno de los requisitos para declarar procedimientos de manejo de interrupciones es que antes del prototipo de función se debe indicar que es un manejador de interrupciones. Esto se hace usando una directiva pragma. controlador_interrupción :

#pragma interrupción_handler : iv_XXX

Dónde este es el nombre de la función que se utilizará como controlador de interrupciones, y la construcción "iv_XXX" es el nombre del vector de interrupción (XXX) con el prefijo "iv_". Como en el caso de AVR Studio, todos los nombres de vectores para un microcontrolador AVR específico se puede encontrar en la "tabla de vectores de interrupción" de la hoja de datos de un microcontrolador determinado o en su archivo de encabezado (ver Fig. 3).


Fig.3 Archivo de encabezado ATmega16 para ImageCraft IDE

Por ejemplo, el procedimiento para manejar una interrupción al recibir un byte a través de USART (USART, Rx Complete) en el entorno ImageCraft se verá así:

#pragma interrupt_handler usart_rxc_isr: iv_USART_RXC
vacío usart_rxc_isr(vacío)
{
// cuerpo del controlador de interrupciones
}

Puede encontrar más información sobre los procedimientos de manejo de interrupciones en ImageCraft IDE en el menú Ayuda->Programación del AVR->Controladores de interrupciones del entorno de desarrollo.

A veces, si varios manejadores de interrupciones necesitan hacer lo mismo, para ahorrar memoria del programa, puede dirigir varios vectores de interrupción a la misma rutina de interrupción.

En AVR Studio se ve así:

ISR (INT0_vector)
{
// Hacer algo
}
ISR(INT1_vect, ISR_ALIASOF(INT0_vect));

Primero viene el procedimiento de procesamiento de interrupciones para un vector específico, en este caso INT0. Todos los demás procedimientos pueden hacer referencia a cualquier controlador de interrupciones utilizando la construcción:

ISR (YYY_vect, ISR_ALIASOF(XXX_vect));

donde YYY es el nombre del vector de interrupción que hace referencia al controlador de interrupciones previamente declarado para el vector XXX.

En ImageCraft se ve así:

#pragma interrupción_handler : iv_XXX : iv_AAAA
vacío< handler_name>(vacío)
{
// cuerpo del controlador de interrupciones
}

#pragma interrupción_handler : iv_XXX
#pragma interrupción_handler : iv_AAAA
vacío< handler_name>(vacío)
{
// cuerpo del controlador de interrupciones
}

donde los vectores XXX e YYY se refieren al mismo controlador de interrupciones .

¿Cómo funciona la interrupción en los microcontroladores AVR?

1. Supongamos que " solicitud de interrupción”(IRQ).

Por cierto: si se producen varias solicitudes de procesamiento de interrupciones simultáneamente, la interrupción con la mayor prioridad se procesará primero, todas las demás solicitudes se procesarán después de que se complete la interrupción de alta prioridad.

2. Examen.

Si el bit de habilitación para esta interrupción está configurado (bit de habilitación de interrupción) y el bit I (bit de habilitación de interrupción general) del registro de estado del procesador (SREG), entonces el procesador comienza a preparar la rutina del servicio de interrupción, mientras que el bit de habilitación de interrupción está configurado. El bit de habilitación de interrupción (bit I del registro SREG) se restablece, deshabilitando así todas las demás interrupciones. Esto ocurre para que ningún otro evento pueda interrumpir el procesamiento de la interrupción actual.

Por cierto: si en el procedimiento de manejo de interrupciones configura el I-bit en el estado de registro. unidades, entonces cualquier interrupción activada puede a su vez interrumpir el procesamiento de la interrupción actual. Estas interrupciones se denominan interrupciones anidadas.

3. Preparación.

El procesador completa la ejecución de la instrucción ensambladora actual y luego coloca la dirección de la siguiente instrucción en la pila (PC->STACK). A continuación, el procesador verifica qué fuente de interrupción ha enviado una "solicitud de interrupción" (IRQ), después de lo cual, utilizando el vector de esta fuente (enlace) de la tabla de vectores (que está firmemente asignada a cada fuente de interrupción), procede a la procedimiento de procesamiento de interrupción (instrucción JMP). Eso es todo, el procesador gasta al menos 4 ciclos de reloj (dependiendo del momento en que aparece la solicitud y la duración de la ejecución de la instrucción actual). Este es un muy buen tiempo de respuesta a IRQ, en comparación con Microcontroladores de otros fabricantes.

Por cierto: si ocurre una IRQ mientras el microcontrolador está en modo de suspensión, el tiempo de respuesta a la IRQ aumenta en otros cuatro ciclos de reloj, más el tiempo almacenado en los bits del fusible SUT1 y SUT0 (tiempo de inicio).

Interrupción: un evento que requiere una respuesta inmediata del procesador. La respuesta es que el procesador interrumpe el procesamiento del programa actual ( programa interrumpido) y procede a ejecutar algún otro programa ( programa de interrupción), especialmente diseñado para este evento. Al finalizar este programa, el procesador vuelve a ejecutar el programa interrumpido.

Cada evento que requiere una interrupción va acompañado de señal de interrupción, notificando a la computadora sobre esto, y llamó solicitud de interrupción.

Estado del programa representa un conjunto de estados de todos los elementos de almacenamiento en el momento correspondiente (por ejemplo, después de que se ejecutó el último comando). Cuando ocurre una interrupción, el microcontrolador almacena el contenido del contador del programa en la pila y carga en él la dirección del vector de interrupción correspondiente. El último comando de la rutina del servicio de interrupción debe ser un comando que regrese al programa principal y restaure el contador del programa previamente almacenado. Mientras se ejecuta el controlador de interrupciones, cierta información puede cambiar. Por lo tanto, al pasar al controlador de interrupciones, es necesario guardar los elementos que se están cambiando. El conjunto de dichos elementos es vector de estado del programa. En este caso, otra información sobre el estado de las celdas de memoria no es significativa o puede restaurarse mediante programación.

Vector estado inicial contiene toda la información necesaria para el lanzamiento inicial del programa. En muchos casos, el vector de estado inicial contiene solo un elemento: la dirección inicial del programa que se está ejecutando.

vector de interrupción es el vector del estado inicial del programa de interrupción (controlador) y contiene toda la información necesaria para pasar al controlador, incluida su dirección inicial. Cada tipo de interrupción tiene su propio vector de interrupción, que inicia la ejecución del controlador correspondiente. Normalmente, los vectores de interrupción se almacenan en ubicaciones de memoria fijas especialmente asignadas con direcciones cortas, que representan tabla de vectores de interrupción. Para saltar al programa de interrupción apropiado, el procesador debe tener un vector de interrupción y la dirección de este vector. En esta dirección, por regla general, hay un comando de salto incondicional a la subrutina de manejo de interrupciones.

Como regla general, el control de almacenamiento y devolución se asigna al controlador de interrupciones. En este caso, el controlador consta de tres partes: preparatoria (prólogo) y final (epílogo), que garantizan el cambio de programa, y ​​el programa de interrupción real, que realiza las operaciones solicitadas por la solicitud. El tiempo de respuesta se define como el intervalo de tiempo desde el momento en que se recibe una solicitud de interrupción hasta que el programa interrumpido comienza a ejecutarse.


tp– tiempo de respuesta del sistema ante una interrupción;
t z– tiempo para almacenar el estado del programa interrumpido;
t ppr– hora del programa de interrupción real;
estaño– tiempo para restablecer el estado del programa interrumpido

Si hay varias fuentes de solicitudes, se debe establecer un cierto orden de atención de las solicitudes entrantes, llamado relaciones prioritarias o disciplina de servicio. El conjunto de todos los tipos posibles de interrupción del procesador es sistema de interrupción microcontrolador. La disciplina de servicio determina cuál de varias solicitudes recibidas simultáneamente debe procesarse primero y si Esta petición interrumpir uno u otro controlador de interrupciones.
Si se recibe una solicitud de interrupción de mayor prioridad mientras se procesa una interrupción, el control se transfiere al manejador de interrupciones de mayor prioridad y el manejador de interrupciones de menor prioridad se suspende. surge interrumpir el anidamiento. El número máximo de programas que pueden suspenderse entre sí se llama profundidad de las interrupciones.

Si la solicitud de interrupción no ha sido atendida cuando llega una nueva solicitud desde la misma fuente (misma prioridad), entonces interrumpir la saturación del sistema. En este caso se perderán parte de las solicitudes de interrupción, lo que por operación normal No se permite el microcontrolador.

Características del sistema de interrupción. son:

  • número total de solicitudes de interrupción número de fuentes de solicitudes de interrupción;
  • tipo de representación de interrupción: como regla general, una solicitud de interrupción se representa mediante un nivel de señal lógica;
  • prioridad de interrupción: determina el orden en que se procesa cada solicitud de interrupción; cuanto mayor sea la prioridad, menor será el retraso en la ejecución del programa de interrupción;
  • tiempo de respuesta – el intervalo de tiempo entre la aparición de la solicitud de interrupción y el inicio de la ejecución del programa de interrupción;
  • retraso de interrupción – determinado por el tiempo total para almacenar y restaurar el programa;
  • profundidad, generalmente coincide con el número de niveles de prioridad en el sistema de interrupción;
  • interrumpir la saturación del sistema;
  • momentos permitidos de interrupción del programa (generalmente el final de la ejecución del siguiente comando).

Enmascaramiento de interrupción Se utiliza para decirle al microcontrolador que responda a cada tipo de interrupción o que la ignore. La máscara de interrupción representa un código binario cuyos bits se asignan a las fuentes de la solicitud de interrupción. El bit en el código binario le dice al microcontrolador que maneje este tipo de interrupción. Un bit cero, por el contrario, no permite que el microcontrolador procese a procesar interrupciones del tipo especificado.
Como regla general, además de enmascarar las interrupciones, también hay un bit de habilitación de interrupción global, cuyo valor cero desactiva todos los manejadores de interrupciones (excepto el reinicio del hardware y el salto al comienzo del programa en ejecución).
Además del código binario de la máscara de interrupción, también hay un código binario banderas de interrupción, que permite al controlador de interrupciones establecer la fuente de la interrupción si hay varias fuentes con la solicitud especificada en el microcontrolador.




Arriba