2026-01-11 4:30 AM
DBGMCU is the STM32 debug controller that lets the debugger stay useful while the MCU is sleeping/stopped/standby and provides “freeze” bits so peripherals (timers, watchdogs, I²C timeouts…) stop when the core is halted — great to inspect state and avoid unwanted resets during breakpoints. Always check your chip’s RM because register names & behavior vary by family.
Keep debug access in low-power modes. If your MCU enters Sleep/Stop/Standby and you still want to attach or keep the debugger alive, set DBGMCU low-power debug bits so the debug clocks stay available. Without this you may lose the debug connection or be forced to connect under reset (which destroys runtime state).
Freeze peripherals during a halt. When you hit a breakpoint, you often want timers, watchdogs, DMA timeouts, RTC, I²C SMBus timeouts etc. to be frozen — DBGMCU provides APB/AHB freeze registers for that (so peripheral clocks are gated or counters paused while core is halted).
Names and layout differ across families, but conceptually:
DBGMCU_CR (or similar) — contains low-power debug bits:
DBG_SLEEP — keep debug in SLEEP mode
DBG_STOP — keep debug in STOP mode
DBG_STANDBY — keep debug in STANDBY mode
Setting these allows debug access / appropriate clocking while in those low-power states.
DBGMCU_APBxFZ / DBGMCU_AHBxFZ / APB1FZR1 / APB1LFZ1 / APB3FZ1 ... — freeze registers that contain bits such as:
DBG_TIM2_STOP, DBG_TIM3_STOP, ... — freeze timer counters when core halted
DBG_IWDG_STOP, DBG_WWDG_STOP — freeze watchdogs
DBG_RTC_STOP / DBG_I2C*_STOP — freeze RTC or SMBus timeouts
The register names and bit positions vary by series (F0/F1/F3/F4/L4/H7/U5/...); HAL/LL provides macros.
Rule: Always open your device RM (Reference Manual) and search “DBGMCU” and “debug” chapters — they show exact register names for your part.
ST HAL/LL already wrap these; use them when you want readable code that follows family conventions.
Example (HAL style; works on F4/L4 families with the Cube HAL):
// Enable debug during low-power modes
__HAL_RCC_DBGMCU_CLK_ENABLE(); // make sure DBGMCU APB clock is enabled (if required)
HAL_DBGMCU_EnableDBGSleepMode(); // enable debug in Sleep (or)
HAL_DBGMCU_EnableDBGStopMode(); // enable debug in Stop
HAL_DBGMCU_EnableDBGStandbyMode(); // enable debug in Standby
// Freeze TIM2 and IWDG while core halted
__HAL_DBGMCU_FREEZE_TIM2(); // macro sets DBGMCU->APB1FZ |= DBGMCU_APB1FZ_DBG_TIM2_STOP
__HAL_DBGMCU_FREEZE_IWDG(); // freeze IWDG (if supported)Or LL (Low-Layer), which is explicit and available on many families:
LL_DBGMCU_EnableDBGSleepMode();
LL_DBGMCU_EnableDBGStopMode();
LL_DBGMCU_EnableDBGStandbyMode();Use the corresponding Disable... calls to revert. These HAL/LL helpers are implemented in the Cube packages.
This is a generic direct-register approach (replace bit names with the exact ones in your RM):
// Example: enable debug in Stop and Sleep modes (pseudo / family-dependent names)
DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
// Example: freeze TIM2 and I2C1 timeouts on halt
DBGMCU->APB1FZ |= (DBGMCU_APB1FZ_DBG_TIM2_STOP | DBGMCU_APB1FZ_DBG_I2C1_STOP);Important: exact register field names differ (APB1FZ, APB1FZR1, APB1LFZ1, APB3FZ1, etc.). Use the RM or the <family>xx_hal.h macros to avoid typos.
Symptom: the debug probe disconnects or cannot halt the CPU after STOP.
Fix: before entering STOP, enable DBG_STOP (via HAL/LL or DBGMCU->CR). That keeps an internal RC oscillator / debug clock path active so the debug interface can reattach without resetting the part. (Family notes: on some parts the debugger still needs to set these bits; some debuggers do it automatically.)
Symptom: TIMx counter keeps running while CPU halted, so you can’t inspect exact counter value at breakpoint.
Fix: set the DBGMCU freeze bit for that timer (DBG_TIMx_STOP), so hardware stops the timer when CPU is halted. Use HAL macro __HAL_DBGMCU_FREEZE_TIM2() or write the freeze bit directly.
Symptom: IWDG/WDT resets while you step in the debugger.
Fix: freeze the watchdog (DBG_IWDG_STOP / DBG_WWDG_STOP) while debugging. But do not leave this enabled in production (it disables safety net).
Register names differ. F0/F1/F4 often use DBGMCU->CR + DBGMCU->APB1FZ/ APB2FZ. Newer families (H7, U5, G4) may use multiple freeze registers (AHB1FZ, APB1LFZ1, APB3FZ1...). Always read the local RM chapter.
Not all peripherals can be frozen. The RM lists exactly which peripherals have freeze bits. Some peripherals are always running or are in separate power domains.
Stop vs Standby behavior: enabling DBG_STOP typically keeps an internal RC on so clocks needed for debug exist; enabling or disabling bits affects how the clock tree behaves in that low-power mode. If you rely on specific PLL/xosc behavior on exit, test carefully.
Some vendors / debugger combos set these bits automatically. Tools like ST-Link GUI, some debuggers or RTOS bring-up scripts may toggle DBGMCU bits; this hides the problem during development but bites you when running on a board without that helper.
Power vs debug tradeoff: enabling debug in low-power increases current draw and may defeat your low-power tests. Use guarded code: only enable during development or behind #ifdef DEBUG.
Relying on freeze for production logic: don’t build functionality that depends on watchdogs being frozen — production devices must not disable safety features.
Cache / peripheral clocks in STOP: STOP may turn off domains — enabling DBG_STOP changes clocking; your wake-up sequence may need to reinit PLLs. Test the exit path.
Different behavior between stepping and halting: Some peripherals continue if they are driven by independent hardware clock domains — freezing is not a guarantee unless RM lists the freeze bit.
AN4989 — STM32 microcontroller debug toolbox (troubleshooting & low-power debug tips).
STM32H7 System Debug (training PDF) — architecture & specifics for H7.
AN5946 / family application notes about low-power — mentions DBGMCU_CR usage.
Cube HAL/LL docs and header macros — search __HAL_DBGMCU_FREEZE_* or LL_DBGMCU_EnableDBGStopMode() in your device package.
ST Community & StackOverflow threads where people discuss debugger disconnects and freezes (practical troubleshooting).
For development: enable DBG_STOP/DBG_SLEEP so you can attach the debugger and freeze the peripherals you care about. Wrap these calls under #ifdef DEBUG.
For low-power validation: test both with and without debug bits — enabling them changes actual power draw and clocking. Measure current and verify behavior.
For CI / automated flashing: be aware some programmers/tools toggle DBGMCU bits — don’t rely on their presence in production.