How to achieve low power consumption with STM32L476?
Achieving sub-1 µA consumption on the board isn’t difficult - my small water meter project last year used the L476 and achieved 0.8 µA in stop mode, with 50,000 units mass-produced without any issues. Following this process will help you avoid pitfalls:
-
Power Supply First
- Use a 1 µA quiescent current LDO (I used the XC6206 series) for 3.3V, avoid mA-leakage parts like 1117
- All sensors, 485, and Flash should go through MOSFET switches - power off completely before entering low-power mode. Don’t trust datasheets claiming “2 µA standby” - actual measurements start from 50 µA
-
GPIO Configuration
- Analog inputs: Use
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;floating is most power-efficient - Digital inputs: Either internal pull-down or external 100k pull-down, never leave floating
- Digital outputs: Set to defined state according to peripheral voltage levels. Even when peripherals are powered off, set IO to 0 to prevent 3V from powering peripherals through protection diodes
- NRST and BOOT0: Replace 10k pull-up with 1M to save 300 µA
- Analog inputs: Use
-
Clock Tree Optimization
- Disable HSI/HSI16/PLL in CubeMX, don’t leave MSI enabled
- RTC wake-up should only use LSE, not LSI (LSI alone consumes ≥1 µA)
-
Use STOP2 Mode
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);preserves RAM content after wake-up, avoiding reinitialization- Use only RTC + 1 GPIO edge as wake-up sources. Avoid UART wake-up which can cause system hangs
-
Thorough Peripheral Shutdown
- For I²C/SPI/UART: First
__HAL_RCC_*_FORCE_RESET()then__HAL_RCC_*_RELEASE_RESET()to reset registers to default values. Leaving them active creates 179 µA leakage (verified through ST official forum) - For ADC/COMP/OPAMP: Use
HAL_*_DeInit()before disabling clocks - Disable clocks for DMA/USB/CRC completely - don’t rely on “auto-shutdown” features. Each missed component adds 20 µA
- For I²C/SPI/UART: First
-
Quick Wake-up Execution
- Enable HSI16 after wake-up, complete operations, then re-DeInit peripherals, switch clocks back to LSE, and re-enter STOP2
- Keep wake-up → sampling → transmission → sleep cycle within 20ms. Average current = 0.8 µA×(sleep time/cycle) + 5 mA×0.02s/cycle. For hourly sampling water meters, average consumption is ~3 µA
-
Current Measurement Tips
- Use uCurrent Gold or Agilent 34401A on the 3.3V line. Don’t use mA range on multimeters - 1Ω internal resistance can add 100 µA leakage
- First test with “bare board” program (no peripherals) - see 0.4 µA first, then gradually add features while measuring each step to identify power-hungry components
Following these seven steps makes achieving sub-1 µA with L476 straightforward. Final reminder: Don’t take ST’s official Nucleo measurements as gospel - those boards have ST-LINK, LD3, LD4 components that add ~200 µA. Always test with your own custom board!祝你一次成功,烧录器永不回头! (Wishing you success on first try, and no need to return to the programmer!)
Hey, the L476 is a great chip for low power, but getting to those single-digit microamp numbers can be tricky. I’ve battled this one before.
Here’s a checklist I usually run through. It’s almost always one of these things.
1. The Obvious Gotcha: The Debugger
Are you measuring the current with the ST-LINK or J-Link debugger connected? If yes, unplug it immediately.
The debug module (part of the ARM core) stays powered and active when a debugger is attached, which stops the MCU from entering its deepest sleep modes. It can add 1-2mA all by itself.
Step: Flash your code, unplug the debugger, reset the board (or power cycle it), and then measure the current.
2. Choose the Right Low-Power Mode
The L476 has many modes. Don’t just use a simple WFI (Wait For Interrupt) in Sleep mode.
- Stop 2 Mode: This is usually the best one. It’s very low power (around 1uA with RTC) and keeps all your RAM and registers. Wakeup is fast. Use
HAL_PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI). - Standby Mode: This is even lower power, but it erases your RAM. It’s only good if you can restart your application from scratch on wakeup.
- Shutdown Mode: Even lower, but almost a full power-off.
Step: Use Stop 2 mode for your main low-power state.
3. Disable ALL Unused Peripherals
This is the most common mistake. Every single peripheral you are not using must have its clock disabled. If you leave the clock running for a Timer, UART, I2C, SPI, ADC, USB, etc., it will draw power.
Step:
- Use CubeMX and go through the peripheral list. Disable everything you don’t need.
- In your code, right before entering sleep, manually disable the clocks for any peripherals you were using but don’t need during sleep.
- Example:
__HAL_RCC_USART1_CLK_DISABLE();__HAL_RCC_TIM2_CLK_DISABLE();
4. Configure GPIOs Correctly
Floating pins are a disaster for low power. They can float to an intermediate voltage, causing the input buffer to oscillate and burn current.
Step: Every unused pin on your MCU must be configured as Analog Input Mode with no pull-up or pull-down. This is their lowest-power state.
- In CubeMX, find all unused pins (green) and set them to
GPIO_Analog. - For pins connected to external components, make sure they aren’t floating. If a button has an external pull-up, it’s drawing current.
5. Lower the System Clock (Before Sleep)
You don’t need to run at 80MHz if you’re about to sleep. The fast clock draws power.
Step: Before calling the HAL_PWR_EnterSTOP2Mode function, switch your system clock (SYSCLK) to a low-speed clock, like the MSI (e.g., at 4MHz or 1MHz). When the MCU wakes up, you can re-configure the PLL and switch back to a high-speed clock if you need to.
6. Set the Voltage Scaling
The L4 series can run its core at different voltages. Lower voltage = lower power. This is called “Range”.
- Range 1 (High Performance): Up to 80MHz.
- Range 2 (Medium): Up to 26MHz. Lower power.
- Range 3 (Low Power): Up to 2MHz. Very low power (but you can’t enter Stop modes from here, so Range 2 is usually the target for low-power run).
Step: Before sleeping, you’ll want to be in Range 2 (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE2)). The HAL_PWR_EnterSTOP2Mode function usually handles this, but it’s good to be aware of.
7. Check Your Hardware!
Is there an LED on? A voltage regulator with a high quiescent current (Iq)? A pull-up resistor that’s always drawing current?
Step: Look at your schematic. Your STM32 might be at 2uA, but your power LED and bad regulator are pulling 5mA. Use a multimeter to “walk” the board and find where the current is going.
Summary: Quick Action Plan
-
Use CubeMX to generate a new, clean project.
-
In CubeMX:
- Set all unused pins to Analog.
- Disable every peripheral you don’t need (USB, ADC, DAC, etc.).
- Enable the RTC if you need a wakeup source.
-
In your
main.c, in thewhile(1)loop, add this code:/* This is just an example, e.g., for a 10-second sleep */ HAL_Delay(1000); // Wait a second for things to stabilize /* --- Prep for Sleep --- */ // 1. Disable any active peripherals (e.g., UART) // __HAL_RCC_USART1_CLK_DISABLE(); // 2. Switch to a low-speed clock (optional but good) // (This part is complex, CubeMX can set up the wakeup clock) /* --- Enter Stop 2 Mode --- */ HAL_PWR_EnterSTOP2Mode(PWR_STOPENTRY_WFI); /* --- WAKEUP --- */ // System clock will be reset to MSI (or HSI) // You need to re-configure your clocks if you were using PLL // SystemClock_Config(); // Call your clock config function again // 4. Re-enable peripherals you need // __HAL_RCC_USART1_CLK_ENABLE(); -
Flash this code.
-
UNPLUG THE DEBUGGER.
-
Power cycle the board.
-
Measure the current.
You should see a massive drop. Good luck! Let us know what you find.