Overclock STM32F4 device up to 250MHz

Let’s test what STM32F4xx devices can do. I have all “4 speed families” at home so why not to try it how fast we can go. By default, for those who don’t know max frequencies for STM32F4xx devices, they are in list below:

  • 84MHz: STM32F401 MCUs, including Nucleo-F401 board
  • 100MHz: STM32F411 MCUs, including Nucleo F411 board
  • 168MHz: STM32F405/7 and STM32F415/17 MCUs, including STM32F4-Discovery board
  • 180MHz: STM32F427/29 and STM32F437/39 MCUs, including STM32F429-Discovery board

Ok, we have everything provided, let’s test how far we can go with PLL settings. First we have to go through, how to set PLL parameters to even get any clock. Step by step on how PLL works.

About PLL settings

  1. You gave him some input frequency, let’s say HSE_VALUE = 8MHz. Then, he divide this by PLL_M factor, that we get 1MHz in the first stage output. This means
  2. Then, PLL multiplies output (1MHz) with a large number, factor is called PLL_N. This number depends on STM32F4xx family. By default, for normal clocks (specified in datasheet) values are:
    1. 84MHz: PLL_N = 336
    2. 100MHz: PLL_N = 400
    3. 168MHz: PLL_N = 336
    4. 180MHz: PLL_N = 360

    Probably your question is why so strange values. Simple answer, STM32F4xx have different peripherals (SDIO, USB, etc) and some specific peripherals needs exact clock. If you want to have 168MHz core clock and then for USB 48MHz, this is not possible, because you cannot set a prescaler of 168/48 = 3.5. This is “no go”. For that purpose, least common value for (in this case) 168MHz and 48MHz is used, 336.

    Note: PLL_N parameter can be set between 192 and 432. At least datasheet says that but we will see that we can go more that this.

  3. Ok, we have 336MHz somewhere inside PLL now. Now become 2 new PLL parameters.
    1. PLL_P: This parameter is used to set system core clock for MCU. If you want 168MHz clock, and you have 336MHz on the input of this divider, you set parameter PLL_P = 2. Equation is

      1. 84MHz: PLL_P = 4
      2. 100MHz: PLL_P = 4
      3. 168MHz: PLL_P = 2
      4. 180MHz: PLL_P = 2
    2. PLL_Q: This parameter is used to set clock for special peripheral (SDIO, USB, RNG) to be at least about 48MHz. But this is not always possible. It divides the input frequency for special peripherals like PLL_P does for system core clock.

      By default this parameter is set to 7. If we take a look at what happens if we have 180MHz clock and PLL_N set to 360, the our PLL_VCO is 360MHz and our “48MHz” clock becomes:

      It’s not a big problem but yeah, if we want perfect, then if we use USB/SDIO/RNG we can not have 180MHz for our MCU. We have to slow it down to 168MHz by setting PLL_N to 336. Someone will probably say that we can increase PLL_N to 384 and then PLL_Q to 8 and we will get

      This is true, but if we set PLL_N to 384, then on divide by 2 for PLL_P we have higher frequency than 180MHz for Core clock (384MHz / 2 = 192MHz) and this is not good now. Terrible 😀 If you have 100MHz core clock, then you have PLL_N set to 400 and PLL_Q to 7, wow, that more than 55MHz for peripheral, not good at all. Even PLL_Q = 8 is too small. You need then about 8.3 prescaler but floating points in prescalers = no go.
  4. If we now make a full equatons for system core clock, we will get something like this:
  5. All these settings are set in system_stm32f4xx.c file if you use Standard Peripheral Drivers like I do.

Overclocking STM32F4xx device

To test how far I can go, I used my PWM library hich automatically sets timer period and prescaler according to the timer’s frequency and pwm frequency you choose. This values are stored in my working struct for PWM library. I used this PWM output to measure actual frequency with oscilloscope.

First, I tried overclock STM32F429-Discovery board. For first test, it was just good if I set PLL_N to higher value. I set it to PLL_N = 400, and if we calculate this, we will get SYSCLK = 200MHz. This is more than 180MHz so we can expect any problems. I’ve also set variable

to be sure my settings are OK in file. Then I’ve started my program in debug mode and set timer settings and PWM output. I’ve measured real 10kHz PWM output like I set. I was still not sure if this is ok. In debug window, you can look at variables. Like I previously said, my PWM struct stores information about timer prescaler and period. I read from debug windows values below:

  • Period: 10000
    • Absolute value how much ticks timer has to make. Value stored in TIM’s register is Period – 1
  • Prescaler: 1
    • Absolute value to use with calculations. Value stored in TIM’s register is Prescaler – 1

It was strange for me first time, because this was not so nice result. Then I realized, that TIM2 for PWM is connected to APB1 bus, which clock frequency is on F429 APB1 = SYSCLK / 4 but TIM has internal PLL which increases frequency by 2, so you get TIM2_TICK_DEFAULT = SYSCLK / 4 * 2 = SYSCLK / 2 = 100MHz.

This result is better now. because you get:

So I was doing this a lot of times, trying different frequencies. To 250MHz on STM32F429-Discovery I got frequency on my oscilloscope 10kHz and parameters for timer were valid. So clock was really 250MHz.

For other boards, I got maximum clocks of:

  • STM32F429-Discovery; 250MHz
    • APB1 = SYSCLK / 4; TIM2 default frequency = SYSCLK / 4 * 2 = 125MHz
  • STM32F4-Discovery: 250MHz
    • APB1 = SYSCLK / 4; TIM2 default frequency = SYSCLK / 4 * 2 = 125MHz
  • Nucleo F401: 125MHz
    • APB1 = SYSCLK / 2; TIM2 default frequency = SYSCLK / 2 * 2 = 125MHz
  • Nucleo F411: 125MHz
    • APB1 = SYSCLK / 2; TIM2 default frequency = SYSCLK / 2 * 2 = 125MHz

Important notes:

  • There is no guarantee that every MCU in the series will go to the value like my did, because they are not designed for so high speed,
    • I do not suggest you that you use this in production
  • When frequency is higher than expected, MCU can become unstable and can crash or some hardfault error can happen,
    • Also, temperature rises with frequency.
  • You can blow your MCU
    • I’m not responsible for that. You are doing this on your own risk.

PLL Settings

These settings are set in system_stm32f4xx.c file


Main program

Project below has settings in system_stm32f4xx.c set to maximum frequency like I said above, so 250 and 125MHz. Before you debug in Keil uVision, you have to rebuild. All libs are included in project.

STM32F4 Overclocking


Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • clive1

    Might save yourself a lot of typing and angst with

    #if defined (PLL_SOURCE_HSI)
    uint32_t SystemCoreClock = (((HSI_VALUE / PLL_M )* PLL_N) / PLL_P);
    uint32_t SystemCoreClock = (((HSE_VALUE / PLL_M )* PLL_N) / PLL_P);

    You can run USB at non-48MHz speeds if you use an external PHY. Why ST didn’t push to 192 MHz instead of 180 MHz, who knows, probably a critical path in the ART over voltage and temperature.

    The SDIO peripheral needs the PLL running to function. And is functional to 75 MHz, giving a bus speed of 37.5 MHz as the BYPASS options is broken.

    This Disqus dialog keeps locking up in a bloody annoying fashion.

    • Hi clive.
      I know you from ST’s forum 😛
      Well, you can tell ST’s programmers that they implement this in STD periph drivers.

      I wanna be exact so that’s the reason why I’m posting this in that way.
      Btw: thanks for posting all this.

  • clive1

    “TIM has internal PLL which increases frequency by 2”

    Not exactly, it takes the clock from the divider chain one stage earlier in all but the DIV1 case, so in most cases you get the equivalent to APBCLK*2

    • Correct, I’m telling here settings i’ve made, and i’ve chose DIV_1.

  • olin

    Hi, thanks for the explanation. Just one note about the code snippet: with PLL_Q set to 7 my OTG USB didn’t work at core clock 250MHz. I had to change it to value 10 to make it work again.

    • Correct, you need 48mhz for that 🙂

      • olin

        True, int that case it’s probably better to go slighly slower at 240MHz core clock as it scales down exactly to 48MHz for USB. Thanks for pointing that out.

        • No problem at all, but I don’t suggest you that you use overclocked device in production. Ok, maybe to about 200MHz it is ok, but not 240-250.

          You might get serious problems 🙂

          • olin

            No worries, it’s just my hobby project. Anyway, after running it at 240 MHz for several hours the processor is quite cool – and I mean it’s not even warm (ambient temp 22 deg. C).

  • Janos Papp

    Until this time I did not called the so called Systeminit() function. Now I set up some frequencies for the clocks with the help of the clock_configuration xls.
    I would like to know what are the default settings for these clocks and prescalers, to be able to compare both setups.
    Thanks for your further answer!

    • Hi,

      When I first started with F4, I didnt kbow that systeminit function is already called from startup file and is not needed in main again. But then i leave as it is and I use this always by calling this function manually again.

      Prescalers depends of your device.
      84 and 100MHz devices have prescalers for abp2 and apb1 set to 1 and 2.

      180 and 168MHz devices have this set to 2 and 4.

      Please explain more which prescaler exactly you wanna know 🙂

    • Deniz Can Çığşar

      Prescalers depends on the frequency limits of the busses.. The limits are defined in RCC_CFGR registers parge.. ST’s documentation is really a mess.

  • jmfriedt

    I can confirm that a STM32F410RBT6 is working fine (apparently: timer, SPI, USART and ADC) when clocked internally at 134.4 MHz when an external 20 MHz quartz resonator is used.

  • Dimas Setiaji

    Man…. Thats Amazing..

  • Deniz Can Çığşar

    You may output predivided clock on MCO2 by the way.. If you divide by 5, you would get 50MHz on that pin.. I tested for 42MHz output and the pin drive was powerful enough to see the clock..

  • argonath cirith

    Then a long search on google and some attempts to overclock a stm32f7 with external sdram above 240 mhz of sysclock, I landed here because I able to reach frequencies like 288 mhz hclk, but sdram (micron 120mhz max sdclk) is stop working.

    I asking me if you have faced this problem when you overclocked stm32f429 disco board.
    I tried maintain sdram timing with values proportional to new frequency, fundamentally I change sdclk divider to one third of hclk in FMC_SDCR1, but nothing.

    • 100MHz is maximum sdram clock on F7 device.

      • argonath cirith

        The question is if you had been using lcd panel on stm32f429disco when you overclocked it to 250mhz, because 250/2 = 125mhz > 100mhz of sdram clk. If afirmative, what changes are you made to sdram parameters to achieve that.
        My objective is overclock core freq while maintaining sdram freq at 100mhz.

        • I didnt. It was just overclock test and ST dont guarantee it will work.