🛠 Programmer aux registres : interruption Timer/Counter1
Objectifs
Sortir de l'API Arduino pour piloter l'ATmega32u4 « à nu » : configurer le Timer/Counter1 en mode CTC (Clear Timer on Compare Match) avec un diviseur de 1024, déclencher une interruption matérielle à 1 Hz, et basculer la LED de la broche 13 (PB7) directement dans le registre PINB. Vous comprendrez le chemin complet : horloge 16 MHz, prescaler, OCR1A, vecteur d'interruption, et pourquoi une ISR doit rester minimale.
Matériel
- 1 Arduino Leonardo (le sketch s'exécute au-dessus du cœur Arduino, qui reste nécessaire pour l'initialisation et le bootloader Caterina)
- Aucun composant externe : la LED intégrée suffit
Code complet
// Clignotement 0,5 Hz par interruption Timer/Counter1 en mode CTC
// 16 MHz / 1024 (prescaler) / 15625 = 1 Hz d'increment compare
volatile uint8_t clignotements = 0;
void setup {
DDRB |= (1 << DDB7); // PB7 (Arduino D13) en sortie
noInterrupts;
TCCR1A = 0;
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); // mode CTC, prescaler 1024
TCNT1 = 0;
OCR1A = 15624; // 16e6 / 1024 / (15624+1) = 1 Hz
TIMSK1 |= (1 << OCIE1A); // autorise l'interruption Compare Match A
interrupts;
}
ISR(TIMER1_COMPA_vect) {
PINB = (1 << PINB7); // écriture de 1 dans PINB = bascule la broche
clignotements++;
}
void loop {
// Le travail se fait dans l'ISR ; la boucle principale reste libre.
// Exemple : Serial toutes les 2 bascules (0,5 Hz) si besoin.
}
Vérification attendue
La LED clignote à 0,5 Hz (une bascule par seconde, donc une extinction/allumage toutes les 2 s). Vérifiez la précision en comparant 60 clignotements à une montre : l'erreur vient uniquement de la tolérance du quartz 16 MHz. Suspendez le loop avec delay : le clignotement continue, preuve que c'est bien le timer et une interruption qui pilotent la broche.
Erreurs fréquentes
- Oublier
noInterrupts/interruptsautour de la configuration : modifier TCCR1B/OCR1A pendant que le timer tourne peut produire un débordement parasite.
- Ne pas déclarer
volatilela variable partagée (clignotements) : sans ce mot-clé, l'optimiseur peut supprimer sa lecture dansloop. - ISR trop longue : une ISR qui imprime ou temporise casse les autres interruptions, dont l'USB de la Leonardo (le service USB est lui-même piloté par interruptions) — la connexion peut se figer.
- Se tromper de registre de bascule :
PINB = (1 << PINB7)bascule ;PORTB ^= ...fonctionne aussi mais fait lire-modifier-écrire, moins atomique en contexte d'interruption. - Précalcul erroné d'OCR1A : avec le prescaler 1024, 1 Hz correspond à OCR1A = 15624 ; à 2 Hz, 7811 ; l'erreur classique est d'oublier le +1 du comptage depuis zéro.
Autres tutoriels pour cette carte
- Faire clignoter la LED intégrée (broche 13)
- Bouton et console série : Serial (USB) vs Serial1 (broches 0/1)
- Lire un capteur analogique : potentiomètre et ADC 10 bits
- Clavier USB : taper du texte avec la bibliothèque Keyboard
- Souris USB : déplacer le curseur avec la bibliothèque Mouse
- Asservir un servo moteur avec un potentiomètre (PWM)
Exemples de code pour cette carte
clignotante.inoArduinobouton-led.inoArduinoclavier-auto-tape.inoArduinosouris-cercle.inoArduinotelecommande-media.inoArduinobouton-clic-souris.inoArduino