·15 min read·BASHCAT 技術團隊·embedded

The Complete Guide to Low-Power Embedded System Design

An in-depth analysis of low-power design techniques for embedded systems, covering chip selection, circuit design, and firmware optimization to help you build battery-powered devices that last for years.

#Low Power#Embedded Systems#STM32#nRF52#Battery#IoT#Power-Efficient Design

The Complete Guide to Low-Power Embedded System Design

IoT devices typically require battery power, and enabling devices to operate for months or even years is a core challenge. This article shares practical low-power design experience across three dimensions: chip selection, circuit design, and firmware optimization.

Power Consumption Fundamentals

Battery Life Calculation

The basic formula for battery life:

Battery Life (hours) = Battery Capacity (mAh) / Average Current (mA)

However, real-world scenarios are more complex and require considering:

  • Periodic switching between operating modes
  • Battery self-discharge (approximately 1-3% per month)
  • Temperature effects
  • Battery aging

Power Consumption Source Analysis

Typical power consumption distribution for an IoT device:

Module Operating Current Percentage
MCU Computation 5-50 mA 20%
Wireless Communication 10-100 mA 50%
Sensors 1-10 mA 15%
Power Conversion 5-15% loss 15%

Chip Selection

Ultra-Low-Power MCU Comparison

Chip Standby Current Operating Current Wake-up Time
STM32L4 30 nA 28 uA/MHz 5 us
nRF52840 0.4 uA 51 uA/MHz 3 us
ESP32-S3 7 uA 240 uA/MHz 250 us
MSP430FR 350 nA 100 uA/MHz 3.5 us

Selection Recommendations

  • BLE required: Nordic nRF52 series
  • WiFi required: ESP32-C6 (low-power WiFi)
  • Sensor-only applications: STM32L0/L4 series
  • Ultra-low power: MSP430FR series

Circuit Design Techniques

1. Power Switches

Use MOSFETs or load switch ICs to control peripheral power:

                    ┌─────────────────┐
  VCC ──────┬───────┤ LDO 3.3V        │
            │       └────────┬────────┘
            │                │
            │       ┌────────┴────────┐
            │       │ MCU (Always ON)  │
            │       └────────┬────────┘
            │                │ GPIO
            │                ▼
            │       ┌────────────────┐
            └───────┤ Load Switch IC  │
                    │ (TPS22860)     │
                    └────────┬───────┘
                             │
                    ┌────────┴────────┐
                    │ Sensors/Modules  │
                    │ (0 current when  │
                    │  powered off)    │
                    └─────────────────┘

2. Pull-up Resistor Optimization

I2C pull-up resistor selection affects power consumption:

  • 10k ohm: Standard choice, balancing power consumption and signal quality
  • 4.7k ohm: High-speed transmission, higher power consumption
  • Internal pull-up: Lowest power consumption, but signal quality may suffer

3. Decoupling Capacitors

Use appropriate decoupling capacitors to reduce high-frequency noise:

// Typical configuration
// - 100nF: per VCC pin
// - 10uF: power input
// - 1uF: sensitive analog circuits

Firmware Optimization

1. Sleep Mode Selection

Using STM32L4 as an example, there are multiple low-power modes:

// STM32L4 low-power mode selection
void enter_low_power_mode(LowPowerMode mode) {
    switch (mode) {
        case LP_SLEEP:
            // CPU only stopped, peripherals continue running
            // Current: ~200 uA
            HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,
                                    PWR_SLEEPENTRY_WFI);
            break;

        case LP_STOP0:
            // CPU and most clocks stopped
            // Current: ~12 uA
            HAL_PWREx_EnterSTOP0Mode(PWR_STOPENTRY_WFI);
            break;

        case LP_STOP1:
            // Lower power STOP mode
            // Current: ~5 uA
            HAL_PWREx_EnterSTOP1Mode(PWR_STOPENTRY_WFI);
            break;

        case LP_STOP2:
            // Lowest power STOP mode
            // Current: ~1.5 uA
            HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
            break;

        case LP_STANDBY:
            // Only RTC and a few registers retained
            // Current: ~280 nA
            HAL_PWR_EnterSTANDBYMode();
            break;

        case LP_SHUTDOWN:
            // Lowest power, requires external wake-up
            // Current: ~30 nA
            HAL_PWREx_EnterSHUTDOWNMode();
            break;
    }
}

2. Clock Management

Dynamically adjust clock frequency:

// Reduce clock frequency to save power
void reduce_clock_speed(void) {
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    // Switch to MSI 4MHz (low-power clock source)
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
    RCC_OscInitStruct.MSIState = RCC_MSI_ON;
    RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;  // 4 MHz
    HAL_RCC_OscConfig(&RCC_OscInitStruct);

    // Configure system clock
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
    HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

    // Disable unnecessary high-speed clocks
    __HAL_RCC_PLL_DISABLE();
    __HAL_RCC_HSE_CONFIG(RCC_HSE_OFF);
}

3. Peripheral Power Management

Enable peripherals only when needed:

// Sensor measurement cycle
void sensor_measure_cycle(void) {
    // 1. Enable sensor power
    HAL_GPIO_WritePin(SENSOR_PWR_GPIO, SENSOR_PWR_PIN, GPIO_PIN_SET);

    // 2. Wait for stabilization (refer to datasheet)
    HAL_Delay(10);

    // 3. Enable ADC
    __HAL_RCC_ADC_CLK_ENABLE();
    HAL_ADC_Init(&hadc1);

    // 4. Read data
    HAL_ADC_Start(&hadc1);
    HAL_ADC_PollForConversion(&hadc1, 100);
    uint16_t value = HAL_ADC_GetValue(&hadc1);

    // 5. Disable ADC
    HAL_ADC_DeInit(&hadc1);
    __HAL_RCC_ADC_CLK_DISABLE();

    // 6. Disable sensor power
    HAL_GPIO_WritePin(SENSOR_PWR_GPIO, SENSOR_PWR_PIN, GPIO_PIN_RESET);
}

Practical Example: 3-Year Battery Life Design

Design target: CR2450 battery (620mAh), operating for 3+ years.

Power Budget

Target lifespan: 3 years = 26,280 hours
Battery capacity: 620 mAh (considering 80% usable) = 496 mAh
Maximum average current: 496 / 26,280 = 18.9 uA

Duty Cycle Design

State Current Duration Cycle
Deep Sleep 1 uA 59 seconds Every minute
Sensor Measurement 500 uA 100 ms Every minute
BLE Advertising 8 mA 3 ms Every 10 minutes

Average Current Calculation

Sensor: (500 uA x 0.1s) / 60s = 0.83 uA
BLE: (8 mA x 0.003s) / 600s = 0.04 uA
Sleep: 1 uA x (59.9/60) = 0.998 uA
Total: 0.83 + 0.04 + 1.0 ≈ 1.87 uA

Estimated lifespan: 496 mAh / 0.00187 mA = 265,240 hours = 30 years
(Actual lifespan will be reduced to 3-5 years due to battery self-discharge)

Common Troubleshooting

Abnormally High Power Consumption?

  1. Check floating pins: Set unused GPIOs to input with pull-down
  2. Check debug interface: SWD may continuously draw power
  3. Check LEDs: Ensure status LEDs are turned off
  4. Check LDO quiescent current: Select ultra-low quiescent current LDOs

Cannot Wake Up After Sleep?

  1. Verify RTC clock source configuration is correct
  2. Confirm wake-up source (GPIO, RTC, UART) settings
  3. Check interrupt priorities

Low-power design is a discipline that requires coordinated hardware and software efforts. If you have a battery-powered product requirement, feel free to contact us to discuss.

$ tail -n 1 /var/log/bashcat/posts

More from the workshop.