cancel
Showing results for 
Search instead for 
Did you mean: 

Problem making an accurate ms delay, either HAL_Delay or my own delay function

ashah.16
Associate II

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

2 REPLIES 2

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

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.

If you feel a post has answered your question, please click "Accept as Solution".