1. Topic
STM32 clock tree: HSI/HSE, PLL, SYSCLK, HCLK, APB1/APB2, kernel clocks, prescalers and actual peripheral frequencies. Main idea: without knowing a peripheral clock, you cannot understand its actual behavior.
2. Why this matters in a project
The clock tree affects UART/RS-485 baud rate, CAN/FDCAN bit timing, ADC sampling time, TIM/PWM period, input capture timestamps, HIL timing and watchdog timeout.
3. Theory
Clock tree:
HSI/HSE/PLL -> SYSCLK -> AHB -> HCLK -> APB1/APB2 -> PCLKx -> peripheralsClock sources:
- HSI is an internal RC oscillator: convenient, but less accurate.
- HSE is an external crystal/clock, preferred for CAN/USB/accurate UART timing.
- LSI/LSE are low-frequency sources used for watchdogs and RTC.
Timer formulas:
timer_counter_freq = TIMxCLK / (PSC + 1)
update_freq = timer_counter_freq / (ARR + 1)A common STM32 trap: when the APB prescaler > 1, TIMxCLK is often 2 * PCLKx. Consult the reference manual for the exact series. UART baud rate is derived from a peripheral/kernel clock. CAN/FDCAN needs the clock, prescaler, time quanta, sample point and SJW. ADC behavior depends on its kernel clock, sampling time and source impedance. CubeMX is a useful calculator rather than a source of requirements. Document the requirements and final clock frequencies.
4. Common mistakes
- Assuming SYSCLK equals every peripheral frequency.
- Forgetting __HAL_RCC_xxx_CLK_ENABLE().
- Setting HSE_VALUE incorrectly.
- Ignoring Flash latency and voltage scaling.
- Using HAL_GetTick() for precise measurements.
- Failing to document TIMxCLK/UARTCLK/ADCCLK/FDCANCLK.
5. Practical task
Create STM32_CLOCK_TREE_POLICY.md:
# STM32 clock tree policy
Required:
- MCU exact part number
- HSE/HSI frequency
- PLL configuration
- SYSCLK, HCLK, PCLK1/PCLK2
- TIMxCLK for every timer
- UART kernel clock
- ADC kernel clock
- CAN/FDCAN kernel clock
- SysTick, RTC, watchdog sourceAdd a runtime clock command:
printf("SystemCoreClock=%lu\r\n", SystemCoreClock);
printf("HCLK=%lu\r\n", HAL_RCC_GetHCLKFreq());
printf("PCLK1=%lu\r\n", HAL_RCC_GetPCLK1Freq());
printf("PCLK2=%lu\r\n", HAL_RCC_GetPCLK2Freq());6. Further reading and experiments
STM32 HAL RCC documentation, the selected series reference manual, CubeMX Clock Configuration and STM32 TIM documentation.
Exercise
For documented TIMxCLK = 80 MHz, PSC = 79 and ARR = 999. Find the counter and update frequencies. What happens if PSC is accidentally 80?
Self-check criteria: Show the +1 divisors, units and the result of the incorrect PSC.
Show the supplied answer
counter = 80000000/(79+1) = 1000000 Hz; update = 1000000/(999+1) = 1000 Hz. With PSC=80, update = 80000000/(81×1000) ≈ 987.654 Hz. Use PSC+1 and ARR+1.