I recently planned to use AVR timer/counter for my projects. I have studied a number of documents about how to set it up. I use ATTiny2313A to test it out and learn about its features. I came across a problem when tried to toggle a pin for every few seconds.
According to the datasheet the TIFR
has the following bit arrangement:
As you see the first bit is assigned to TOV0
. When a counter overflow occurs this bit is set to 1. I used this fact and developed a code as following:
#include <avr/io.h>
int main(void)
{
uint16_t count=0, M=500;
uint8_t n=0x02;
DDRB=0xff;
TCNT0=0x00;
TCCR0B=(1<<CS00) | (1<<CS02); //use prescaler 1024
while (1)
{
while ((TIFR & n) == 0); // control passes this loop after TIFR sets to n,
// which is when counter overflows
TCNT0 = 0x00;
TIFR=n; // clear TIFR
count++;
if (count>=M)
{
PORTB ^= (1 << PB0);
count=0;
}
return (0);
}
The code works as expected. I expect that when an overflow occurs TIFR
changes to 0x02
as TOV0
sets to one. But that seems not to be the only scenario. If I change the variable n
to something like n=0x04
and build the program I see the same behavior, meaning that the LED connected to PB0
still toggles with the same frequency as it did previously. The second bit in TIFR
corresponds to OCF0B
. So if the code wants to work as before this bit must change to 1 when an overflow happens. But does it? I don't think the output compare flag is enabled so OCF0B
can't change.
Best Answer
The
OCF0B
is a compare match flag, which will get set regardless of whether the interrupt is enabled or not. It will get set exactly once per overflow cycle, just like a broken clock will show the correct time twice a day. This is why you are getting the exact same period time with this flag or with the overflow flag.