Skip to main content
Visitor II
January 23, 2024
Question

STM32H5 GPIO toggling performance

  • January 23, 2024
  • 3 replies
  • 4733 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.

 

 

 

 

    This topic has been closed for replies.

    3 replies

    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

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

    BrusslAuthor
    Visitor II
    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?

    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  .

     

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