Skip to main content
Associate III
January 23, 2024
Question

STM32H5 GPIO toggling performance

  • January 23, 2024
  • 3 replies
  • 4734 views

I use STM32H562 and/or STM32H503 (nucleo board). When try in loop only this line:

while (1)

{

 

GPIOB->ODR ^= GPIO_PIN_6;  

 

}

The frequency on pin is only 12.5 mhz. I use external quartz 8mhz (and 24mhz on nucleo)

I config  to 250mhz (with build-in CubeMX ) :

 

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct = {0};

RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 

/** Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

 

while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 

 

 

/** Initializes the RCC Oscillators according to the specified parameters

* in the RCC_OscInitTypeDef structure.

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 2;

RCC_OscInitStruct.PLL.PLLN = 125;

RCC_OscInitStruct.PLL.PLLP = 2;

RCC_OscInitStruct.PLL.PLLQ = 2;

RCC_OscInitStruct.PLL.PLLR = 2;

RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_3;

RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;

RCC_OscInitStruct.PLL.PLLFRACN = 0;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

Error_Handler();

}

 

/** Initializes the CPU, AHB and APB buses clocks

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

|RCC_CLOCKTYPE_PCLK3;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

 

if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)

{

Error_Handler();

}

}

 

Why is output frequency is too low ?. In assembler are no more 5 lines. So must be arround 50mhz.

 

 

 

 

3 replies

Peter BENSCH
Technical Moderator
January 23, 2024

Welcome @Brussl, to the community!

well, a similar issue has already been discussed several times in the community, for example here.

Hope that helps?

Regards
/Peter

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
AScha.3
Super User
January 23, 2024

In my speed test on H563 at 250M core , i got

bsrr 4ns , +12ns ( while loop 8+4ns) =>  16ns total , so about 62MHz output at a pin, including the while loop.

But only if compiling with optimizer -O2 (or -Ofast) , these cpus are made to be fast only in cooperation with the optimized code.  So set the optimizer...

"If you feel a post has answered your question, please click ""Accept as Solution""."
BrusslAuthor
Associate III
January 23, 2024

Tnx a lot for fast answers. I see and other strange - when i add HAL_Delay(1)  in loop the period is not around 2ms but 4ms - 2 time slower !

AScha.3 - Tnx will check it. Can you send me  SystemClock_Config(void) function if is different from mine. And what source you have use? And what is VCC - 3.3V?

AScha.3
Super User
January 23, 2024

To check internal clk, you have a MCO output ! Enable it, select the clock to test and test on mco pin with scope (or counter ) . I did this at first ... never trust anything. :)

AScha3_0-1706028249341.pngAScha3_1-1706028291784.png

-> testing pll1q (100M) /10 here , 10M coming out.

AScha3_2-1706028417483.png

 

 

+ here SystemClock_Config , just as cube puzzeled it together:

 

void SystemClock_Config(void)
{
 RCC_OscInitTypeDef RCC_OscInitStruct = {0};
 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 /** Configure the main internal regulator output voltage
 */
 __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0);

 while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}

 /** Initializes the RCC Oscillators according to the specified parameters
 * in the RCC_OscInitTypeDef structure.
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
 RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIGITAL;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
 RCC_OscInitStruct.PLL.PLLSource = RCC_PLL1_SOURCE_HSE;
 RCC_OscInitStruct.PLL.PLLM = 4;
 RCC_OscInitStruct.PLL.PLLN = 250;
 RCC_OscInitStruct.PLL.PLLP = 2;
 RCC_OscInitStruct.PLL.PLLQ = 5;
 RCC_OscInitStruct.PLL.PLLR = 2;
 RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1_VCIRANGE_1;
 RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1_VCORANGE_WIDE;
 RCC_OscInitStruct.PLL.PLLFRACN = 0;
 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
 |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
 |RCC_CLOCKTYPE_PCLK3;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

 

 

cpu at 3v3 , source ...is on NUCLEO-H563ZI board...hse bypass , set :8MHz  .

 

"If you feel a post has answered your question, please click ""Accept as Solution""."
Tesla DeLorean
Guru
January 24, 2024

The RMW is going to be inherently slow. It's compounded by the speed of the bus.

Do singular writes to BSRR to set a pin high or low.

If you need to toggle a pin use the TIM. Don't saturate the processor and bus.

For driving patterns use DMA from a buffer to the GPIO BSRR register.

 

 

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