STM32F407VET6 external oscillator configuration

Hello,

I am currently designing a new board for my project after testing it on a development board.
My question is regarding the oscillator configuration…

The MCU is a STM32F407VET6, Board settings: “black_f407vg”
Originally this board uses an 8 MHz HSE and 32.768 kHz LSE.

Due to better availability, I want to use a 16MHz HSE and 32.768 kHz LSE.

Where can I find and change this settings?

By using this board you the relevant file is variant_BLACK_F407VX.cpp, where it sets the PLL multipliers for the HSE. You can see that the SystemClock_Config() function that does this is WEAK. So, in your project code, say e.g. src\main.cpp, you can just place a non-weak version of this function where you have the correct PLL settings.

By using STM32CubeMX…

it is apparent that the only thing that changes from thet original code is the PLLN value from 336 to 168, aka half of it (because crystal frequency is doubled). So placing

extern "C" void SystemClock_Config(void)
{

  RCC_OscInitTypeDef RCC_OscInitStruct = {};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {};

  /**Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();

  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

  /**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 = 8;
  RCC_OscInitStruct.PLL.PLLN = 168;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 7;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
    Error_Handler();
  }

  /**Initializes the CPU, AHB and APB busses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
                                | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) {
    Error_Handler();
  }

  /* Ensure CCM RAM clock is enabled */
  __HAL_RCC_CCMDATARAMEN_CLK_ENABLE();

}

in your project’s code (in a .cpp file) should suffice.

(Above function is also verifyable or constructable by just letting STM32CubeMX generate the project code once RCC HSE + USB has been configured. It generates exactly the code above in main.c.)

Sadly that’s not nicely macro-controllable to just change some multiplier, the entire function has to be given.

This function does not do LSE / RTC initialization. That is done by separate libraries, namely https://github.com/stm32duino/STM32RTC, which allows you to select the clock source.

If you don’t like the idea of having that function in your source code, you can also create a new STM32Duino variant for your specific board. Then you can e.g. clone the Black 407VX (V and E are treated the same) variant files, fix that one multiplier, and then refer to your newly created variant. An example for that is at GitHub - maxgerhardt/pio-custom-stm32duino-variants: A short example of how to use a custom variant folder for the PlatformIO + STM32Duino environment.

1 Like