cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with the delay function in the library for STM32H7B0

When using the delay function, I encountered an incomprehensible manifestation, for verification I brought a signal to the output of the microcontroller and received a switching frequency two times lower. I checked SystemCoreClock, it shows the configured frequency in the debugger. To check, I started a timer and got the correct output switching frequency. With what it can be connected?

11 REPLIES 11
TDK
Guru

Are you doing HAL_Delay(1) and expecting it to be a 1 ms delay? It'll be more like 2 ms.

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

Yes, that's right, but if you change the function to

__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)
//  {
//    wait += (uint32_t)(uwTickFreq);
//  }

  while ((HAL_GetTick() - tickstart) < wait)
  {
  }
}

then the delay starts working normally. The commented-out code biter just doubles it.

I just updated the libraries for STM32F7 and STM32H7 today. This is probably the reason why this error appeared. It didn't exist before the update.

You need the increment to ensure a "minimum-N" delay

JW

If I understood you correctly and from what I read now, the delay value takes on the value N - 1, HAL_Delay (N-1)

HAL_Delay adds 1 to the input value in order to ensure the wait is at least as long as what you requested. This isn't a bug, it's intentional. Otherwise, you could have a situation where HAL_Delay(1) was called immediately before a clock rollover and ended up delaying near 0 ms instead.

There are better ways to do delays, using DWT->CYCCNT or a timer, for instance, which will give you more granularity and reduce this effect.

This part of the code hasn't changed in 4 years, which is as long as it's been posted online.

TDK_0-1693140653489.png

 

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

Using a free running 32-bit TIM (TIM2, TIM5 ?) clocking at 1 MHz (1 us) would provide much finer resolution and granularity.

But this also wouldn't be immune from interrupts or task changes. Would still be markedly better than using SysTick and the resolution and interrupt priority issues there.

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

Ok, sort of figured out the new delay solution. It monitors the number of core ticks, and even if the microcontroller goes into an interrupt, upon exiting it, the function reads the state of the tick counter and adds them, taking into account the missed ones.

It monitors the number of core ticks

Isn't it too complicated? Just use a free-running timer without interrupt, a 32-bit one if available.