Timer callback issue?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-24 06:47 AM
Hi,
I have timer with period 1 sec (80 MHz clock):
htim2.Init.Prescaler = 80-1;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 1000000-1;
Global var (volatile uint32_t) increased every time counter wraps around
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2) {
globalSeconds++;
}
}
In the code, timestamp (timer counter and var) collected and send later over UART (speed 921600)
do {
sec = globalSeconds;
us = TIM2->CNT;
} while (sec != globalSeconds);
When I get values on pc, I noticed that seconds are not always correct. It happens when usec timer counter wraps around:
34.995010
34.999530
34.100404
34.100858
I'm a bit puzzled about it, coz globalSeconds changed only in one place in the code by TIM2 interrupt.
The only explanation I could imagine, that HAL_TIM_PeriodElapsedCallback() is not called (INT disabled?)...
Even if handling of INT was delayed by other INT, eventually it shall increase globalSeconds counter.
Could other interrupts (two UARTs, SPI) or high MCU load cause trouble with HAL_TIM_PeriodElapsedCallback()?
Any ideas are welcome :)
Regards,
Lex
- Labels:
-
Interrupt
-
STM32L4 Series
-
TIM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-24 08:10 AM
How is globalSeconds defined?
The most straighforward thing to do is to toggle a pin at the place where globalSeconds is incremented, and observe using oscilloscope/logic analyzer.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-25 12:09 AM
Thanks for advise! At least I could prove that it is not stepped up. globalSeconds definition is below:
volatile uint32_t globalSeconds = 0;
Solution is using 3d-party library and SDK to control another chip connected over SPI. I recall some part of code from the SDK blocks interrupts to process SPI data...
/Lex
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-04-25 07:07 AM - edited ‎2024-04-25 07:14 AM
You do not need an interrupt! Just let the timer overflow at 0xFFFFFFFF. As long as you read the timer value at least once every 4000 seconds you can simply detect the occasional single overflow in software!
Code snippet (untested, but I've used similar code)
static uint64_t microSecondsOld = 0;
uint32_t val = TIM2->CNT;
uint64_t microSecondsNew = microSecondsOld & 0xFFFFFFFF00000000ULL | val;
if (microSecondsNew < microSecondsOld)
{
//overflow occured
microSecondsNew += 1ULL<<32;
}
microSecondsOld = microSecondsNew;
Just be aware the variable is not atomic so you should disable interrupts when modifying it (I didn't for simplicity sake).
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.
