🛠 Programmer en registres AVR : timer 16 bits et interruption

Arduino Mega 2560 (Rev3) · avance · Schéma : IMG-mega-2560-avance-1-registres-timer16.svg — schéma fonctionnel du timer 16 bits TCNT1 de l’ATmega2560 en mode CTC avec OCR1A, prédiviseur 1024 et bascule de la broche PB7 pilotée par l’interruption TIMER1_COMPA

Objectifs

Sortir du cadre Arduino : programmer l'ATmega2560 en C AVR nu (avr-libc) pour configurer le timer 16 bits Timer1 en mode CTC (clear timer on compare), armer l'interruption TIMER1_COMPA et basculer la LED de la broche 13 (PB7) à 1 Hz exacte. Vous comprendrez TCNT1 (compteur 16 bits, 0 à 65535, contre les timers 8 bits Timer0/Timer2), le prédiviseur, OCR1A et le vecteur d'interruption.

Matériel

Le bootloader d'origine (image stk500boot_v2, protocole série à 115200 bauds) accepte un binaire chargé avec le protocole « wiring ». Note documentée : le bootloader actuel refuse l'effacement complét de la puce par avrdude (problem « stk500v2_command: command failed »), d'où l'option -D ci-dessous.

Code complet

/* Blink 1 Hz par Timer1 en CTC — ATmega2560 nu, sans core Arduino */
#define F_CPU 16000000UL          /* quartz de la carte : 16 MHz */
#include <avr/io.h>
#include <avr/interrupt.h>

/* 16 000 000 / 1024 = 15 625 Hz ; OCR1A = 15 624 -> bascule à 1 Hz */
ISR(TIMER1_COMPA_vect) {
    PORTB ^= (1 << PORTB7);       /* toggle PB7 = broche Arduino 13 */
}

int main(void) {
    DDRB  |= (1 << DDB7);         /* PB7 en sortie */
    TCCR1A = 0;                   /* mode normal sur la partie A */
    TCCR1B = (1 << WGM12)         /* CTC : efface TCNT1 à OCR1A */
           |  (1 << CS12) | (1 << CS10);  /* prédiviseur 1024 */
    OCR1A  = 15624;               /* valeur de comparaison 16 bits */
    TIMSK1 |= (1 << OCIE1A);      /* autorise TIMER1_COMPA */
    sei;                        /* active les interruptions */
    for (;;) { /* le CPU dort utilement ici */ }
}
/* Compilation et flash :
   avr-gcc -mmcu=atmega2560 -Os -o timer1.elf timer1.c
   avr-objcopy -O ihex -R .eeprom timer1.elf timer1.hex
   avrdude -p atmega2560 -c wiring -P COMx -b 115200 -D \
           -U flash:w:timer1.hex
*/

Vérification attendue

La LED intégrée bascule exactement une fois par seconde (période complète de 2 s), sans delay ni millis : la cadence vient du quartz 16 MHz divisé par 1024 puis par 15625. En lisant TCNT1 avec un débogueur ou en changeant OCR1A, la fréquence suit immédiatement.

Erreurs fréquentes

Autres tutoriels pour cette carte

Exemples de code pour cette carte

← Retour à la fiche 🛠 Tous les tutoriels