Interrupción Externa AVR
La interrupción externa AVR se produce cuando en un pin preparado especialmente para este fin se produce algún evento, como que ocurra algún cambio de estado en ese pin como por ejemplo pasar de un bajo(0) a un alto(1); la interrupción externa AVR se comentará para el caso del ATmega88 pero si se quiere utilizar algún otro microcontrolador AVR, el procedimiento es muy similar, solo hay que guiarse de la hoja de datos del microcontrolador AVR utilizado.
La interrupción externa AVR es útil para el manejo de pulsadores, comunicación SPI, detectores de cruce por 0, teclados matriciales y mucho mas; hay 2 tipos de interrupciones externas en los microcontroladores AVR, en la imagen se tiene la representación de los pines del Atmega88, los pines resaltados que se nombran como INT0 e INT1, son pines que están preparados para producir una interrupción externa AVR por diversos eventos que se pueden elegir por programa. otros microcontroladores AVR tienen mas pines INTx.
Los pines nombrados como PCINT0, PCINT1 así hasta PCINT23, son pines que están preparados para producir una interrupción externa AVR cuando en estos pines se produce un cambio de estado, esto es si sus estados pasan de alto a bajo o de bajo a alto; la interrupción externa AVR se producirá no importando si el pin elegido es una entrada o salida digital.
INTERRUPCIÓN EXTERNA AVR INT0 E INT1
Los pines INT0 e INT1 trabajan de forma independiente pero realizan el mismo tipo de tarea, a través de estos pines se pueden realizar una interrupción externa AVR, siendo la causa o el evento que produzca la interrupción uno de los siguientes motivos:
- Un 0 o bajo en el pin INT0 o INT1.
- Por cambio de estado en el pin INT0 o INT1, esto es que pase de un bajo a un alto o de un alto a un bajo.
- Por flanco de bajada ocurrido en el pin INT0 o INT1, esto es que el estado del pin pase de un alto a un bajo.
- Por flanco de subida ocurrido en el pin INT0 o INT1, esto es que el estado del pin pase de un bajo a un alto.
Para elegir el tipo evento que producirá la interrupción externa AVR y el pin a utilizar, se utiliza el registro llamado registro de control de la interrupción externa EICRA.
Los bits 7 a 4 del registro EICRA no son utilizados por lo que se les suele poner a 0, con bits 3 y 2 se elige utilizar el pin INT1 y con los bits 1 y 0 se elige utilizar el pin INT0, de acuerdo a las combinaciones de bits que se hagan se producirá la interrupción externa AVR por alguno de los eventos mencionados líneas arriba.
En la siguiente imagen se muestran las combinaciones de bits para la elección del evento que producirá una interrupción externa AVR por el pin INT1.
En la siguiente imagen se muestran las combinaciones de bits para la elección del evento que producirá una interrupción externa AVR por el pin INT0.
Para habilitar el uso de la interrupción externa AVR se utilizará el registro llamado EIMSK, además deben estar habilitadas las interrupciones globales, lo cual en el XC8 se hará con la instrucción sei(), como se comentó aquí.
Los bits 7 a 2 no se utilizan por lo cual se les suele poner a 0, poniendo a 1 su bit 1 se habilita el uso de la interrupción externa AVR del pin INT1; poniendo a 1 su bit 0 se habilita el uso de la interrupción externa AVR del pin INT0.
Para detectar cuando se ha producido la interrupción externa AVR se cuenta con el registro EIFR.
Los bits 7 a 2 no se utilizan por lo que se les suele poner a 0, para detectar si se ha producido una interrupción externa avr por el pin INT1, el bit 1 se tendrá que poner a 0, cuando se produzca la interrupción este bit se pondrá a 1, si se quiere seguir produciendo mas interrupciones por el pin INT1 este bits habrá que ponerlo nuevamente a 0 dentro de la rutina de interrupciones, cuando se utiliza la rutina de interrupciones con el XC8, este bits se pone a 0 automáticamente; para detectar si se ha producido una interrupción externa avr por el pin INT0, el bit 0 se tendrá que poner a 0, cuando se produzca la interrupción este bit se pondrá a 1, si se quiere seguir produciendo mas interrupciones por el pin INT0 este bits habrá que ponerlo nuevamente a 0 dentro de la rutina de interrupciones, cuando se utiliza la rutina de interrupciones con el XC8, este bits se pone a 0 automáticamente;
Rutinas de interrupción externa avr INT0 e INT1 en C/C++ en el XC8 Si se utiliza la interrupción externa AVR INT0, la rutina de interrupción se realizará dentro de la siguiente función:
ISR(INT0_vect){
//tareas a realizar dentro de la rutina de interrupción INT0
}
Si se utiliza la interrupción externa AVR INT1, la rutina de interrupción se realizará dentro de la siguiente función:
ISR(INT1_vect){
//tareas a realizar dentro de la rutina de interrupción INT1
}
Ejemplo:
Se hará un ejemplo para la interrupción externa AVR por el pin INT0, se le hará llegar una señal la que cambiará su estado entre altos y bajos con la ayuda de un fotorresistor, cuando se ilumine el fotorresistor su resistencia disminuirá y al pin INT0 le llegará un alto, cuando el fotorresistor no se ilumine su resistencia será alta y al pin INT0 le llegará un bajo. Se programará para que la interrupción externa AVR ocurra por flanco de bajada, esto es cuando la señal que llega al pin INT0 pase de un alto a un bajo; cada vez que se produzca la interrupción se cambiará el estado del pin PB0 esto será visible mediante un led. El circuito utilizado es el que se muestra en la imagen.
El programa realizado en el XC8 para el uso de la interrupción externa avr INTx, siguiendo el procedimiento comentado aquí es el siguiente:
#define F_CPU 20000000UL
#include <avr/io.h>
#include <avr/interrupt.h> //libreria necesaria para utilizar las interrupciones
int main(void) {
DDRB|=(1<<0);//pin PB0 como salida para el led que cambia de estado
PORTB&=~(1<<0);//el led se incia apagado
cli();//deshabilita todas las interrupciones, esto se hace por si acaso
EICRA=0b00000010;//interrupción externa por flanco de bajada en el pin INT0
EIMSK=0b00000001;//habilita interrupción externa INT0
EIFR=0b00000000;//su bit 0 a 0 para detectar las interrupciones en INT0
//al producirse la interrupción INT0 este bit se pondrá a 1
//en la rutina ISR se pondrá nuevamente a 0 automaticamente
sei();//habilita las interrupciones globales
while (1) {
//en este ejemplo no se hará nada aquí, todo se hará por interrupción INT0
}
}
ISR(INT0_vect){//rutina cuando se produzca una interrupción externa INT0
PORTB^=(1<<0);//cada vez que ocurre la interrupción el pin PB0 cambia de estado
//visible por medio del led
}
Esperamos de todo corazón ser de vuestra ayuda, no olviden suscribirse al canal de mrelberni, darle me gusta a los vídeos, compartirlos, que de esa manera nos ayudan a continuar, desde ya muchas gracias.
Publicar un comentario