How to properly set clock speed for STM32F4xx devices

I see that you have problems with your devices when you don’t know even (and you don’t even ask) on which speed your device is actually running. Speed of your device depends on PLL settings or clock source you have selected for system core clock.

In most cases system core clock’s source is PLL output. To get proper value, you check ALWAYS first these settings when something is not working. Because I’m tired of questions that something is not working but then your MCU clock is totally failed.

STM32F4xx series MCUs have ALL 16MHz RC oscillator inside which can be used for PLL input clock. It is not so accurate but it works just well if you don’t have connected external clock.

External clock is probably your crystal you have connected. In this example we will talk in case that you have external crystal connected.

If your clock is not properly set, then you have problems with everything. USB not working, USART baudrate failed, timer’s clock not OK…

This content has only sense, if you use Standard Peripheral Drivers and not HAL drivers from ST!

To be able to get your MCU to full speed, you have to do the following changes:

  • In file stm32F4xx.h set HSE_VALUE to match your crystal frequency (In Hz)
    • In case of any STM32F4xx Discovery board, select HSE_VALUE = 8000000
    • In other case, you can set this to your crystal
    • If you have an option for global defines in your compiler, then add HSE_VALUE=8000000 to your defines.
    • If you don’t use external crystal or clock, then you don’t need to change anything
  • In file system_stm32f4xx.c set PLL_M value to match your crystal frequency (In MHz)
    • In case of any STM32F4xx Discovery board, select PLL_M = 8
    • This will divide input clock with 8 to get 1MHz on the input for PLL
    • If you don’t use external clock, then this value MUST be set to 16, because internal RC will be used for PLL
  • Now you can expect top speed for your device.

Some informations about Nucleo boards:

  • Nucleo boards don’t use external clock by default, but they have pins for adding external crystal.
  • In case you don’t add external crystal or clock, then set PLL_M value to 16
  • I have at home set F401 Nucleo board with external crystal 8MHz (so PLL_M is set to 8 and HSE_VALUE set to 8000000) and F411 without external crystal (PLL_M set to 16)

STM32F4xx Clocks

Proper PLL settings to get maximum clocks (except of PLL_M parameter everything should be already defined in system_stm32f4xx.c file).

SystemCoreClock = ((INPUT_CLOCK (HSE_OR_HSI_IN_HZ) / PLL_M) * PLL_N) / PLL_P

STM32F4xx MAX CLOCK in MHz APB1 CLOCK in MHz APB2 CLOCK in MHz PLL_M PLL_N PLL_P
STM32F401 84 42 84 Must match input frequency in MHz (HSE or HSI) 336 4
STM32F411 100 50 100 Must match input frequency in MHz (HSE or HSI) 400 4
STM32F405 168 42 84 Must match input frequency in MHz (HSE or HSI) 336 2
STM32F407 168 42 84 Must match input frequency in MHz (HSE or HSI) 336 2
STM32F415 168 42 84 Must match input frequency in MHz (HSE or HSI) 336 2
STM32F417 168 42 84 Must match input frequency in MHz (HSE or HSI) 336 2
STM32F427 180 45 90 Must match input frequency in MHz (HSE or HSI) 360 2
STM32F429 180 45 90 Must match input frequency in MHz (HSE or HSI) 360 2
STM32F437 180 45 90 Must match input frequency in MHz (HSE or HSI) 360 2
STM32F439 180 45 90 Must match input frequency in MHz (HSE or HSI) 360 2
STM32F446 180 45 90 Must match input frequency in MHz (HSE or HSI) 360 2

Settings for STM32F4xx boards

This settings should be used in case of any STM32F4xx boards used.

STM32F4xx MAX CLOCK in MHz APB1 CLOCK in MHz APB2 CLOCK in MHz DEFAULT PLL INPUT CLOCK PLL_M PLL_N PLL_P
STM32F401-Discovery 84 42 84 HSE 8MHz 8 336 4
STM32F411-Discovery 100 50 100 HSE 8MHz 8 400 4
STM32F4-Discovery 168 42 84 HSE 8MHz 8 336 2
STM32F429-Discovery 180 45 90 HSE 8MHz 8 360 2
Nucleo F401 84 42 84 HSI 16MHz HSE_VALUE / 1MHz in case of external crystal or 16 in case of internal HSI RC oscillator 336 4
Nucleo F411 100 50 100 HSI 16MHz HSE_VALUE / 1MHz in case of external crystal or 16 in case of internal HSI RC oscillator 400 4

 

tilz0R

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!
  • Onur Akgün

    Hi Majerle,

    That’s a great topic. Thanks for sharing.

    I could change PLL_M value in stm32f4xx.h

    #define RCC_PLLCFGR_PLLM ((uint32_t)0x00000008)

    In order to change PLL_N value should I change the value below?

    #define RCC_PLLCFGR_PLLN ((uint32_t)0x00007FC0)

    There is same thing in PLL_P value, too

    #define RCC_PLLCFGR_PLLP ((uint32_t)0x00030000)

    • You use HAL drivers? This article is for STD periph drivers.

      • Onur Akgün

        I’m afraid I don’t know the answer

        • system_stm32f4xx.c is a file where you change PLL parameters. So if you don’t do it in this file, you are not using std drivers.

          • Onur Akgün

            Thank you so much, my friend. I thought I had to change the values in stm32f4xx.h file. No problem, now

  • Pingback: Library 59- Change PLL settings while STM32F4xx is running - STM32F4 Discovery()

  • Pingback: Programming an ARM-processor (II) | erossel()

  • TheBreMar

    Hi, why you say that the HSI is 16 MHz where in datasheet for the stm32f411 states that the HSI is 8MHz? I am definitely missing something. Thank you for the answer in advance.

    • Show me that please. On every F411 I see HSI 16MHz.

      • TheBreMar

        My mistake, I was watching STM32F303xB STM32F303xC all the time. Exhaustion was the source of my faulty reading. You can delete my thread since it is completely irrelevant. Good job on the post!
        Best regards!

  • wind fan

    Hi Majerle,

    I am being trapped by the PLL for a long time. I use a NUCLEO evaluation board with STM32F446RE chip. But when I set system clock above 130MHz, the chip just didn’t work.

    The program I ran in while(1) loop was just “a = b + c;” and a toggling LED was used to indicate whether the program was running. The system clock configuration code was pulled from STM32CubeMX. Everything went well with a system clock under 130MHz, however, any frequency above that, program died. The STM32F446 manual says the system clock can go up to 180MHz. Do you happen to know why it was like that?

    Thanks,
    Fan

    • There is an option for flash latency and pwr scale mode. Did you set this? Scale should be 1.

      • wind fan

        It works! Thank you so much Majerle! I increased the flash latency to 4WS and did not touch power scale. Then everything was OK. Should I also set power scale just in case?

        • Power scale must be set to scale1 in order to achieve 130+ MHz.
          If it works, then it is already set.

          • wind fan

            Thanks, dude. Yea, probably I should write power scale configuration in the code, making it visible, although it works without touching power scale register.

  • Christian Julius

    Hi Genius 🙂
    Is it possible to provide a libary which can set different speeds for the core and AHB bus? I often want to reduce power consumption by doenclocking the device when in idle mode. That would be usedful, I think. But the clocking is somewhat more complex than in the AVR or PICs.
    Regards,
    Christian

    • I give you another change to look at libraries list and check if any lib is for you here.

      • Christian Julius

        Err… I dont understand what you mean. I checked th libs. The only thing is to add pre calculated functions setting proper speeds for core and peripherals. Maybe 168 Mhz, 84 Mhz, 42 Mhz and so on. Every time the core is in idle mode, (while loop), it speeds down and if it leaves in sub routine, it speeds up again. Hope that this is possible. It seems that I am too silly to calculate the parameters for the PLL.

        • You should know that:
          If you change PLL clock, then you also have to change prescalers for peripherals (reinit again), and changind PLL parameters also takes some time.

          Add precalculated functions. These function could call my TM_PLL function from RCC library.
          It is VERY easy to calculate. Just find my other posts about explanation.

          • Christian Julius

            Ok, the calcultion tool is very simple. I will try to modify core clock while keeping the peripheral and bus clock stable.

          • Your tool must consider that you need for usb for example always the same clock.

  • Talha Zia

    i have STM32F401VC I have changed the values to HSE_VALUE=8000000 an PLL_M=8 but now its encountring hard fault error in debugger .

  • Toni

    Good morning! I have a problem with stm32f446 nucleo, i’ve just soldered the X3 (8MHz), the caps and res to the board (20pF the caps and 220 and 0 ohms the res, I chose this values because of the HSE of the f4discovery is configured so), and changed the SB connections. The problem is that if I configure the system clock (using the HSE as clock source) it works perfectly at 84MHz, but if I only change the RCC_PLLP_DIV4 to RCC_PLLP_DIV2 (to achieve 168MHz) it doesn’t work. What can it be?
    Thank you very much,
    Toni

    • All settings please.

      • Toni

        Hardware:
        -SB54/55/16/50 off
        -R35 0 and R37 220 ohm
        -C33/34 20pF
        -X3 8.000s3z
        Software (Clock config):
        http://pastebin.com/EA6qtgDP
        After some research i’ve detected that the problem is appearing in the systick part, because if I use a Timer as a time source base it works at 168Mhz . I don’t understand why..

        Thanks Tilen!

        Toni

        • Pllq is set to 2 why? Should be at least 7.

          • toni

            You’re right, I was making some changes in order to see if the code worked and I forgot to put back pllq correctly.
            http://pastebin.com/nVtawUWe
            I set it right but still don’t working.

            Thanks,
            Toni

          • toni

            Hi again, I was reading other posts and you’ve already solved this problem to other person! I tried changing the flash latency to 4 and it works at 168Mhz! I’ve never changed this register and didn’t know what it is for. Sorry about wasting your time and thanks for the help!

            Toni

          • divum

            Hi Tilen,
            Is it possible to use more than one SystemClock_Configurations in one file?

          • They are in one file already.

          • divum

            thanks for rply tilen…
            Is it question or Answer?

          • Does it have question mark? :))

          • divum

            No..but your rply comments too funny..so..

          • Why is it funny? If clock config is already in separate file, why would be funny? And you didnt specify HAL or STD you use.

  • vanaja

    Hi Tilen,

    I am using internal RC osc for STM32F407vg(my own board) in my project and need to achieve 115200 baud rate for UART. Using std peripheral lib.
    I have changed only PLL_M to 16 as you said. Able to receive and transmit for baud rates less than 115200. For 115200 garbage data is being received.
    Could you tell me how to make it work.

    • How you send and transmit data to MCU?
      Try to use transmit from MCU to USB->UART for start to see how it sends.

      Configuration looks ok to me. Make sure you don’t have external crystal connected to pins for it.

      • vanaja

        Just using PC serial terminal to transmit and receive data.
        I am sure that there is no external crystal on my board.

  • Yassine

    Hi , I intend to set my STM32F4 Discovery board with the 8MHz external clock HSE
    here is the code:
    RCC_DeInit();
    RCC_HSEConfig(RCC_HSE_ON);
    hseState = RCC_WaitForHSEStartUp();

    but RCC_WaitForHSEStartUp always returns ERROR
    any help please

    • Does all the settings match for PLL?
      Another option is that external clock does not work.

      • Yassine

        Thank you for responding,
        Actually i have recently bought the evaluation board. It’s new. And for the PLL settings in my code , it match and won’t be executed unless the mentioned fuction has returned SUCCESS. But i read in a forum that stm32 eval board doesn’t have any external clock, is that true ?

        • By actually reading post, you would see if it has internal or external source clock!

          • Yassine

            I just wanted to make sure that’s it

  • Mario Toma

    Hi Majerle,

    I downloaded the STM32Fxxx libraries have to operate a module of a ESP8266-01 with STM32F746G-DISCO board. But when I start the program and call the Init function (ESP8266_Init) then return “Device not connected” result.
    I connected the module D0 and D1 pin to the arduino device (PC6 and PC7). I’m using Pinspack 1 (USART6). I connected the ESP8266 reset pin to A0 pin (PA0), because I saw in your library that you use it for reset.

    Do you have any idea what is the problem? Did I connected incorrectly
    something?

    Thank you in advance for your help!

    Hi good day!

    Mario

  • Mario Toma

    Hi Majerle,

    I downloaded the STM32Fxxx libraries have to operate a module of a ESP8266-01 with STM32F746G-DISCO board. But when I start the program and call the Init function (ESP8266_Init) then return “Device not connected” result.

    I connected the module D0 and D1 pin to the arduino device (PC6 and PC7). I’m using Pinpack 1 (USART6). I connected the ESP8266 reset pin to A0 pin (PA0), because I saw in your library that you use it for reset.

    Do you have any idea what is the problem? Did I connected incorrectly
    something?

    Thank you in advance for your help!

    Hi good day!

    Mario

  • Dimas Setiaji

    i have STM32F407VG i want to replace external xTal(8MHz) to new XTal 168 MHz (Max reff datasheet).. for it maximum Speed.
    please kindly to give me the setting/config, so the main code would run also in maximum Speed…….

    • You want to change XTAL from 8MHz to 168MHz? why would you do that?
      PLL is here for you to increase frequency from 8MHz to 168.
      Configuration is above.

      • Dimas Setiaji

        so, can’t do any faster then?

      • Dimas Setiaji

        so, can’t do any faster then?
        thank for your answer, sir. you the best.

        • I dont understand yoir needs. External xtal can be 4-26MHz,any value between.
          Then there is PLL which increases that clock to max for processor, in you case 168MHz.

          • Dimas Setiaji

            well, actually that was the exact answer i looking for. you just explain it to me.
            now i know my chip limit. base on your answer.
            Thank you very much Sir.

          • Dimas Setiaji

            well, actually that was the exact answer i looking for. you just explain it to me.
            no matter External Xtal (between 4-26MHz), as long as PLL reach max.168MHz(base on datasheet.)
            so datasheet talk about PLL, not about XTal then.
            .
            now i know my chip limit. base on your answer.
            Thank you very much Sir.
            .
            btw. im trying to build simple bare bone fastest oscilloscope, logic analyser and wave generator using Stm32F407, sir.

  • RusikOk

    how to check the clock went to our initialization of the battery or not? so as not to expose them at every turn it on

    • I’m not sure I know what you wanna ask actually. Can you repeat more clearly?