Skip to main content
PNova.2
Associate II
June 9, 2023
Solved

HAL_Delay(1); takes 2ms

  • June 9, 2023
  • 5 replies
  • 10314 views

Hello

I just found out that the HAL_Delay() delay actually takes 1ms longer than the desired value. Why?

STM CUBE IDE 1.9.0

STM32F072RBT6


_legacyfs_online_stmicro_images_0693W00000dDT36QAG.png
_legacyfs_online_stmicro_images_0693W00000dDT31QAG.png

This topic has been closed for replies.
Best answer by waclawek.jan

Because it's an "at-least-N-ms" delay with 1ms granularity.

JW

5 replies

waclawek.jan
waclawek.janBest answer
Super User
June 9, 2023

Because it's an "at-least-N-ms" delay with 1ms granularity.

JW

Tesla DeLorean
Guru
June 9, 2023

If you want something that can resolve better, use a TIM that clocks faster, and read the TIMx->CNT

Code may also be interrupted

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
S.Ma
Principal
June 9, 2023

To measure or wait a precise duration, you may need a dedicated stopwatch, sharing a always running wallclock won't be the same...

PNova.2
PNova.2Author
Associate II
June 12, 2023

waclavek.jan,Tesla DeLorean, S.Ma :

But I'm not interested in accuracy. The time is always accurate, just always +1ms, because as I found out, the function automatically increments the variable at the beginning.

__weak void HAL_Delay(uint32_t Delay)
{
 uint32_t tickstart = HAL_GetTick();
 uint32_t wait = Delay;
 
 /* Add a freq to guarantee minimum wait */
 if (wait < HAL_MAX_DELAY)// allways add uwTickFreq (1)
 {
 wait += (uint32_t)(uwTickFreq);
 }
 
 while((HAL_GetTick() - tickstart) < wait)
 {
 }
}

For values in hundreds of milliseconds it is of course not important, but for 1ms it does 100%. And that caused me a problem that I only discovered by using a logic analyzer.

Of course, it is a weak function that I can override according to my needs, but I was more interested in the reason why it is so.

Sure, the comment says that it should guarantee at least a minimal delay, but it can certainly be better:

 /* Add a freq to guarantee minimum wait */
 if (wait < 1)
 {
 wait += (uint32_t)(uwTickFreq);
 }

Or am i wrong?

Tesla DeLorean
Guru
June 12, 2023

Depends when it is called.

A fraction of a second prior to the systick will result in a very short delay.

The solution is really to have a time base that resolves in much finer resolution, say 1 or 2 orders of magnitude.

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
waclawek.jan
Super User
June 12, 2023

I tried to answer ecactly this in the article I linked to above.

JW

PNova.2
PNova.2Author
Associate II
June 12, 2023

Yes, that's what I wanted to know. I just didn't notice that "Because" was a link.

Thanks