← Back to Embedded C series
🔌
STM32
STM32 · Prereq: lesson 12

13. Cortex-M · CMSIS · Clock Tree

We graduate from the 8051 to the 32-bit Arm Cortex-M (STM32F103). Thanks to the CMSIS standard, any Cortex-M is accessed similarly at the register level. This track controls registers directly, without HAL/SPL. We lay three foundations for the next seven lessons — Cortex-M structure, the CMSIS header (stm32f10x.h), and the clock tree (HSE→PLL→SYSCLK→AHB/APB) — and adopt the iron rule "enable the peripheral clock via RCC before using it".

STM32Cortex-MCMSISRCCclock treePLL
Duration
~1.5–2 hours
Level
📊 Intermediate
Prerequisite
🎯 Lesson 12
OUTCOME
Use CMSIS stm32f10x.h for registers, enable peripheral clocks via RCC, and compute SYSCLK/HCLK/PCLK1/PCLK2 from HSE·PLL·prescalers.

What you'll learn

  • 1Explain Cortex-M (STM32) vs 8051 differences (width·address·buses)
  • 2Know what CMSIS and stm32f10x.h provide
  • 3Apply the RCC rule "enable the clock before using a peripheral"
  • 4Follow the clock tree (HSE/HSI·PLL·AHB/APB prescalers)
  • 5Compute SYSCLK/HCLK/PCLK1/PCLK2 from configuration

Introduction

Versus the 8-bit 8051, register width·address space·peripheral count all widen. This lesson focuses on the foundations (structure·CMSIS·clock tree) for lessons 14–20, using CMSIS standard symbols (RCC->APB2ENR, GPIOC->ODR, SystemCoreClock) for readability·portability.

Key concepts

1) 8051 vs Cortex-M

Aspect8051Cortex-M3 (F103)
Width8-bit32-bit
Clock~12MHzup to 72MHz
RegistersSFR (P1·TMOD)structs (GPIOC->ODR)
Peripheral clockalways onindividually enabled via RCC
⚠️

The most important new habit is clock gating. STM32 leaves each peripheral clock off by default to save power, so enable it via RCC before writing.

2) RCC — the gateway to clocks

BusEnable registerPeripherals
APB2 (fast)RCC->APB2ENRGPIOA~E·ADC·USART1·TIM1·AFIO
APB1 (slow)RCC->APB1ENRTIM2~4·USART2/3·I2C·SPI2
c
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;  /* enable GPIOA·GPIOC */

3) Clock tree and bus limits

c
HSE(8MHz) → PLL(×9) → SYSCLK(72MHz) → AHB(/1) → HCLK(72MHz)
                                       → APB1(/2) → PCLK1(36MHz)
                                       → APB2(/1) → PCLK2(72MHz)

F103 limits: SYSCLK/HCLK ≤ 72MHz, PCLK1(APB1) ≤ 36MHz, PCLK2(APB2) ≤ 72MHz. So the standard config uses APB1 /2 and APB2 /1.

Core example

c
#include "stm32f10x.h"
int main(void) {
    /* STM32 rule: enable the clock before using a peripheral */
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
    /* SystemCoreClock (CMSIS global) holds the core clock (usually 72000000) */
    volatile uint32_t heartbeat = 0;
    while (1) { heartbeat++; }
}

Clock-tree check: HSE 8MHz×9=72MHz → SYSCLK 72M, HCLK 72M, PCLK1 36M, PCLK2 72M. In the simulator, RCC->APB2ENR shows IOPAEN(bit2)·IOPCEN(bit4) set to 0x14.

Common mistakes

Q. I wrote a GPIO register but nothing happens.

A. Most likely the clock is off. Do RCC->APB2ENR |= RCC_APB2ENR_IOPxEN; first to bring the register to life. This is the biggest difference from 8051.

Q. stm32f10x.h isn't found or RCC is undefined.

A. Check CMSIS:CORE and Device:Startup in Manage Run-Time Environment, and that a density macro like STM32F10X_MD is in C/C++ Define.

Q. HSI is 8MHz — how do we get 72MHz?

A. The PLL multiplies. HSE ×9 = 72MHz. system_stm32f10x.c's SystemInit() applies this at startup and records it in SystemCoreClock.

Summary

  • STM32 is a 32-bit Cortex-M; enable each peripheral's clock via RCC
  • CMSIS stm32f10x.h provides registers as structs and bit macros
  • Clock tree: HSI/HSE → PLL → SYSCLK → AHB/APB prescalers → each bus
  • F103 limits make APB1 /2 (36MHz), APB2 /1 (72MHz) standard
  • Direct register control without HAL/SPL, with CMSIS symbols for readability

Exercises

  1. For HSE 8MHz × 6, compute SYSCLK/HCLK/PCLK1/PCLK2 (and judge any APB1 limit violation)
  2. Write RCC code enabling GPIOB·USART1 clocks in one line (name each bus)
  3. Watch SystemCoreClock to confirm it's 72000000 after startup
Example code / lecture materials

All lecture materials and example code (with homework and answers) are openly available on GitHub.

View on GitHub ↗