🛠 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

Objetivos

Salir del marco de Arduino: programar el ATmega2560 en C AVR puro (avr-libc) para configurar el temporizador de 16 bits Timer1 en modo CTC (clear timer on compare), habilitar la interrupción TIMER1_COMPA y alternar el LED del pin 13 (PB7) a una frecuencia exacta de 1 Hz. Comprenderá TCNT1 (contador de 16 bits, de 0 a 65535, frente a los temporizadores de 8 bits Timer0/Timer2), el prescaler, OCR1A y el vector de interrupción.

Material

El bootloader original (imagen stk500boot_v2, protocolo serie a 115200 baudios) acepta un binario cargado con el protocolo « wiring ». Nota documentada: el bootloader actual rechaza el borrado completo del chip mediante avrdude (problema « stk500v2_command: command failed »), de ahí la opción -D que se muestra a continuación.

Código completo

/* 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
*/

Verificación esperada

El LED integrado alterna exactamente una vez por segundo (período completo de 2 s), sin delay ni millis: la frecuencia proviene del cristal de 16 MHz dividido por 1024 y luego por 15625. Al leer TCNT1 con un depurador o al cambiar OCR1A, la frecuencia se ajusta inmediatamente.

Errores frecuentes

Otros tutoriales para esta placa

Ejemplos de código para esta placa

← Volver a la ficha 🛠 Todos los tutoriales