ATmega328P: Interrupciones

Contenido:

Interrupciones del ATmega328P

Las interrupciones del ATmega328p son señales que indican al procesador que se ha producido un evento externo o interno que requiere su atención inmediata. Cuando ocurre una interrupción, el procesador detiene temporalmente la ejecución del programa actual y salta a una rutina de interrupción específica que se encarga de manejar el evento en cuestión. Una vez que se ha completado la rutina de interrupción, el procesador regresa a la ejecución del programa donde lo dejó antes de que ocurriera la interrupción. Las interrupciones permiten al procesador responder rápidamente a eventos externos o internos sin tener que esperar a que se complete el programa en curso, lo que mejora la eficiencia y la capacidad de respuesta del sistema.

El ATmega328P tiene las siguientes fuentes de interrupción:

  • Interrupciones externas: El microcontrolador puede ser interrumpido por una señal en el pin INT0 (PD2) o INT1 (PD3). Estas señales pueden ser generadas por dispositivos externos, como sensores, botones, etc.
  • Interrupciones por timer: Los timers (temporizadores) internos del microcontrolador pueden generar interrupciones en ciertos momentos, por ejemplo, cuando un contador llega a un valor determinado.
  • Interrupciones por cambio de estado: El microcontrolador puede ser interrumpido por un cambio en el estado de los pines de entrada/salida.
  • Interrupciones por comunicación serie: El microcontrolador puede generar interrupciones cuando recibe o transmite datos a través de los módulos USART, SPI o I2C.
  • Interrupción por finalización de conversión A/D: El módulo ADC puede generar una interrupción cuando finaliza una conversión A/D.

Cada fuente de interrupción tiene un vector de interrupción asociado, que es una dirección de memoria que indica la ubicación del código que se ejecutará cuando se produzca la interrupción.

✅ Si quieres conocer la descripción de cada uno de los registros, además de varios ejemplos adicionales de los que encontrarás en este post, te invito a que adquieras la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 dando clic ⭐ aquí ⭐. Adicionalmente recibirás los sketch de Arduino IDE y de Microchip Studio, incluyendo los archivos de simulación en Proteus Profesional v8.10.

Video Tutorial

Ejemplo 1:Usar interrupciones para hacer parpadear los leds de acuerdo a diversas condiciones.

  • Led 1 parpadea con un periodo de 200ms.
  • Led 2 parpadea con un periodo de 1000ms.
  • Led 3 parpadea con un periodo de 700ms.
  • Led 4 cambia de estado cada vez que se presiona el Pin INT0.

Para lograr un parpadeo de cada led mediante el manejo de interrupciones, se configura el Timer/Counter0 en modo de operación normal, con un preescaler 1024, y se utiliza la interrupción por comparación del Timer/Counter0, debido a que la frecuencia del dispositivo es de 16MHz.

Utilizando el preescaler antes mencionado se obtiene un periodo de 64us, al contabilizar 157 periodos se tiene un tiempo de 10ms, con el uso de tres contadores los cuales incrementan su valor cada 10ms se logra realizar el parpadeo de cada led a su respectivo tiempo, el primer contador el cual se encarga de realizar un parpadeo cada 200ms, cuando llegue al valor de 20 habrán transcurrido los 200ms, allí es donde la salida cambia de estado y el contador se reinicia, el mismo proceso se realiza en los otros contadores.

at328p interrupciones ejm1 calculo
Figura 1: Calculo de condiciones.

Para realizar el parpadeo del led4 mediante un botón se debe generar una señal digital en el Pin INT0, para ello se debe habilitar en sus respectivos registros la interrupción externa por flanco de bajada, cada vez que se presione el botón se realiza una interrupción y la salida cambia de estado.

Arduino:

at328p interrupciones ejm1 1
Figura 2: Circuito con Arduino para el Ejemplo 1 de las Interrupciones.
uint8_t contador_1 = 0;
uint8_t contador_2 = 0;
uint8_t contador_3 = 0;

void setup() {
  DDRC = 0b00001111; // Puerto C: [3:0] Salidas para los leds
  PORTC = 0b00000000; // Salidas en bajo

  cli(); // Deshabilito interrupciones hasta configurar

  // INTERRUPCION TIMER0
  TCCR0A = 0b00000010; // [7:6] OC0A Desabilitado, [5:4] OC0B Desabilitado, [1:0] Operacion normal
  TCCR0B = 0b00000101; // [2:0] Preescaler 1024
  TIMSK0 = 0b00000110; // [2:1]Interrupcion timer0 por comparacion A, B

  // INTERRUPCION EXTERNA
  EICRA = 0b00000010; // Interrupcion externa por flanco de bajada en el pin INT0
  EIMSK = 0b00000001; // Habilito interrupcion externa INTO
  EIFR = 0b00000000; // a 0 para detectar interrupciones en INT0

  sei(); // Habilito interrupciones

  OCR0A = 157; // Comparacion A cada 10ms
  OCR0B = 157; // Comparacion B cada 10ms
}

ISR(TIMER0_COMPA_vect) { // Interrupcion por comparacion A
  contador_1++; // Incremento la variable

  // Cambio de estado cada 200ms
  if (contador_1 == 20) { // Si la variable es igual a 20
    contador_1 = 0; // Reinica la variable
    PORTC ^= (1 << PINC0); // Cambia de estado el Pin
  }
}

ISR(TIMER0_COMPB_vect) { // Interrupcion por comparacion B
  contador_2++; // Incremento la variable
  contador_3++; // Incremento la variable

  // Cambio de estado cada 1000ms
  if (contador_2 == 100) { // Si la variable es igual a 10
    contador_2 = 0; // Reinica la variable
    PORTC ^= (1 << PINC1); // Cambia de estado el Pin
  }

  // Cambio de estado cada 700ms
  if (contador_3 == 70) { // Si la variable es igual a 10
    contador_3 = 0; // Reinica la variable
    PORTC ^= (1 << PINC2); // Cambia de estado el Pin
  }
}

ISR(INT0_vect) { // Interrupcion externa
  PORTC ^= (1 << PINC3); // Cambia de estado el Pin
}

void loop() {

}

Lenguaje C:

at328p interrupciones ejm1 2
Figura 2: Circuito con ATmega328P para el Ejemplo 1 de las Interrupciones.
Este ejemplo solo está disponible en la 🔥 Guía de Programación mediante registros del Microcontrolador ATmega328P 🔥 adquiérela hoy dando clic ⭐ aquí ⭐.

Deja un comentario