When you are forced to use 64-bit variables you should be extra-careful, because as usual the devil is in the details.
Recently I implemented a 64-bit counter by using a 32-bit counter and a counter for the overflow interrupt.
Here is the overflow interrupt callback:
Code: Select all
// Interrupt Service Routine for TIM2 counter overflow / wraparound
void Timer2_Overflow_ISR(void)
{
tim2overflowcounter++;
// do we have to manually clear the UIF bit in TIM2 status register? No, the UIF flag is cleared automatically.
}
Code: Select all
lsfcount = TIM2->CCR3; // read 32-bit counter compare register for Timer 2
fcount64 = (tim2overflowcounter << 32) + lsfcount; // hehe now we have a 64-bit counter
![Idea :idea:](./images/smilies/icon_idea.gif)
I had declared tim2overflowcounter as a global variable thus:
Code: Select all
volatile uint32_t tim2overflowcounter = 0; // counts the number of times TIM2 overflows
The correct declaration of tim2overflowcounter should be:
Code: Select all
volatile uint64_t tim2overflowcounter = 0; // counts the number of times TIM2 overflows
![Shocked :shock:](./images/smilies/icon_eek.gif)