With timers, I want to toggle an LED every one second. I'm using ATMega32 and the clock frequency is 1MHz. I can get to 0.1 second using the 8-bit counter, and for each 10 timer interrupts, I blink the led.
#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
typedef unsigned char u8_t;
typedef unsigned short u16_t;
void func();
int main(void)
{
DDRC = 0x80;
TCCR0 |= (1 << WGM01); // CTC bit.
TCCR0 |= (1 << CS02) | (1 << CS00); // Prescalar = 1024.
OCR0 = 98; // 98 ticks correspond to roughly 0.1 second with 1024 prescaler
TIMSK |= (1 << OCIE0);
TCNT0 = 0;
sei();
while(1)
{
if (!(TIFR & (1 << OCF0))) {
func();
}
}
}
void func()
{
static u8_t extra_time = 0;
if (extra_time == 10)
{
extra_time = 0;
PORTC ^= 0x80;
}
else extra_time++;
TIFR |= (1 << OCF0);
}
In the preceding code, I do not define an ISR for the TIMER0_COMP_vect
interrupt.
From the datasheet:
The OCF0 bit is set (one) when a compare match occurs between the Timer/Counter0 and the data in OCR0 – Output Compare Register0. OCF0 is cleared by hardware when executing the corresponding interrupt handling vector. Alternatively, OCF0 is cleared by writing a logic one to the flag. When the I-bit in SREG, OCIE0 (Timer/Counter0 Compare Match Interrupt Enable), and OCF0 are set (one), the Timer/Counter0 Compare Match Interrupt is executed.
emphasis mine.
Therefore, by the emphasized sentence, I can check for the OCF0 bit for being a zero, and if so, I can "handle" the on-compare-match event.
However, the LED blinks much more frequently (not even a tenth second between each blink but I cannot measure of course).
This works fine if I just set an ISR on TIMER0_COMP_vect
and check for nothing, but I want to know why is the OCF0 always(?) logic 0, hence "on", even though I set it to high on each func()
call. And what's the problem with this method.