Electronics Design AU
STM32Testing

Why Does My STM32 Keep Resetting Unexpectedly?

Last updated 19 August 2026 · 7 min read

Direct Answer

An STM32 that resets unexpectedly is almost always triggered by one of four causes — an unserviced watchdog timeout, a brown-out from inadequate power decoupling, an unhandled hard fault, or an external reset glitch — and the RCC/RCC_CSR reset-flag register on the chip tells you exactly which one occurred on the last reset.

Detailed Explanation

STM32 parts expose a reset-cause register (RCC_CSR on F4/F1-class parts, RCC_RSR on newer G0/G4/H5 families) that latches a flag for each possible reset source and persists across the reset itself. The four most common causes in the field are:

  1. Independent or window watchdog (IWDG/WWDG) timeout: firmware stalled (deadlock, infinite loop, blocking on a peripheral that never responds) and missed its watchdog refresh window. The IWDG also keeps running through Stop and Standby mode (it's clocked from LSI, which the WWDG's APB clock is not), so a device that spends longer than the configured IWDG timeout in a low-power mode resets mid-sleep, which looks identical to a firmware deadlock until the reset-flag register is checked.
  2. Brown-out / power-on reset (BOR/POR): the supply rail dropped below the brown-out threshold, often momentarily under load.
  3. Hard fault escalating to a system reset — an unhandled fault (bad pointer, stack overflow, unaligned access, or NVIC priority misconfiguration when using FreeRTOS) that the fault handler resolves by forcing a reset rather than halting. See STM32 NVIC interrupt priority configuration for the FreeRTOS-specific priority constraints that cause hard faults when violated, and decoding a Cortex-M HardFault for how to read the CFSR/HFSR registers to identify exactly what caused the fault before it forced the reset.
  4. External NRST glitch: noise or a marginal reset-line design pulling NRST low transiently.

Reading the flag register first thing in main() (or even earlier, in SystemInit) and logging or storing it before anything else touches the register turns "it just resets sometimes" into a specific, addressable bug.

Reset-Flag Register by Family

The register name and exact bit layout are not identical across the STM32 portfolio. Confirm the specifics for your part in its reference manual, but the general pattern is:

FamilyReset-flag registerNotes
F0 / F1 / F2 / F3 / F4 / F7, L0 / L1 / L4 / L5, G0 / G4RCC_CSRTypical bit set: LPWRRSTF, WWDGRSTF, IWDGRSTF, SFTRSTF, PORRSTF, PINRSTF, BORRSTF (F2/F4 and later only; earlier F1 parts don't separate BOR from POR), plus a write-only RMVF clear bit
H7 (single-core and dual-core H745/H747)RCC_RSRA dedicated reset-status register, separate from RCC_CSR (which on H7 only holds LSI oscillator control bits). Adds domain- and CPU-scoped flags such as CPURSTF, D1RSTF/D2RSTF (or CDRSTF on single-core parts), alongside IWDG1RSTF/WWDG1RSTF
H5, U5, WB, WLTypically RCC_CSR, though some parts consolidate flags under a security-domain-aware naming schemeCheck the family reference manual: TrustZone-enabled parts can gate flag visibility by security state

The bit names shift between families, so don't hardcode a single family's flag macro into shared firmware that targets multiple STM32 lines. Use the HAL's __HAL_RCC_GET_FLAG() abstraction (or an equivalent per-family #ifdef) instead of reading the raw register directly if the codebase needs to stay portable.

Practical Examples

A board that resets only when a Wi-Fi or BLE radio transmits is a textbook brown-out symptom: the transmit current spike sags the 3.3V rail just enough to trip BOR, especially if decoupling capacitance near the radio is thin. Reading RCC_CSR after such a reset and seeing the BOR flag set (rather than the watchdog flag) immediately rules out a firmware logic bug and points straight at power design. If the on-chip BOR's threshold or timing accuracy isn't tight enough to catch a marginal supply reliably, an external voltage supervisor IC monitoring the same rail with a precisely-set threshold is the standard fix. The same symptom shows up on Espressif parts too: see why an ESP32 keeps brownout-resetting for the equivalent diagnostic approach using esp_reset_reason() and the RTC_CNTL brownout detector register.

Conversely, a reset that only happens after the device has been running for hours under heavy peripheral load, with the IWDG flag set, points at a deadlock or missed refresh under specific timing conditions: a firmware bug, not a hardware one.

Diagnosing an Intermittent Reset Step by Step

When the reset-flag register alone doesn't settle the question, or the reset happens rarely enough that you need to catch it in the act, combine the register read with hardware instrumentation:

  1. Read and log the flag register on every boot, before anything clears it, and store it somewhere that survives the reset (a small non-volatile log, or a UART message sent immediately at startup). This turns an intermittent field failure into a dataset instead of a one-off anecdote.
  2. Instrument a heartbeat GPIO that toggles from the main loop (or a low-priority task, if using an RTOS). Capture it on a logic analyzer alongside the event of interest. If the heartbeat freezes before the reset, firmware was hung and the watchdog is the likely cause, regardless of what the flag register reports (a corrupted flag read is rarer, but not impossible, if the reset itself glitched register readout).
  3. Scope the supply rail and NRST together across the suspected reset window. A rail that visibly sags a moment before NRST/the CPU restarts confirms a brown-out; a clean, flat rail with NRST toggling low on its own points at an external glitch (noisy reset line, a marginal reset supervisor, or ESD coupling into the reset net) rather than a power problem.
  4. Correlate against load events: trigger the scope capture from the event most likely to cause the sag, such as a radio keying up, a motor driver switching, or a relay coil energising, rather than free-running. This turns "resets randomly" into "resets when X switches on," which is a much smaller problem to fix.
  5. Cross-check the flag register against the hardware evidence. If the register says IWDG but the heartbeat GPIO shows the loop still running normally right up to the reset, suspect a watchdog refreshed from the wrong context (see the window-mode pitfall below) rather than an actual hang.

Design Considerations

  • Always enable and service a watchdog timer in production firmware. It converts an unrecoverable hang into a clean, identifiable reset rather than a frozen device.
  • If using IWDG window mode (available on newer families such as G0/G4/L4/H7 via the IWDG_WINR register, not on plain F1/F4 IWDG), refreshing before the window's lower bound triggers a reset just as surely as refreshing too late. This typically bites when a refresh call is moved into a wake-from-Stop ISR without accounting for the window: waking earlier than the window opens produces a reset that looks exactly like a spurious IWDG timeout in the flag register, even though firmware never actually hung.
  • Verify clock configuration before assuming a firmware bug: a PLL configured with insufficient flash wait states, or an HSE that never reaches its ready flag, can cause crashes at startup that look like firmware faults. See how the STM32 clock tree works for the correct initialisation sequence.
  • Decouple aggressively near high-transient loads (radios, motor drivers, relays) and verify rail droop with a scope under real load, not just a multimeter average.
  • Log the reset cause to non-volatile storage (or send it over the debug/telemetry channel) on every boot in deployed products. Without this, field-reported "random resets" are nearly impossible to diagnose remotely.
  • Clear the reset flags explicitly (RCC_CSR |= RCC_CSR_RMVF or equivalent) after reading them, since they otherwise persist and can be misread after a subsequent unrelated reset.
  • Production firmware reliability: Shipping firmware that handles watchdog timeouts, hard faults, and power-supply variations gracefully requires production-hardened patterns. Zeus Design's embedded software team builds this reliability in as a standard part of the firmware development process.

Common Mistakes

  • Disabling the watchdog "temporarily" during development and forgetting to re-enable it before shipping.
  • Assuming every reset is a firmware bug without first checking whether it's actually a brown-out from inadequate decoupling.
  • Refreshing the watchdog from a low-priority task or interrupt that can itself be starved, which defeats the watchdog's purpose.
  • Never reading the reset-cause register at all, leaving the team debugging blind on every field report.
  • Hardcoding one family's RCC_CSR/RCC_RSR bit names into portable firmware, then porting to a different STM32 family without checking whether the register name or bit layout changed.
  • Refreshing a window-mode IWDG too early after waking from a low-power mode, producing a reset that reads as a watchdog timeout even though the firmware never hung.

Frequently Asked Questions

How do I find out what caused the last STM32 reset?
Read the reset flag bits in the RCC_CSR (or RCC_RSR on newer families) register immediately after startup, before anything else clears them. The flags distinguish watchdog, brown-out, software, pin, and low-power resets.
Can a brown-out reset look like a random crash?
Yes — a marginal 3.3V rail that dips under load (e.g. when a radio or motor driver switches on) will trigger the brown-out detector, which looks identical to a 'random' reset unless you check the reset cause register.
Is the reset-flag register named the same thing on every STM32 family?
No. Classic F0/F1/F2/F3/F4/F7/L-series parts expose it as RCC_CSR. The STM32H7 splits it into a separate RCC_RSR because the dual-domain (and dual-core, on H745/H747) architecture needs extra reset-source bits that don't fit alongside the LSI control bits RCC_CSR retains on those parts. Always confirm the exact register name and bit layout in your part's reference manual before writing recovery logic against it.

References

Related Questions

Related Forum Discussions