🛠 Sortir des sentiers : registres AVR et interruption externe
Objectives
Program the ATmega32U4 at the register level: configure an external interrupt on a falling edge (registers EICRA and EIMSK), write a short Interrupt Service Routine (ISR), and understand the pattern of using a volatile flag rather than performing long tasks within the ISR. On the Micro, external interrupts are available on pins 0, 1, 2, 3, and 7.
Hardware
- 1 Arduino Micro + micro-USB cable
- 1 push button between pin 3 and GND (pin 3 carries external interrupt INT0; internal pull-up enabled by the code)
- The onboard LED (pin 13) serves as an indicator
Complete code
// 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");
}
}
Expected verification
Each press (falling edge) toggles LED 13 and prints a line; the monitor remains responsive because only a flag toggle occurs in the ISR. By bringing your finger close to the long-wired button, you may see spurious triggers: this is real, hence the pull-up and debouncing on the loop side if necessary.
Common errors
- Calling delay or Serial.println in the ISR: the ISR blocks system time (millis) and corrupts serial output; only raise a flag.
- Forgetting volatile on the shared flag: the compiler optimizes the loop read and the event seems lost.
- Forgetting sei: EIMSK is armed but interrupts are globally masked, so nothing happens.
- Thinking that pins 0/1 are good interrupt inputs here: they are used for Serial1 (RX/TX); prefer 2, 3, or 7.
- Be aware of known quirks of the Caterina bootloader: it executes SPM operations with interrupts enabled and may leave an interrupt armed upon exit (AVR core issues #122 and #218); properly reinitialize EIMSK in setup.
Other tutorials for this board
- 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
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinoclavier-auto-tape.inoArduinosouris-cercle.inoArduinotelecommande-media.inoArduinobouton-clic-souris.inoArduino