Skip to main content
Visitor II
June 9, 2023
Solved

HAL_Delay(1); takes 2ms

  • June 9, 2023
  • 5 replies
  • 8493 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

    Super User
    June 9, 2023

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

    JW

    Graduate II
    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

    Visitor II
    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.2Author
    Visitor 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?

    Graduate II
    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.

    Super User
    June 12, 2023

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

    JW

    PNova.2Author
    Visitor II
    June 12, 2023

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

    Thanks