Microcontrollers & architecture 3 min read

The clock system

Everything in a microcontroller happens on a clock edge. The clock system picks a source, either an internal oscillator or an external crystal, multiplies it with a PLL, then divides it with prescalers so each bus and peripheral gets the frequency it needs.

Example clock tree for an STM32F103. HSI, an internal 8 MHz RC oscillator, and HSE, an external 8 MHz crystal, are the main sources; LSE, a 32.768 kHz crystal, drives the real-time clock. HSE feeds a PLL that multiplies by 9 to 72 MHz, selected as SYSCLK. The AHB prescaler divides by 1 for the CPU, memory and DMA; APB1 divides by 2 to 36 MHz for UART2 and I2C; APB2 divides by 1 to 72 MHz for GPIO and SPI1.
A clock tree: sources on the left, consumers on the right.

Pick a source

An STM32F103 always starts on the HSI after reset. Startup code then switches to the crystal and the PLL.

Multiply, then divide

A phase-locked loop (PLL) multiplies a stable reference up to a high frequency: 8 MHz × 9 = 72 MHz, the F103's maximum. Prescalers then divide that clock for each bus. On the F103, the APB1 bus is limited to 36 MHz, so it runs at ÷2.

ClockDerived fromFrequencyFeeds
SYSCLKHSE × 9 (PLL)72 MHzThe whole tree
HCLKAHB ÷ 172 MHzCPU, memory, DMA
PCLK1APB1 ÷ 236 MHzUSART2, I2C, TIM2–4
PCLK2APB2 ÷ 172 MHzGPIO, SPI1, USART1, ADC

Three gotchas