EmbDev.net

Forum: ARM programming with GCC/GNU tools STM32 HAL Delay too slow


Author: Philipp (Guest)
Posted on:

Rate this post
0 useful
not useful
Hi,

I recently started with an STM32F103C8T6 on a bluepill board. I am using 
SW4STM32 on Windows 10.

When writing a program that blinks an LED on PC13 with the standard
peripheral library and implementing my own SysTick_Handler and Delay 
functions, the LED blinks in the correct intervals.

This is the relevant code:
// Main without GPIO Initialization and APB2ENR code
int main(void)
{
  SystemInit();
  SysTick_Config(SystemCoreClock / 1000);
}

// My own SysTick_Handler
void SysTick_Handler(void) {
  static uint32_t millis = 0;
  millis++;
  if (millis % 1000 == 0) {
    flipPin();
  }
}


When I tried porting this code to a project using the Cube HAL libraries 
provided by SW4STM32 and using HAL_Delay for delay, the LED blinks ~18x 
slower. I tried following other guides on writing HAL applications, 
however I could not find any examples about clock configuration.

The relevant HAL code:
// Main without GPIO Initialization and APB2ENR code
int main(void) {
  HAL_Init();
  SysTick_Config(SystemCoreClock / 1000);
  ...
  for (;;) {
    HAL_Delay(1000);
    flipPin();
  }
}

While the STD code blinks the LED in precise 1000ms intervals, the HAL 
code takes ~18000ms for each loop. I have looked at the HAL_Init code, 
switched HAL_Init and SysTick_Config and tested flipPin, but could not 
find any hints to what might cause this behaviour.

 In case anybody knows what I am doing wrong, please let me know. Thank 
you

Author: Philipp (Guest)
Posted on:

Rate this post
0 useful
not useful
I can't edit the post, but one important detail: The main function in 
STD also has a loop in the form of
for(;;);

Author: Philipp (Guest)
Posted on:

Rate this post
1 useful
not useful
Ok, kind of embarassing, I read the code but I skipped the comments. It 
says right on line 175 of "stm32f1xx_hal.c":
  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */

So after configuring the PLL and SysClock with
RCC_PLLInitTypeDef pll;
pll.PLLMUL = RCC_PLL_MUL9;
pll.PLLSource = RCC_PLLSOURCE_HSE;
pll.PLLState = RCC_PLL_ON;

RCC_OscInitTypeDef osc;
osc.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
osc.HSEState = RCC_HSE_ON;
osc.OscillatorType = RCC_OSCILLATORTYPE_HSE;
osc.PLL = pll;

HAL_RCC_OscConfig(&osc);

RCC_ClkInitTypeDef clock;
clock.ClockType = RCC_CLOCKTYPE_SYSCLK;
clock.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

HAL_RCC_ClockConfig(&clock, FLASH_LATENCY_2);

I feel like an idiot, but I will leave this here, so others can find a 
solution.

Author: W.S. (Guest)
Posted on:

Rate this post
0 useful
not useful
Philipp wrote:
> I feel like an idiot, but I will leave this here, so others can find a
> solution.

Why do you fiddle around with this obfuscating HAL?

Just be a man and build your own firmware. I give you a hint, how to do:
https://www.mikrocontroller.net/attachment/316790/STM32F103C8T6.ZIP

Just have a look into it - and use what you want if you are interested.
btw: the binary in this archive should also work on a blue-pill board.

W.S.

Author: STM Code Warrior (Guest)
Posted on:

Rate this post
0 useful
not useful
Philipp wrote:
> In case anybody knows what I am doing wrong, please let me know. Thank
> you

Perhaps you did not do the clock initializiation in the
HAL version correctly.

Author: Sebastian E. (Guest)
Posted on:

Rate this post
0 useful
not useful
SystemCoreClock might still contain the initial clock value (HSI).
Double-check whether the clock configuration updates SystemCoreClock or 
call SystemCoreClockUpdate before using SystemCoreClock .

Author: Heinz M. (subi)
Posted on:

Rate this post
0 useful
not useful
Try to NOT use HAL_Delay.
With HAL_Delay the µC does nothing, but consume energy. I only use it 
for start up, while waiting for some external peripherie to start up.

Never put a HAL_Delay in the Systick or Timer Interrupt!
While HAL_Delay the µC can do nothing else. If the next systick 
interrupt comes meanwhile you have a problem. If some other interrupt 
comes the HAL_Delay timing is added to the time the other interrupt 
takes. Thats why it only should be used while start up or in the main 
loop.

Use a timer or the systick and put a counter inside. By 1 ms timer, 
count until 1000 and then flip the LED on. Like you have done in your 
own systick. Now the µC only needs ~ 1% of the calculating power like 
with HAL_Delay. Now you can use different variables to get different 
timings out of one timer. With HAL_Delay absolutly not possible.

: Edited by User

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig