cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 High Speed GPIO (Internal Clock) can't get 42Mhz

zhanwey
Associate II
Posted on May 18, 2016 at 17:52

Hi,

I can't get the GPIO into high speed as stated in data sheet 42Mhz with the following code even I already set the clock to Max based on Internal clock:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitDef.GPIO_Pin = GPIO_Pin_2;

GPIO_InitDef.GPIO_OType = GPIO_OType_PP;

GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;

//initialisation port B pins

GPIO_Init(GPIOA, &GPIO_InitDef);

while(1)

{

GPIOB->BSRRL = GPIO_Pin_2;

GPIOB->BSRRH = GPIO_Pin_2;

}

When I hooked the pin to the

oscilloscope it only 

show

14Mhz

, is the instruction cycle too slow to achieve 42Mhz or is the GPIO characteristic issue (rising and falling time)?

Clock setting is based on following  SetSysClockInternal() function, 

Clock parameters setting:

static void SetSysClockInternal(void)

{

// HSI_RC = 16Mhz

// SYSCLK = 168Mhz

// HCLK = 168Mhz

// APB1 peripheral = 42Mhz

// APB1 timer = 84Mhz

// APB2 peripheral = 84Mhz

// APB2 timer = 168Mhz

__IO uint32_t HSIStatus = 0;

/* Enable HSI */

RCC->CR |= ((uint32_t)RCC_CR_HSION);

/* Wait till HSI is ready and if Time out is reached exit */

do

{

HSIStatus = RCC->CR & RCC_CR_HSIRDY;

} while(HSIStatus == 0);

/* Select regulator voltage output Scale 1 mode, System frequency up to 168 MHz */

RCC->APB1ENR |= RCC_APB1ENR_PWREN;

PWR->CR |= PWR_CR_VOS;

/* HCLK = SYSCLK / 1*/

RCC->CFGR |= RCC_CFGR_HPRE_DIV1;

/* PCLK2 = HCLK / 2*/

RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;

/* PCLK1 = HCLK / 4*/

RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;

/* Configure the main PLL */

RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) |

  (RCC_PLLCFGR_PLLSRC_HSI) | (PLL_Q << 24);

/* Enable the main PLL */

RCC->CR |= RCC_CR_PLLON;

/* Wait till the main PLL is ready */

while((RCC->CR & RCC_CR_PLLRDY) == 0)

{

}

/* Configure Flash prefetch, Instruction cache, Data cache and wait state */

FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;

/* Select the main PLL as system clock source */

RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));

RCC->CFGR |= RCC_CFGR_SW_PLL;

/* Wait till the main PLL is used as system clock source */

while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);

{

}

}

regards,

David

#stm32 #internal-clock #gpio
5 REPLIES 5
Walid FTITI_O
Senior II
Posted on May 18, 2016 at 18:27

Hi david.zhanwey, 

You are configuring GPIOA and toggling the GPIOB !?

-Hannibal-

Posted on May 18, 2016 at 18:51

But what does that actually assemble to? Do you have optimization on? Which compiler?

This whole thing has been discussed here previously, and I'm pretty sure I can get that number well north of 14 MHz if coded efficiently.

This is a poor strategy to get high speed signalling, suggest if you want 42 MHz, use a timer.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
zhanwey
Associate II
Posted on May 19, 2016 at 03:32

Hi Hannibal,

Thank for your reply.

Sorry for the mistake, I am configuring GPIOA and toggling GPIOA.

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

GPIO_InitDef.GPIO_Pin = GPIO_Pin_2;

GPIO_InitDef.GPIO_OType = GPIO_OType_PP;

GPIO_InitDef.GPIO_Mode = GPIO_Mode_OUT;

GPIO_InitDef.GPIO_PuPd = GPIO_PuPd_NOPULL;

GPIO_InitDef.GPIO_Speed = GPIO_Speed_100MHz;

//initialisation port B pins

GPIO_Init(GPIOA, &GPIO_InitDef);

while(1)

{

GPIOA->BSRRL = GPIO_Pin_2;

GPIOA->BSRRH = GPIO_Pin_2;

}

regards,

ZW Siew

zhanwey
Associate II
Posted on May 19, 2016 at 03:37

Hi clive1,

I am using CoIDE with optimizate Most (-O3).

My intention is to test the toggling speed as fast as possible, timer interrupt handle will waste some instruction cycles. That why I put it into main loop.

thank,

regards,

ZW Siew

megahercas6
Senior
Posted on May 20, 2016 at 07:08

Not all compilers are equal.

When i started to play with MCU, i was using atolic, it was just horrible even with best optimization. Tests showed me ( gpio toggling and math) that IAR ARM same code make  as much as 20x faster, with atolic i was never get more than fev MHz toggling, while with IAR ARM i always get sysclk/2