🛠 Programmer aux registres : interruption Timer/Counter1
Objetivos
Salir de la API de Arduino para controlar el ATmega32u4 « a pelo »: configurar el Timer/Counter1 en modo CTC (Clear Timer on Compare Match) con un divisor de 1024, activar una interrupción de hardware a 1 Hz y alternar el LED del pin 13 (PB7) directamente en el registro PINB. Comprenderás la ruta completa: reloj de 16 MHz, prescaler, OCR1A, vector de interrupción y por qué una ISR debe ser mínima.
Material
- 1 Arduino Leonardo (el sketch se ejecuta sobre el núcleo de Arduino, que sigue siendo necesario para la inicialización y el bootloader Caterina)
- Ningún componente externo: el LED integrado es suficiente
Código completo
// 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); // ecriture 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.
}
Verificación esperada
El LED parpadea a 0,5 Hz (un cambio de estado por segundo, por lo tanto, un apagado/encendido cada 2 s). Verifica la precisión comparando 60 parpadeos con un reloj: el error proviene únicamente de la tolerancia del cristal de 16 MHz. Suspende el loop con delay: el parpadeo continúa, lo que demuestra que es el temporizador y una interrupción los que controlan el pin.
Errores frecuentes
- Olvidar
noInterrupts/interruptsalrededor de la configuración: modificar TCCR1B/OCR1A mientras el temporizador está funcionando puede producir un desbordamiento parásito.
- No declarar
volatilela variable compartida (clignotements): sin esta palabra clave, el optimizador puede eliminar su lectura enloop. - ISR demasiado larga: una ISR que imprime o introduce retardos rompe otras interrupciones, incluida la USB de la Leonardo (el servicio USB está controlado por interrupciones) — la conexión puede bloquearse.
- Equivocarse de registro de alternancia:
PINB = (1 << PINB7)alterna;PORTB ^= ...también funciona, pero realiza una lectura-modificación-escritura, menos atómica en contexto de interrupción. - Cálculo erróneo de OCR1A: con el prescaler 1024, 1 Hz corresponde a OCR1A = 15624; a 2 Hz, 7811; el error clásico es olvidar el +1 del conteo desde cero.
Otros tutoriales para esta placa
- 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)
Ejemplos de código para esta placa
clignotante.inoArduinobouton-led.inoArduinoclavier-auto-tape.inoArduinosouris-cercle.inoArduinotelecommande-media.inoArduinobouton-clic-souris.inoArduino