2019-11-05 06:43 AM
Hi,
I am facing an odd situation when I use HAL_Delay. In most of the functions I have it works well, but in some functions the program stays in this loop forever:
while((HAL_GetTick() - tickstart) < wait) {}
When I debug, the difference between two values are more than the wait value, but the while statement is always TRUE and stays in the loop !!!
A similar problem exists when I make my own delay using a timer like TIM21. It rises an interrupt and I decrease a counter in the handler as below:
void delay_m(uint16_t ms)
{
HAL_StatusTypeDef state;
if (HAL_TIM_Base_Start_IT(&htim21) != HAL_OK)
{
Error_Handler();
}
myDelayCount = ms;
while(myDelayCount)
LDR_OFF();
HAL_TIM_Base_Stop_IT(&htim21);
return;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM21)
{
myDelayCount --;
}
}
Again: it works well sometimes, but after a while or at some conditions, this operation fails. The myDelayCount would reach 0 or whatever condition I set, but the while statement is not true at all and stays in the while(myDelayCount) for ever.
Could someone help me about this issue?
Thanks
2019-11-05 08:05 AM
The HAL_GetTick() is generally dependent of an interrupt to advance the count, if you are in an IRQ Handler or callback you may be blocking interrupts, and consequently won't advance.
Best to use a free running timer committed to the task, could be 16 or 32-bit depending on the span of the delay. Use a maximal count on the timer, and don't use interrupts.
You can clock the counter at 1 MHz, and get close to +/- 1us resolution, although interrupt loading may impact actual delay. Delta the value in TIMx->CNT to determine the amount of elapsed time.
2019-11-05 12:34 PM
The compiler can optimize away myDelayCount if it’s not declared as volatile. Or two calls to delay_m could be overwriting the value.
You can also consider using the debug timer for very fine precision timing. It counts once per tick with a 32-bit rollover. Look up DWT->CYCCNT and how to enable it.
Make sure you’re using uint32_t variables so the overflow is interpreted correctly.