I was trying to understand the working of micros() function internally and I had a look at the function in Arduino.h
This is the code:
unsigned long micros() {
unsigned long m;
uint8_t oldSREG = SREG, t;
cli();
m = timer0_overflow_count;
#if defined(TCNT0)
t = TCNT0;
#elif defined(TCNT0L)
t = TCNT0L;
#else
#error TIMER 0 not defined
#endif
#ifdef TIFR0
if ((TIFR0 & _BV(TOV0)) && (t & 255))
m++;
#else
if ((TIFR & _BV(TOV0)) && (t & 255))
m++;
#endif
SREG = oldSREG;
return ((m << 8) + t) * (64 / clockCyclesPerMicrosecond());
}
Can someone please explain me what this line is doing :
if ((TIFR0 & _BV(TOV0)) && (t & 255))
m++;
2 Answers 2
If the timer 0 has overflowed (TIFR0 & _BV(TOV0)
) and there is at least a count of 1 in the timer count register (t & 255
) then increment the local copy of the overflow count.
That overflow count is used later on to add an upper 8 bits to what is basically an 8 bit counter to turn it into a 16 bit one ((m << 8) + t
).
-
can you please explain me "timer0_overflow_count" too?Parthiv P– Parthiv P2016年01月07日 16:20:00 +00:00Commented Jan 7, 2016 at 16:20
-
1It's the current count of timer overflows - it's incremented in an interrupt routine elsewhere.Majenko– Majenko2016年01月07日 16:20:34 +00:00Commented Jan 7, 2016 at 16:20
Since at the start of this function interrupts have been disabled by the cli()
function it is possible that the timer TCNT0
has overflowed yet this event has not been processed and included in the value of timer0_overflow_count
that has been read into m
. Therefore the line that you are asking about is checking for this condition and incrementing the local copy m
if necessary before using it to calculate the number of microseconds since startup.