🛠 Timer1 et registres AVR : le tempo sans delay
Objectifs
Programmer l'ATmega328P « en métal nu » : timer1 en mode CTC, registres TCCR1A/TCCR1B/TCNT1/OCR1A, calcul du prescaler à 8 MHz, bascule de sortie par registre GPIO. La fiche LilyPad est formelle — aucune radio embarquée (Wi-Fi/Bluetooth uniquement en modules cousus externes) — c'est donc la maîtrise des registres et des timers qui débloque les chronométrages précis et l'économie d'énergie.
Matériel
- 1 LilyPad SimpleSnap (ATmega328P @ 8 MHz)
- 1 LED sur pastille 9 (broche Arduino 9 = PB1 = sortie OC1A du timer1 sur ATmega328P)
- >
- Adaptateur FTDI pour l'échelle de temps série (optionnel)
Code complet
// Timer1 en CTC : carré précis sur la pastille 9 (PB1), sans delay ni tone
// 8 MHz / prescaler 8 = 1 MHz au timer ; 1 MHz / (OCR1A+1 = 250) = 4 kHz d'ISR
volatile uint16_t battements = 0;
void setup {
DDRB |= _BV(PB1); // pastille 9 = PB1 en sortie
TCCR1A = 0; // mode normal côté comparaison de sortie
TCCR1B = _BV(WGM12) // CTC : TCNT1 repart à 0 sur comparaison avec OCR1A
| _BV(CS11); // prescaler /8 -> horloge timer à 1 MHz
OCR1A = 249; // 1 MHz / 250 = une ISR toutes les 250 µs
TIMSK1 = _BV(OCIE1A); // autoriser l'ISR « comparaison A » du timer1
sei; // activer les interruptions globales
}
ISR(TIMER1_COMPA_vect) { // exécutée toutes les 250 µs
if (++battements >= 2000) { // 2000 x 250 µs = 0,5 s
battements = 0;
PINB = _BV(PB1); // écrire 1 dans PINB bascule la broche (XOR matériel)
}
}
void loop {
// 100 % libre : lecture de capteurs, calculs, ou sleep entre deux battements
}
Vérification attendue
La LED clignote à 1 Hz (0,5 s par état) avec la précision du quartz 8 MHz, sans un seul delay : loop reste disponible pour d'autres tâches ou le sommeil. En changeant OCR1A, la fréquence suit exactement le calcul 8 MHz / 8 / 250 / 2000 / 2. Un oscilloscope logique sur la pastille voit un carré net de 1 Hz.
Erreurs fréquentes
- Précalculer OCR1A pour 16 MHz : tout clignote deux fois trop vite — le LilyPad est à 8 MHz, refaire le calcul.
- Oublier sei ou le bit OCIE1A de TIMSK1 : l'ISR ne se déclenche jamais, la LED reste figée.
- Modifier TCCR1B sans remettre TCNT1 à 0 : une interruption immédiate arrive avec un compteur périmé.
- Tenter tone en parallèle sur la même pastille : tone (core Arduino) et ce code se disputent timer1.
- Chercher une radio embarquée : aucune LilyPad n'a de Wi-Fi/Bluetooth intégré ; les radios sont des modules cousus externes, sinon rester sur les périphériques AVR (timer, ADC, UART, SPI, I²C internes).
Autres tutoriels pour cette carte
Exemples de code pour cette carte
clignotante.inoArduinobouton-led.inoArduinopwm-respiration.inoArduinoluxmetre-couture.inoArduinointerrupteur-tilt.inoArduinoservo-balayage.inoArduino