Skip to content

低功耗设计实践

功耗优化总体策略

IoT 设备低功耗设计需要从系统级考虑,不仅仅是模组本身:

系统功耗 = 模组功耗 + MCU 功耗 + 传感器功耗 + 其他外设功耗

优化层次:
  1. 应用层:减少不必要的数据传输
  2. 协议层:选择合适的省电模式(PSM/eDRX)
  3. 硬件层:外设按需供电,MCU 深度睡眠
  4. 电源层:高效 DC-DC 转换,减少静态电流

模组省电模式

PSM vs eDRX 选择

PSM(省电模式):
  适用场景:
    - 上报频率低(每小时或更低)
    - 不需要接收下行数据(或可以等到下次上报时接收)
    - 对时延不敏感
  功耗:2-5 μA(深睡眠)
  缺点:无法实时接收下行数据

eDRX(扩展非连续接收):
  适用场景:
    - 需要定期接收下行数据
    - 上报频率中等(每分钟到每小时)
    - 对时延有一定要求
  功耗:10-100 μA(取决于 eDRX 周期)
  优点:可以定期接收下行数据

组合使用:
  先用 eDRX 等待下行数据
  无数据时进入 PSM 深睡眠

最优 PSM 配置

bash
# 场景:每小时上报一次,不需要接收下行
AT+CPSMS=1,,,"00100110","00000001"
# TAU = 6小时("001" × 6 = 6小时)
# Active Time = 2秒

# 场景:每天上报一次(智能水表)
AT+CPSMS=1,,,"01000001","00000001"
# TAU = 1小时(每小时向网络注册,防止被踢出)
# Active Time = 2秒
# 注:TAU 不能设太长,否则网络会认为设备离线

# 场景:需要接收下行命令(远程控制)
AT+CPSMS=1,,,"00100001","00000101"
# TAU = 1分钟
# Active Time = 10秒(给服务器足够时间发送下行)

MCU 低功耗设计

STM32 低功耗模式

c
// STM32 与 NB-IoT 模组协同低功耗
#include "stm32l4xx_hal.h"

void system_sleep(uint32_t sleep_seconds) {
    // 1. 关闭不需要的外设
    HAL_GPIO_WritePin(SENSOR_PWR_GPIO, SENSOR_PWR_PIN, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(LED_GPIO, LED_PIN, GPIO_PIN_RESET);
    
    // 2. 配置 RTC 唤醒定时器
    HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, sleep_seconds, 
                                 RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
    
    // 3. 进入 STOP2 模式(最低功耗,保留 RAM)
    HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
    
    // 4. 唤醒后恢复时钟
    SystemClock_Config();
    
    // 5. 重新上电外设
    HAL_GPIO_WritePin(SENSOR_PWR_GPIO, SENSOR_PWR_PIN, GPIO_PIN_SET);
}

void main_loop(void) {
    while (1) {
        // 采集传感器数据
        float temperature = read_temperature();
        float humidity = read_humidity();
        
        // 唤醒模组
        wakeup_module();
        
        // 发送数据
        send_data(temperature, humidity);
        
        // 等待发送完成
        wait_send_complete();
        
        // 模组进入 PSM
        module_enter_psm();
        
        // MCU 进入深度睡眠
        system_sleep(3600);  // 睡眠 1 小时
    }
}

模组唤醒方式

c
// 方法1:通过 UART 发送 AT 指令唤醒
void wakeup_module_uart(void) {
    // 发送任意字符唤醒
    uart_send_byte(0xFF);
    delay_ms(100);
    // 等待模组响应
    uart_send("AT\r\n");
    wait_response("OK", 3000);
}

// 方法2:通过 PWRKEY 引脚唤醒(如果模组支持)
void wakeup_module_pwrkey(void) {
    HAL_GPIO_WritePin(MODULE_PWRKEY_GPIO, MODULE_PWRKEY_PIN, GPIO_PIN_RESET);
    delay_ms(200);
    HAL_GPIO_WritePin(MODULE_PWRKEY_GPIO, MODULE_PWRKEY_PIN, GPIO_PIN_SET);
    delay_ms(2000);  // 等待模组启动
}

// 方法3:通过 DTR 引脚唤醒
void wakeup_module_dtr(void) {
    HAL_GPIO_WritePin(MODULE_DTR_GPIO, MODULE_DTR_PIN, GPIO_PIN_RESET);
    delay_ms(50);
    HAL_GPIO_WritePin(MODULE_DTR_GPIO, MODULE_DTR_PIN, GPIO_PIN_SET);
    delay_ms(100);
}

电源设计优化

电池选型

电池类型特点适用场景
锂亚(Li-SOCl₂)高能量密度,自放电极低,宽温度NB-IoT 超长寿命设备
锂锰(Li-MnO₂)高脉冲电流,低温性能好需要大电流脉冲的设备
锂聚合物(LiPo)可充电,轻薄可充电设备
碱性电池成本低,易获取低成本消费品

NB-IoT 设备推荐:锂亚电池(ER系列)

ER14505(AA 尺寸):2700mAh,3.6V
ER26500(C 尺寸):9000mAh,3.6V
ER34615(D 尺寸):19000mAh,3.6V

注意:锂亚电池内阻较高,不适合大电流脉冲
需要并联超级电容(0.1-1F)提供瞬时大电流

超级电容辅助供电

NB-IoT 发射时峰值电流 220mA,持续时间约 1-5 秒
锂亚电池内阻约 10-50Ω,无法提供足够电流

解决方案:锂亚电池 + 超级电容并联
  锂亚电池:提供平均电流(慢充超级电容)
  超级电容:提供瞬时大电流(发射时放电)

电路设计:
  ER14505 → 肖特基二极管 → 超级电容(0.47F/5.5V)→ 模组 VBAT
  超级电容充电时间:约 10-30 秒
  超级电容放电时间:约 2-5 秒(发射期间)

功耗测试方法

使用电流探针测量

测试设备:
  - 精密电流表(如 Nordic PPK2,精度 0.1μA)
  - 示波器(观察电流波形)
  - 逻辑分析仪(关联 AT 指令和电流)

测试步骤:
  1. 串联电流表到 VBAT 供电线
  2. 记录各状态下的电流:
     - 模组启动:峰值电流
     - 网络注册:平均电流
     - 数据发送:峰值和平均电流
     - PSM 睡眠:静态电流
  3. 计算平均功耗和电池寿命

电池寿命计算公式

平均电流 = Σ(各状态电流 × 持续时间) / 总时间

示例(每小时上报一次):
  启动+注册:500mA × 10s = 5000mAs
  数据发送:220mA × 5s = 1100mAs
  PSM 睡眠:3μA × 3585s = 10755μAs ≈ 10.8mAs
  
  总电荷 = 5000 + 1100 + 10.8 = 6110.8 mAs
  平均电流 = 6110.8 / 3600 = 1.70 mA

  3000mAh 电池寿命 = 3000mAh / 1.70mA = 1765h ≈ 73天

优化后(模组保持注册,不重启):
  数据发送:220mA × 5s = 1100mAs
  PSM 睡眠:3μA × 3595s = 10785μAs ≈ 10.8mAs
  
  平均电流 = (1100 + 10.8) / 3600 = 0.31 mA
  电池寿命 = 3000mAh / 0.31mA = 9677h ≈ 403天 ≈ 1.1年

褚成志的笔记