🛠 Sortir des sentiers : registres AVR et interruption externe
Objetivos
Programar el ATmega32U4 a nivel de registros: configurar una interrupción externa por flanco de bajada (registros EICRA y EIMSK), escribir una rutina de servicio (ISR) breve, y comprender el patrón de usar una bandera volatile en lugar de realizar trabajo largo dentro de la ISR. En la placa Micro, las interrupciones externas están disponibles en los pines 0, 1, 2, 3 y 7.
Material
- 1 Arduino Micro + cable micro-USB
- 1 botón pulsador entre el pin 3 y GND (el pin 3 corresponde a la interrupción externa INT0; el pull-up interno se activa mediante el código)
- El LED integrado (pin 13) sirve como indicador
Código completo
// Interruption externe sur front descendant, a la main (sans attachInterrupt).
// Broche 3 du Micro = INT0. On configure les registres puis on ecrit l'ISR.
volatile bool evenement = false; // drapeau partage ISR -> boucle
void setup {
DDRB &= ~(1 << DDB0); // sens entree de la broche 13 cote port B
EIMSK &= ~(1 << INT0); // INT0 desactive pendant la config
EICRA = (1 << ISC01) | (0 << ISC00); // INT0 sur front descendant
EIMSK |= (1 << INT0); // autoriser INT0
// Broche 3 : entree + pull-up (le noyau Arduino gere le pull via PORT)
pinMode(3, INPUT_PULLUP);
pinMode(LED_BUILTIN, OUTPUT);
sei; // autorisation globale des interruptions
Serial.begin(9600);
}
ISR(INT0_vect) { // executee sur chaque front descendant
evenement = true; // travail minimal : lever un drapeau
}
void loop {
if (evenement) {
evenement = false;
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
Serial.println("INT0 : front descendant detecte");
}
}
Verificación esperada
Cada pulsación (flanco de bajada) alterna el estado del LED 13 e imprime una línea; el monitor permanece reactivo porque solo se produce un cambio de bandera dentro de la ISR. Al acercar el dedo al botón con cableado largo, se pueden observar disparos parásitos: esto es real, de ahí la necesidad del pull-up y de la gestión antirrebote en el bucle principal si es necesario.
Errores frecuentes
- Usar delay o Serial.println dentro de la ISR: la ISR bloquea el tiempo del sistema (millis) y corrompe la salida serie; solo se debe levantar una bandera.
- Olvidar el modificador volatile en la bandera compartida: el compilador optimiza la lectura en el bucle y el evento parece perderse.
- Olvidar llamar a sei: aunque EIMSK esté armado, las interrupciones están globalmente enmascaradas y no ocurre nada.
- Pensar que los pines 0/1 son buenas entradas de interrupción aquí: se utilizan para Serial1 (RX/TX); es preferible usar los pines 2, 3 o 7.
- Prestar atención a las particularidades conocidas del bootloader Caterina: ejecuta operaciones SPM con interrupciones activas y puede dejar una interrupción armada al salir (problemas del núcleo AVR #122 y #218); reinicializa correctamente EIMSK en setup.
Otros tutoriales para esta placa
- Faire clignoter la LED embarquée (et comprendre les LED TX/RX)
- Lire un bouton avec une résistance de pull-up interne
- Lire un capteur analogique sur le convertisseur 10 bits
- Transformer le Micro en clavier USB (HID) avec bouton de sécurité
- Pont Serial vers Serial1 : passerelle USB vers TTL
- Piloter un servo moteur avec le PWM et un potentiomètre
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinoclavier-auto-tape.inoArduinosouris-cercle.inoArduinotelecommande-media.inoArduinobouton-clic-souris.inoArduino