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 ?