🛠 Timer1 et registres AVR : le tempo sans delay
Objectives
Program the ATmega328P "bare metal": timer1 in CTC mode, registers TCCR1A/TCCR1B/TCNT1/OCR1A, prescaler calculation at 8 MHz, output toggling via GPIO registers. The LilyPad board is explicit — no embedded radio (Wi-Fi/Bluetooth only via external sewn-on modules) — so mastering registers and timers is what unlocks precise timing and power efficiency.
Hardware
- 1 LilyPad SimpleSnap (ATmega328P @ 8 MHz)
- 1 LED on pad 9 (Arduino pin 9 = PB1 = timer1 OC1A output on ATmega328P)
- >
- FTDI adapter for serial time scale (optional)
Complete code
// 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
}
Expected verification
The LED blinks at 1 Hz (0.5 s per state) with the precision of the 8 MHz crystal, without a single delay: loop remains available for other tasks or sleep. Changing OCR1A makes the frequency follow exactly the calculation 8 MHz / 8 / 250 / 2000 / 2. A logic analyzer on the pad sees a clean 1 Hz square wave.
Common errors
- Precomputing OCR1A for 16 MHz: everything blinks twice as fast — the LilyPad is at 8 MHz, redo the calculation.
- Forgetting sei or the OCIE1A bit of TIMSK1: the ISR never triggers, the LED stays frozen.
- Modifying TCCR1B without resetting TCNT1 to 0: an immediate interrupt arrives with a stale counter.
- Trying tone in parallel on the same pad: tone (Arduino core) and this code compete for timer1.
- Looking for an embedded radio: no LilyPad has integrated Wi-Fi/Bluetooth; radios are external sewn-on modules, otherwise stick to AVR peripherals (timer, ADC, UART, SPI, internal I²C).
Other tutorials for this board
Code examples for this board
clignotante.inoArduinobouton-led.inoArduinopwm-respiration.inoArduinoluxmetre-couture.inoArduinointerrupteur-tilt.inoArduinoservo-balayage.inoArduino