Estoy usando atmega8 que se ejecuta en 1MHz . Escribí una función que cuenta los milisegundos y estaba funcionando perfectamente.
Sin embargo, cuando modifiqué el código para contar microsegundos, el resultado fue extraño para mi ojo, por ejemplo. En lugar de parpadear el LED cada segundo, se encendió durante un segundo y luego se apagó permanentemente.
¿Hay algo de lo que no esté al tanto? ¿Podría estar relacionado con el hecho de que timer2 es 8bit (suceden algunos desbordamientos)?
El timer.c (los fragmentos comentados están funcionando)
#define F_CPU 16000000UL
#include <avr/interrupt.h>
#include <util/atomic.h>
#include "../include/timers.h"
volatile unsigned long milliseconds;
volatile unsigned long microseconds;
ISR (TIMER2_COMP_vect)
{
microseconds += 50;
if (microseconds % 1000 == 0) {
milliseconds++;
}
}
void timers_init(void)
{
TCCR2 |= (1 << WGM21);
//Set the prescaler to 8
TCCR2 |= (1 << CS21);
//OCRn = [ (Clock / Prescaler) * Seconds ] - 1
OCR2 = 99;
TIMSK |= (1 << OCIE2);
sei();
}
unsigned long timers_millis(void)
{
unsigned long millis;
ATOMIC_BLOCK(ATOMIC_FORCEON) {
millis = milliseconds;
}
return millis;
}
unsigned long timers_micros(void)
{
unsigned long micros;
ATOMIC_BLOCK(ATOMIC_FORCEON) {
micros = microseconds;
}
return micros;
}
Y llamando al indicador luminoso LED
while (1) {
if (timers_micros() % 1000000 == 0) {
leds_on(LEDS_REGISTER_PORT, LEDS_PORT_LEFT);
} else {
leds_off(LEDS_REGISTER_PORT, LEDS_PORT_LEFT);
}
if (timers_millis() % 1000 == 0) {
leds_on(LEDS_REGISTER_PORT, LEDS_PORT_RIGHT);
} else {
leds_off(LEDS_REGISTER_PORT, LEDS_PORT_RIGHT);
}
}
ACTUALIZAR
El código anterior se ha actualizado para reflejar los cambios en el software / hardware.
He actualizado el hardware con un oscilador 16MHz externo, configuré los bits de fusible, modifiqué las macros, por ejemplo. F_CPU en consecuencia. Ahora, solo quería comprobar si mi contador funciona como sospecho pero falló: el led RIGHT que adquiere timers_millis() y se supone que se enciende cada segundo funciona bien, pero el otro led LEFT parpadea al azar. El único patrón con LEFT es que si se activa, RIGHT también está activado.
Me he quedado sin ideas y soluciones. ¿Qué podría estar mal con mi software / hardware y cómo puedo contar los microsegundos con precisión ?