STM32F412 clock configuration

I’ve produced a custom board with the STM32F412 which is running ok, but looking at the generic implementation, this uses the internal oscillator. From reading the thread below, it seems that all I should need to do to change this configuration is to place a cpp file in my project with the SystemClock_Config function, and this should now be used…

I’ve used the STM utility to configure the clock with my external 8MHz HSE oscillator, but it doesn’t appear that the clock configuration is changing. I’ve just implemented a flashing LED at a specific rate using the delay function, and I would expect that if I change the PLL divider, the speed of my LED (and probably my serial debug) should change - but it doesn’t.

Below is the cpp file I’ve dropped in my project, and you can see where I’ve tried changing the PLL value by a factor of ~2 - simply to try and confirm this is being executed. The 192 should give me the 100MHz clock, and dropping this to 100, I’d expect to slow everything down by a factor of 2…

#include "pins_arduino.h"

void SystemClock_Config(void)
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Configure the main internal regulator output voltage

    /** 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_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 8;
    RCC_OscInitStruct.PLL.PLLN = 100; // 192
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 2;
    RCC_OscInitStruct.PLL.PLLR = 2;
    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

    /** Initializes the CPU, AHB and APB buses clocks
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

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

However using the PIO debugger, it does seem that this function is being executed, so I’m at a loss to understand why the LED doesn’t change frequency. Or is there some other “magic” at play that can work out the clock rate and change the timer used for the delay and serial speed etc?

I’d welcome any pointers on this that would help me understand what’s happening under the hood…


Even though your SystemClock_Config() function may be executed and setup the correct PLL parameters, if the STM32 HAL / system function for getting the current clock speed (SystemCoreClockUpdate()) returns the wrong value (e.g., because the macro HSE_VALUE is set incorrectly), as happened e.g. here, you will still end up with the wrong speed.

Can you post your exact project files, e.g. as a github repo?