I've read a few documents on best practices for interrupt handling and thought I was doing things correctly, ensuring the variable set in the ISR was declared volatile. In my code the interrupt handler is operating properly, firing at the correct rate per the timer settings (checked by toggling an LED). The problem I'm encountering is that when I check the status of the flag set in the interrupt from my main loop, I get seemingly random updates at rate much much slower than expected. Some more specifics:
Timer ISR Period: 500ms
Main Loop Execution Period: 50us
Effective period of CheckPeriodicTimer() being set: anywhere from 2 - 45 seconds
MCU: STM32F030R8 48 MHz
IDE: STM32CubeIDE 1.3.1
I have tried compiling with and without optimization and am getting the same behavior.
tim.c
volatile uint16_t PeriodicTimerFlag = TIMER_FLAG_CLEAR;
volatile uint32_t TimerOverflow = 0;
...
void HAL_TIM_PeriodElapsedCallback (TIM_HandleTypeDef *htim) {
// check which timer
if (htim->Instance == TIM1) {
// check for stale flag - something is wrong (but also occurs when
// debugger stops execution)
if (PeriodicTimerFlag == TIMER_FLAG_SET) {
TimerOverflow++;
} else { // set the flag and get out of here
PeriodicTimerFlag = TIMER_FLAG_SET;
}
}
}
...
uint16_t CheckPeriodicTimer (void) {
return PeriodicTimerFlag;
}
void ClearPeriodicTimerFlag (void) {
PeriodicTimerFlag = TIMER_FLAG_CLEAR;
}
main.c
...
uint16_t mainPeriodicTimerFlag = TIMER_FLAG_CLEAR;
...
int main(void)
...
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//timer check
mainPeriodicTimerFlag = CheckPeriodicTimer();
Task1(mainPeriodicTimerFlag);
Task2(mainPeriodicTimerFlag);
// Clear timer flag once done
ClearPeriodicTimerFlag(); // remote
mainPeriodicTimerFlag = TIMER_FLAG_CLEAR; //local
}
```
mainPeriodicTimerFlag
is set in the main loop. Turn another pin on right before you call Task1 and off after you exit. Ditto (with a third pin) for Task2. Then look at it all with an oscilloscope. \$\endgroup\$