Estaba luchando con las interrupciones del temporizador en mi proyecto. No pude hacer que funcionara correctamente. Así que decidí escribir un código simple y vi un caso muy interesante.
ISR(TIMER1_COMPB_vect)
{
PORTB ^= (1 << PORTB5);
}
int main(void)
{
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
OCR1A = 10000;
OCR1B = 100;
TCCR1B |= (1 << WGM12);
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS12);
TIMSK1 |= (1 << OCIE1A);
TIMSK1 |= (1 << OCIE1B);
DDRB= 0xFF;
#define F_CPU 16000000
sei();
while (1)
{
}
}
Aquí está mi código. Cuando cambio el valor de OCR1B, no pasa nada, pero si cambio el valor de OCR1A, el parpadeo se vuelve más rápido. ¿Hay una explicación lógica para esto?
Al configurarlo, TCCR1B |= (1 << WGM12);
opera el temporizador en modo CTC contando desde 0 hasta el valor asignado a OCR1A y de regreso a cero nuevamente.
Con el valor dado del OCR1A = 10000;
temporizador cuenta 0-10000, 0-10000...
Por cada cuenta 0-10000 obtiene una Interrupción de comparación B Match cuando el contador alcanza el valor de 100 (porque ha configurado OCR1B = 100
).
Al cambiar OCR1A, esencialmente cambia el límite de conteo superior del temporizador, lo que significa que también cambia la duración de cada ciclo de conteo, por lo que la interrupción de coincidencia de comparación B ocurre más rápido.
Como ejemplo, si configura OCR1A = 5000;
Comparar B, la interrupción ocurre dos veces más rápido en comparación con cuando, OCR1A = 10000;
porque el temporizador reinicia el conteo cuando llega a 5000 en lugar de 10000, por lo que el período del contador se acorta.
Como nota al margen, asegúrese de incluir en su código las funciones del controlador de interrupciones para todas las interrupciones habilitadas ( ISR(TIMER1_COMPA_vect)
parece que faltan) o pueden ocurrir reinicios.
Zgrkpnr__
alexan_e
alexan_e
Zgrkpnr__