cancel
Showing results for 
Search instead for 
Did you mean: 

Why I get STM32H7 GPIO Toggle speed just only at 16.7MHz?

Cen Yunxiong
Associate II
Posted on March 01, 2018 at 05:10

I used NUCLEO-H743ZI board which is mounted STM32H743ZIT, and  used STM32 CubeMX generate Code like this.

I config PC9 = MCO2   to output   SYSCLK/10.   I  can get 80MHz wave at Pin PC9, so I ensure the SYSCLK   is 400MHz 。 As the AHBCLKDivider  = RCC_HCLK_DIV2,so  AHB4CLK  is 200MHz,。 But I just  only get 16.7MHz wave at the Pin PB8.  What is wrong with that? Thanks!

void main(void)

{

HAL_Init();

SystemClock_Config();

MX_GPIO_Init();

HAL_EnableCompensationCell();

while (1)

{

   GPIOB->ODR = 0X100;

   GPIOB->ODR = 0X00;

   GPIOB->ODR = 0X100;

   GPIOB->ODR = 0X00;

   GPIOB->ODR = 0X100;

   GPIOB->ODR = 0X00;

   GPIOB->ODR = 0X100;

   GPIOB->ODR = 0X00;

    }

}

void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

/**Supply configuration update enable

*/

MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);

/**Configure the main internal regulator output voltage

*/

__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY)

{

}

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

*/

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;

RCC_OscInitStruct.HSEState = RCC_HSE_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;

RCC_OscInitStruct.PLL.PLLM = 1;

RCC_OscInitStruct.PLL.PLLN = 100;

RCC_OscInitStruct.PLL.PLLP = 2;

RCC_OscInitStruct.PLL.PLLQ = 2;

RCC_OscInitStruct.PLL.PLLR = 2;

RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3;

RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;

RCC_OscInitStruct.PLL.PLLFRACN = 0;

if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

{

_Error_Handler(__FILE__, __LINE__);

}

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

*/

RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2

|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;

RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;

RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;

RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;

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

{

_Error_Handler(__FILE__, __LINE__);

}

HAL_RCC_MCOConfig(RCC_MCO2, RCC_MCO2SOURCE_SYSCLK, RCC_MCODIV_5);

/**Configure the Systick interrupt time

*/

HAL_SYSTICK_Config(SystemCoreClock/1000);

/**Configure the Systick

*/

HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);

/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}

static void MX_GPIO_Init(void)

{

GPIO_InitTypeDef GPIO_InitStruct;

/* GPIO Ports Clock Enable */

__HAL_RCC_GPIOH_CLK_ENABLE();

__HAL_RCC_GPIOC_CLK_ENABLE();

/*Configure GPIO pin : PC9 */

GPIO_InitStruct.Pin = GPIO_PIN_9;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF0_MCO;

HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

__HAL_RCC_GPIOB_CLK_ENABLE();

/*Configure GPIO pin : PB8 */

GPIO_InitStruct.Pin = GPIO_PIN_8;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}

4 REPLIES 4
Posted on March 01, 2018 at 09:21

Try to switch on optimization. Observe disassembled code.

Run from TCM memory. Switch on caches for the 'main' memory.

Generally, don't have expectation from software performing any task at timely manner down to a few cycle precision. Use as much hardware as possible - toggling a pin is the timer's task, for example.

JW

Posted on March 03, 2018 at 11:36

 ,

 ,

Thanks for reply.

I have try as your suggestion,optimization for speed level-3, put the code in the TCM, enable cache, and so on. But I get the same result ,the GPIO toggled still , at 16.7MHz wave.

I also check the disassembled code ,, like these. That is just one instructions to do it. ,

 ,  ,STR ,  ,  ,  ,  ,  ,r5,[r0, ♯ 0x00]

 ,  ,STR ,  ,  ,  ,  ,  ,r4,[r0, ♯ 0x00]

 ,  ,STR ,  ,  ,  ,  ,  ,r5,[r0, ♯ 0x00]

 ,  ,STR ,  ,  ,  ,  ,  ,r4,[r0, ♯ 0x00]

I think the problem may not the speed of the code be executed. The core run the code at 400MHz is right.

It looks more like than that's something wrong with the GPIO ,periphery‘s clock do not ,reach 200MHz.

I found the AHB4 is ,

the GPIO ,

periphery‘s , bus , at ,

the datasheet page 17 (Figure 1. STM32H743xI block diagram ).

And the clock for AHB4 is configed to 200MHz as the source code I posted , before.

Is that something I miss to configed the

GPIO ,

periphery‘s clock?

Posted on March 03, 2018 at 23:39

This then may simply be the system limitation.

Note, that this is not a microcontroller, this is a SoC, and a highly complex one. The write from processor goes through its AXIM interface to the AXI bus matrix; from that to an AXI-to-AHB bridge, then to the D3 AHB matrix, and from there to AHB4 itself. All these may impose an arbitration which may take up cycles. Most of this is publicly undocumented or documentation buried deeply in ARM's documents; and even if you'd have all that, it may be non-trivial to deduce the exact timing for any particular situation.

Loss of control over precise timing is the price you pay for overall speed.

JW

Posted on March 08, 2018 at 01:00

Yes.As what you said , I think that may be cause by the complex bus matrices  must consume many clock's to transfer and synchronize  the data.  Thanks  you.