I have started to play with PlatformIO and have a working blinking LED in two projects, one with HAL, another with libopencm3.
Both of them use this to blink (so clock changes would be visible):
…
while(true) {
gpio_toggle(LEDPORT, LEDPIN); //Using API function gpio_toggle()
for (i = 0; i<1000000; i++) asm(“nop”);
}
None of the projects sets the clock explicitly in main.c or elswhere. So I have tried to edit platform.ini:
board_build.f_cpu = 18000000L
build_flags = -D HSE_VALUE=12000000U
build_flags = -D SYS_CLOCK=12000000L
None of these settings changed the blinking frequency.
Is it possible to change the clock (PLL, divider, …) in HAL or libopencm3 projects? What am I doing wrong?
Thanks
works as initialisation using HAL manually (without using STM32CubeMX).
I was falsely thinking that PlatformIO configures the chip on it own, because of existing .ini flags.
Utilizing and Verifying System Clock Configuration on STM32
Here’s how to set up and verify the system clock configuration for an STM32 microcontroller, such as the Blue Pill, using an external 8 MHz crystal to run the MCU at 72 MHz.
#include "stm32f1xx_hal.h"
void Error_Handler(void)
{
// Infinite loop as an error indicator
while (1) {
// You can add additional error handling here
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
// Configure the HSE oscillator and activate PLL with desired settings
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.PLLMUL = RCC_PLL_MUL9; // 72 MHz
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
Error_Handler();
}
// Configure clocks for CPU, AHB, and APB buses
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_DIV2; // Max 36 MHz for APB1
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) {
Error_Handler();
}
// Ensure the Flash latency is correct
__HAL_FLASH_SET_LATENCY(FLASH_LATENCY_2);
}
Step 2: Use in main.cpp
main.cpp:
#include "ClockConfig.h"
void setup() {
HAL_Init(); // Initialize the HAL Library
SystemClock_Config(); // Configure the system clock
// Verify clock frequencies using HAL functions
uint32_t sysClkFreq = HAL_RCC_GetSysClockFreq();
uint32_t hClkFreq = HAL_RCC_GetHCLKFreq();
uint32_t pClk1Freq = HAL_RCC_GetPCLK1Freq();
uint32_t pClk2Freq = HAL_RCC_GetPCLK2Freq();
// Variables for debugging and verification
volatile uint32_t debugSysClkFreq = sysClkFreq;
volatile uint32_t debugHClkFreq = hClkFreq;
volatile uint32_t debugPClk1Freq = pClk1Freq;
volatile uint32_t debugPClk2Freq = pClk2Freq;
// Place breakpoints here to verify the values
}
void loop() {
// Your main loop code
}
Step 3: Verifying Clock Speed
Debugging:
Set breakpoints on the lines where debugSysClkFreq, debugHClkFreq, debugPClk1Freq, and debugPClk2Freq are assigned.
Use a debugger to inspect the values and verify that sysClkFreq equals 72 MHz, hClkFreq equals 72 MHz, pClk1Freq equals 36 MHz, and pClk2Freq equals 72 MHz.
Post Verification:
Ensure code consistency and verify hardware connections if values do not match expected results. Check oscillator and clock settings in the configuration files.
This setup ensures your STM32 is configured to run at its maximum frequency with an external crystal and provides a reliable method to verify that…