Clocks, Reset & Watchdog Timers
Before any peripheral works, the MCU needs a clock and a clean reset. Learn clock sources (HSI, HSE crystal, LSI, LSE), PLL configuration, bus prescalers and Flash wait states, clock gating, reset sources and brown-out detection, and independent and window watchdogs — including how to size timeouts and design a watchdog strategy that really catches failures.
Every timer frequency, UART baud rate and ADC sample time derives from the clock tree. A wrong PLL setting gives garbled serial output and timers that run at the wrong speed; an unstable crystal can cause intermittent USB failures. Understanding the clock tree is the first step of bring-up on any new board.
Reset and watchdog hardware keep devices recoverable. Brown-out detection prevents corrupted Flash writes when a battery sags; a watchdog resets a hung system so a remote sensor recovers without a site visit.
An analogy
The clock is the heartbeat of the chip and the PLL is a gearbox that multiplies it. The watchdog is a dead-man's switch: if the train driver (firmware) stops pressing it regularly, the train brakes (resets) automatically.
Clock sources
MCUs offer several oscillators with different trade-offs:
- HSI (internal RC, 8–16 MHz): starts instantly, ±1% accuracy — fine for many tasks, not USB/CAN
- HSE (external crystal 4–26 MHz): ±20–50 ppm — needed for USB, CAN, Ethernet, accurate UART
- LSI (internal ~32 kHz): watchdog, rough wake-ups
- LSE (32.768 kHz crystal): RTC timekeeping (2¹⁵ Hz divides to exactly 1 s)
PLL and the clock tree
A PLL multiplies a reference to a high frequency (the VCO), then dividers produce the system clock and special clocks (48 MHz USB). The system clock feeds the AHB bus (CPU, DMA, memory) and slower APB buses for peripherals — each with its own maximum. Every peripheral's clock must be enabled (RCC->APBxENR) before use; forgetting this is the #1 bring-up bug ('my register writes do nothing').
Reset sources and brown-out
Resets come from power-on (POR), the reset pin, brown-out (BOR, supply below threshold), watchdogs, software (NVIC_SystemReset), and low-power exits. Read and clear the reset-cause flags at boot and log them — they are invaluable for diagnosing field failures. Brown-out reset holds the MCU in reset when voltage is too low to execute or write Flash reliably.
Watchdog strategy
An independent watchdog (IWDG) runs from its own LSI clock and survives main-clock failure. A window watchdog (WWDG) also resets if kicked too early, catching runaway loops that kick too often. Size the timeout above the longest legitimate gap (Flash erase can block for 100s of ms) but short enough for safe recovery. Safety systems add a clock-security system (CSS) that switches to HSI if the crystal fails, and external watchdog ICs with independent time bases.
Formulas
- PLL output (STM32F4 style):
f_VCO = f_in × N / M; SYSCLK = f_VCO / P; f_USB = f_VCO / Q - Bus clocks:
HCLK = SYSCLK / AHB_prescaler; PCLK = HCLK / APB_prescaler - Flash wait states:
WS = ⌈HCLK / f_Flash,max⌉ − 1 (e.g. 30 MHz per WS at 3.3 V) - Independent watchdog timeout:
t = (RL + 1) × prescaler / f_LSI - Crystal load capacitors:
C_L = (C₁·C₂)/(C₁ + C₂) + C_stray → C₁ = C₂ ≈ 2(C_L − C_stray)
Worked example: PLL settings
Given: HSE 8 MHz, M = 8, N = 336, P = 2, Q = 7
Find: SYSCLK and USB clock.
- VCO = 8/8 × 336 = 336 MHz
- SYSCLK = 336/2; USB = 336/7
Answer: 168 MHz and 48 MHz
Worked example: Watchdog timeout
Given: LSI 32 kHz, prescaler 64, reload 4095
Find: Maximum timeout.
- t = 4096 × 64 / 32 000
Answer: 8.19 s
Worked example: Crystal load caps
Given: Crystal C_L = 12 pF, stray ≈ 5 pF
Find: C₁ = C₂.
- C₁ = 2(12 − 5)
Answer: 14 pF (use nearest standard 15 pF)
168 MHz from an 8 MHz crystal (register-level, STM32F4)
void clock_init_168mhz(void)
{
RCC->CR |= RCC_CR_HSEON; /* start crystal */
while (!(RCC->CR & RCC_CR_HSERDY)) { } /* wait until stable */
/* VCO = 8 MHz / M(8) * N(336) = 336 MHz; SYSCLK = /P(2) = 168 MHz;
USB/SDIO = /Q(7) = 48 MHz */
RCC->PLLCFGR = (8u << RCC_PLLCFGR_PLLM_Pos) | (336u << RCC_PLLCFGR_PLLN_Pos)
| (0u << RCC_PLLCFGR_PLLP_Pos) /* 0 means /2 */
| (7u << RCC_PLLCFGR_PLLQ_Pos) | RCC_PLLCFGR_PLLSRC_HSE;
RCC->CR |= RCC_CR_PLLON;
while (!(RCC->CR & RCC_CR_PLLRDY)) { }
FLASH->ACR = FLASH_ACR_LATENCY_5WS | FLASH_ACR_PRFTEN
| FLASH_ACR_ICEN | FLASH_ACR_DCEN; /* BEFORE speeding up */
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4 | RCC_CFGR_PPRE2_DIV2; /* APB1 42, APB2 84 MHz */
RCC->CFGR |= RCC_CFGR_SW_PLL;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) { }
}Order matters: raise Flash wait states before increasing the clock, or the CPU fetches garbage and crashes. APB1 is limited to 42 MHz on this family, hence the /4 prescaler.
Watchdog kicked only when all tasks are healthy
#define ALL_ALIVE (ALIVE_SENSOR | ALIVE_CONTROL | ALIVE_COMMS)
static volatile uint32_t alive_bits;
void task_report_alive(uint32_t bit) { alive_bits |= bit; } /* each task */
void watchdog_supervisor(void) /* runs every 100 ms */
{
if ((alive_bits & ALL_ALIVE) == ALL_ALIVE) {
IWDG->KR = 0xAAAA; /* refresh ("kick") */
alive_bits = 0;
}
/* otherwise don't kick: IWDG resets the MCU after its timeout */
}
void iwdg_init_500ms(void) /* LSI ~32 kHz */
{
IWDG->KR = 0x5555; /* unlock PR/RLR */
IWDG->PR = 3; /* prescaler /32 */
IWDG->RLR = 499; /* (499+1)*32/32000 = 0.5 s */
IWDG->KR = 0xCCCC; /* start (cannot be stopped) */
}Kicking the dog from a timer ISR alone is useless — the ISR keeps running even if the main logic deadlocks. Kick only when every critical activity has proven it is alive.
Common mistakes
- Wrong: Using a peripheral without enabling its clock. — Right: Enable RCC clock first; registers ignore writes otherwise.
- Wrong: Raising SYSCLK before setting Flash wait states. — Right: Increase latency first, then clock; reverse when slowing down.
- Wrong: Kicking the watchdog in a timer ISR. — Right: Kick only after verifying all critical tasks made progress.
- Wrong: Using HSI for CAN/USB. — Right: Use a crystal (HSE) for protocols needing tight timing.
Applications
- USB & CAN devices: Crystal + PLL to meet tight frequency tolerance.
- Remote IoT nodes: Watchdog + reset-cause logging for unattended recovery.
- Battery products: Brown-out reset protects Flash during low battery.
- Safety systems: Window watchdog and clock-security system per IEC 61508/ISO 26262.
Key takeaways
- Crystal → PLL → SYSCLK → AHB/APB buses.
- Enable peripheral clocks; set wait states before speeding up.
- Log reset causes at boot.
- Kick the watchdog only when the system is truly healthy.
Going further
- Spread-spectrum clocking: Modulates the PLL to reduce EMI peaks.
- Clock security system: Detects HSE failure and switches to HSI with an NMI.
- Dynamic frequency scaling: Change SYSCLK at run time to trade power for speed.