Low Power 应用指南

1. Low Power 概述

本文基于SDK低功耗使用指南,聚焦实际项目中的低功耗分析与优化,涵盖工具选型、漏电模型、待机功耗、关机功耗、Sensor 优化五大核心模块,提供可落地的分析方法与配置方案。

2. Low Power 分析准备

2.1 测量工具及对比

工具型号

核心优势

劣势

适用场景

PPK2

支持 μA 级测量; 含电源/电流计双模式; 便携小巧; 支持 IO 电平反转

不支持电压+电流同步测量; 单次测量≤500ms

移动场景、短时间 μA 级功耗测试

KeySight 34465A

支持 μA 级测量; 电压+电流同步测量; 测量时间无限制

体积大、便携性差; 仅电流计功能(需额外供电); 无 IO 电平反转

实验室固定场景、长时间功耗监测

EMK850x

支持 μA 级测量; 测量时间无限制

不支持电压+电流同步测量; 无 IO 电平反转

实验室固定场景、长时间 μA 级测试

  • PPK2实物外形:

fishy
  • 34465A实物外形:

fishy
  • EMK850x实物外形:

fishy

2.2 低功耗模式与平台适配

2.2.1 基础低功耗模式(SDK 定义)

模式名称

功耗等级

核心特性

PM_SLEEP_MODE_IDLE

最高

轻度睡眠,外设基本保持工作

PM_SLEEP_MODE_LIGHT

中高

中度睡眠,部分外设暂停

PM_SLEEP_MODE_DEEP

中低

深度睡眠,多数外设关闭

PM_SLEEP_MODE_STANDBY

较低

待机模式,仅保留核心唤醒电路

2.2.2 关机超低功耗模式

  • Shutdown 模式:完全关机,仅保留唤醒电路,功耗最低。

  • Hibernate 模式:深度休眠,仅保留唤醒源与最小供电,唤醒后需重新初始化外设,功耗次之;

  • Standby 模式:待机模式,仅保留核心唤醒电路,唤醒后需重新初始化外设,功耗稍高。

2.2.3 平台模式适配表

平台

HCPU 睡眠模式

LCPU 睡眠模式

关机模式

特殊说明

56x

Standby

Standby

Standby

关机时关闭外设供电,依赖 PM_SLEEP_MODE_STANDBY 实现低功耗

52x

Deepsleep

-

Hibernate

关机依赖 Hibernate 模式,唤醒后需重初始化

55x/58x

Standby

Standby

Hibernate

关机依赖 Hibernate 模式,唤醒后需重初始化

2.3 漏电模型(核心原理)

2.3.1 标准 PAD 模型(基础)

  • 标准PAD模型

fishy
  • PAD 控制信号包括以下几种:

    • DS (Driving Strength): 驱动强度

    • OE (Output Enable): 输出使能

    • O (Output): 输出(信号)

    • I (Input): 输入(信号)

    • IE (Input Enable): 输入使能

    • PE (Pull Enable): 上下拉使能

    • PS (Pull Select): 上下拉选择

这些信号通过组合控制可实现推挽输出、开漏输出等功能。配置不当可能导致漏电。。

2.3.2 三种典型漏电模型

模型 1
  • 配置条件

    • OE=1(输出使能)

    • O=1(输出高)

    • PE=1(上下拉使能)

    • PS=0(下拉)

  • 漏电原理:高电平输出与下拉电阻形成回路

fishy
  • 电流计算公式:I = Vo/Rpd(Rpd:下拉电阻)

  • 错误配置示例

// PA31 输出高+下拉
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_PULLDOWN, 1);
BSP_GPIO_Set(31, 1, 1);
  • 修正方案

// 改为无上下拉
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);
BSP_GPIO_Set(31, 1, 1);
模型 2
  • 配置条件

    • OE=1(输出使能)

    • O=0(输出低)

    • PE=1(上下拉使能)

    • PS=1(上拉)

  • 漏电原理:低电平输出与上拉电阻形成回路

fishy
  • 电流计算公式:I = VDDIO/Rpu(Rpu:上拉电阻)

  • 错误配置示例

// PA31 输出低+上拉
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_PULLUP, 1);
BSP_GPIO_Set(31, 0, 1);
  • 修正方案

// 改为无上下拉
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);
BSP_GPIO_Set(31, 0, 1);
模型 3
  • 配置条件

    • IE=1(输入使能)

    • OE=0(输出关闭)

    • PE=0(无上下拉)

    • IO 浮空

  • 漏电原理:IO 电平处于 0~VDDIO 之间,导致输入单元 NMOS/PMOS 半导通

fishy
  • 电流计算公式:I = VDD/(Rnmos+Rpmos)

  • 错误配置示例

// PA31 无上下拉+浮空
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);
// 未调用 BSP_GPIO_Set 或 rt_pin_write 设置固定电平
  • 分析

    PA31 配置为nopull,没有上拉也没有下拉,没有调用BSP_GPIO_Set或者 rt_pin_write输出高或低电, IO外部处于浮空状态,没有对应的上下拉固定电平,电平有可能处于0和VDDIO之间,就会导致漏电,漏电大小取决半导通状态的阻抗

  • 修正方案

// 改为无上下拉
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);
BSP_GPIO_Set(31, 0, 1);

3. 漏电分析与 IO 正确配置

3.1 待机时 IO 正确配置规范

待机状态下,IO需通过合理配置避免漏电,以下为4种核心正确配置场景,覆盖不同使用需求:

配置场景

适用场景

配置示例

场景 1:IO 为 NC
(未使用)

未初始化的闲置 IO

无需额外配置(默认自带上下拉,避免浮空)

场景 2:IO 作为输出口

需输出高/低电平
(如外设使能)

// 无上下拉+输出低
HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1);
BSP_GPIO_Set(31, 0, 1);

场景 3:IO 作为输入口
(外部有电平)

外部有上下拉或外设固定电平
(如 UART)

// 无上下拉(依赖外部电平)
HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_NOPULL, 0);

场景 4:IO 作为输入口
(外部无电平)

外部无上下拉,电平不确定
(如唤醒源)

// 内部上拉固定电平
HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLUP, 0);
// 非唤醒源可设为高阻
HAL_PIN_Set_Analog(PAD_PB45, 0);

具体介绍如下:

3.1 正确配置1:IO口为NC(未使用)

  • 适用场景:整机中未启用、无任何功能关联的闲置IO(如预留但未焊接外设的引脚)。

  • 配置逻辑:无需初始化,芯片默认会为未配置IO加载内置上下拉(避免浮空漏电)。

  • 默认状态参考

    IO默认上下拉状态图

3.2 正确配置2:IO作为输出口(输出高/低电平)

  • 适用场景:IO需主动输出高电平或低电平以控制外设(如LCD电源使能、LED驱动等)。

  • 配置原则:输出口禁止配置上下拉(避免与输出电平冲突产生漏电流),统一使用 PIN_NOPULL(无上下拉)模式,再通过接口控制输出电平。

  • 配置代码示例

    // 1. 配置PA31:无上下拉(PIN_NOPULL),使能输出功能(第4个参数1=输出使能)
    HAL_PIN_Set(PAD_PA31, GPIO_A31, PIN_NOPULL, 1); 
    // 2. 控制PA31输出低电平(LCD_VCC_EN为PA31功能别名,第2个参数0=低电平,1=输出使能)
    BSP_GPIO_Set(LCD_VCC_EN, 0, 1); 
    

3.3 正确配置3:IO作为输入口(外部有稳定电平)

  • 适用场景:IO 作为输入,且外部存在硬件上下拉电阻,或连接的外设能持续提供稳定电平(如 UART 的 TX/RX 引脚、传感器数据输出引脚、按键固定电平引脚等)。

  • 配置原则:根据外部电路状态选择配置,避免内部上下拉与外部电平冲突:

    • 若外部已有上下拉电阻:IO 配置为 PIN_NOPULL(避免双重上下拉导致电流损耗);

    • 若外部电平稳定(无上下拉但外设输出固定):可配置为 PIN_PULLUP(增强高电平稳定性)或 PIN_NOPULL。

  • 配置代码示例
    示例1:外部已有上下拉,IO配置为无上下拉

    // USART3_TX(PB45)、USART3_RX(PB46)作为输入,外部已有上下拉,配置为无内部上下拉
    HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_NOPULL, 0);  // 第4个参数0表示使能输入功能
    HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_NOPULL, 0);
    

    示例2:外部无上拉,IO 配置为内部上拉(补充稳定电平)

    // USART3_TX、USART3_RX配置为内部上拉,使能输入功能
    HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLUP, 0); 
    HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_PULLUP, 0); 
    
  • 外部上拉电路参考

    fishy

3.4 正确配置 4:IO 作为输入口(外部无稳定电平)

  • 适用场景:IO 作为输入,但外部无上下拉电阻,且连接的外设无法提供稳定电平(如悬空的预留输入引脚、未接外设的传感器接口引脚等)。

  • 配置原则:需通过内部配置固定电平,避免浮空漏电,需区分普通 IO 与唤醒源 IO:

    • 普通 IO(非唤醒源):可选择 “内部上拉 / 下拉” 或 “高阻态”;

    • 唤醒源 IO:仅可配置 “内部上拉 / 下拉”(禁止高阻态,存在漏电风险)。

  • 配置代码示例
    示例 1:普通 IO 配置为内部上拉 / 下拉

     // 非唤醒源IO(PB45、PB46)配置为内部上拉
     HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLUP, 0); 
     HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_PULLUP, 0); 
     
     // 或配置为内部下拉(根据实际需求选择)
     HAL_PIN_Set(PAD_PB45, USART3_TXD, PIN_PULLDOWN, 0); 
     HAL_PIN_Set(PAD_PB46, USART3_RXD, PIN_PULLDOWN, 0); 
    

    示例2:示例 2:普通 IO 配置为高阻态(仅非唤醒源可用)

    // 非唤醒源IO设置为高阻态(模拟输入模式,无电流通路)
    HAL_PIN_Set_Analog(PAD_PB45, 0); 
    HAL_PIN_Set_Analog(PAD_PB46, 0); 
    
  • 唤醒源 IO 特殊说明
    唤醒源 IO 因硬件设计特性,需与普通 IO 区分配置,核心注意事项如下:

    1. 禁止高阻态的原因
      带唤醒功能的 IO 内置独立“唤醒输入通道”,即使主 IO 配置为高阻态,该唤醒通道仍需维持稳定电平;若电平悬空(高阻态),会符合“漏电模型3”(电平波动导致 NMOS/PMOS 半导通),产生 0~200uA 不等的漏电。因此必须通过内部或外部上下拉固定电平,杜绝悬空。

    2. 各平台唤醒源 IO 范围

      • 52x 平台:PA28 ~ PA44(连续引脚段,覆盖主流唤醒场景)

      • 56x 平台:PA50 ~ PA54、PB32 ~ PB36、PBR0 ~ PBR3(多组离散引脚,适配不同硬件布局)

    3. 唤醒源 IO 配置示例

      若外部无上下拉,配置为内部上拉(固定高电平):

      // 场景:52x 平台唤醒 IO PA30(外部无上下拉),配置内部上拉固定电平
      // 参数说明:PAD_PA30=引脚标识,WAKEUP_IO=唤醒功能别名,PIN_PULLUP=内部上拉,0=使能输入功能
      HAL_PIN_Set(PAD_PA30, WAKEUP_IO, PIN_PULLUP, 0); 
      

      若外部已有下拉电阻(固定低电平),则需匹配配置为内部下拉:

      // 外部为低电平,配置内部下拉避免冲突
      HAL_PIN_Set(PAD_PA30, WAKEUP_IO, PIN_PULLDOWN, 0); 
      

特殊说明:唤醒源 IO

  • 定义:可触发系统唤醒的 IO(如 52x 的 PA28~PA44,56x 的 PA50~PA54);

  • 限制:不能配置为高阻态(唤醒输入通道存在漏电风险),必须通过内部/外部上下拉固定电平。

3.2 漏电分析方法(实操)

方法 1:pin status 命令

  • 操作步骤

    • 执行 pin status all 查看所有 IO 配置

    • 检查“上下拉配置”与“实际电平”是否冲突(如模型 1/2)
      如下图中,pin19 配置为上拉,实际电平却为低,则会通过上拉电阻漏电,参考《漏电模型2》

fishy
  • 适用场景:快速定位配置冲突类漏电(如“上拉+低电平”)

  • 优势:无需debug,直接查看配置

方法 2:Ozone 寄存器调试

  • 操作步骤

    1. 通过 Ozone 连接设备,手动修改 IO 寄存器为高阻

    2. 观察电流变化,定位漏电源
      下图中记录了电流波形对应的电平翻转情况,以此分析对应的代码执行电流是否符合预期。

fishy
  • 适用场景:不确定漏电源的场景

  • 优势:精准定位单个 IO 漏电

方法 3:代码执行时间分析

  • 操作步骤

    1. 代码中增加 tick 打印或 IO 电平翻转

    2. 结合 PPK2 观察电流波形与代码执行的关联

  • 适用场景:代码逻辑导致的异常功耗(如循环未休眠)

  • 优势:区分“硬件漏电”与“软件逻辑功耗”

3.3 典型漏电案例(避坑指南)

案例 1:ADC pin 配置错误

  • 漏电场景:ADC 功能未启用,但 pinmux 配置为 ADC 模式

  • 原理图

fishy
  • 根本原因:未使用的 ADC 引脚仍保持模拟输入模式,导致漏电

  • 解决方案:用宏包裹 ADC 配置,未启用时设为普通 IO:

    #ifdef BSP_USING_ADC1
    HAL_PIN_Set_Analog(PAD_PA32, 1);
    #else
    HAL_PIN_Set(PAD_PA32, GPIO_A32, PIN_NOPULL, 1);
    #endif
    

案例 2:下拉电阻阻值过小

  • 漏电场景:Audio 使能 pin 下拉电阻 10kΩ,输出高电平时漏电 180μA

  • 原理图

fishy
  • 根本原因:下拉电阻阻值过小,导致高电平输出时回路电流过大
    当PA_28_AUDIO_PA_CTRL的置高时,由于下拉电阻只有10k,导致漏电发生。
    漏电电流大致:1.8v/10k = 180uA电流。

  • 解决方案:更换为 1MΩ 电阻,漏电降至 1.8μA

案例 3:多外设共享 IO 上电时序错误

  • 漏电场景:PB23 同时控制电源芯片、Gsensor、心率传感器,供电不同步导致漏电

  • 原理图

fishy
  • 根本原因:外设上电时序不一致,部分设备未供电时 IO 电平冲突

  • 解决方案:确保 3 个外设同时供电,且 I2C 上拉供电正常

案例 4:中断触发方式与上下拉不匹配

  • 漏电场景:上升沿触发中断,但 IO 配置为下拉(模型 2 漏电)

  • 根本原因:中断触发边沿与上下拉配置冲突,形成持续漏电回路

  • 解决方案

    • 上升沿触发→配置上拉/无外部上拉

    • 下降沿触发→配置下拉/无外部下拉

案例 5:心率传感器掉电后 IO 配置未更新

  • 漏电场景:VC32S 掉电后,reset pin 仍保持高电平,导致向器件漏电

  • 原理图

fishy
  • 根本原因

    • 外设掉电后 IO 仍维持高电平,通过内部电路形成漏电路径

    • vc32s 驱动关闭后但供电不关闭,reset pin继续保持为高,也不会漏电;

    • 但当vc32s 驱动关闭后但供电也关闭的时候,reset pin继续保持为高,就会造成大漏电

  • 解决方案:掉电时将 reset pin 配置为低电平或高阻,上电后恢复高电平

4.待机低功耗分析与优化

4.1 低功耗配置策略

  1. HCPU的频率配置

配置项

CPU主频

亮屏

240MHz

息屏,CPU工作

48MHz

CPU idle

55x/56x/58x:1MHz,52x:4MHz

睡眠

OFF。RTC选择32KHz(外部) or RC10KHz(内部)

  1. 配置策略

配置项

优化目标

配置方法

idle时自动降频

idle时自动降低 CPU 频率

menuconfig启用“自动降频”,5x/56x/58x上是1MHz,52x是4MHz

LCD关闭时频率调整

降低CPU 频率

sifli_pm_runPM_RUN_MODE_MEDIUM_SPEED)设置为48MHz

睡眠时钟源选择

避免 RC10K 周期性校准功耗

优先使用外置 32K 晶振(menuconfig 中取消“使用 RC10K”选项)

Flash 待机配置

待机时让 Flash 进入睡眠模式

- 在 BSP_Power_Down() 中调用 rt_flash_power_down()
- 在BSP_Power_Up() 中恢复

PSRAM 待机配置

待机时让 PSRAM 进入半睡眠模式

- 在 BSP_Power_Down() 中调用 rt_psram_enter_low_power()
- 在BSP_Power_Up()中恢复

4.1.1 idle时自动降频的配置

自动降频功能是指CPU空闲时自动降低频率,忙碌时恢复高频,以此降低功耗。 menuconfig配置如下:

自动降频配置界面

4.1.2 LCD关闭时频率调整

CPU运行且LCD关闭状态下,MCU 会自动切换频率降低功耗。具体运行频率可通过以下方式修改:

fishy

4.1.3 RC10K / 外置 32K 的配置

  • RC10K:内部时钟,需周期性校准,会增加功耗;

  • 外置 32K:依赖外部晶振,可减少功耗,但需额外硬件成本。

menuconfig配置如下:

fishy

(选中表示使用 RC10K,未选中表示使用外置 32K)

4.1.4 Flash 待机的配置

待机时需使 Flash 进入睡眠状态,可在BSP_Power_Up()BSP_Power_Down()中添加如下接口:

  • Flash 进入睡眠:

#if  defined(BSP_USING_NOR_FLASH2)
#ifdef BSP_QSPI2_DUAL_MODE
    rt_flash_enable_lock(0);
    rt_flash_power_down(0x13000000, 1); // 深度睡眠:双总线Flash B
    HAL_Delay_us(50);
#endif
    rt_flash_power_down(0x12000000, 1); // 深度睡眠:双总线Flash A
    HAL_Delay_us(50);
#endif
  • Flash 退出睡眠:

#if   defined(BSP_USING_NOR_FLASH2)
    rt_flash_power_down(0x12000000, 0); // 退出睡眠:双总线Flash A
    HAL_Delay_us(50);
#ifdef BSP_QSPI2_DUAL_MODE
    rt_flash_power_down(0x13000000, 0); // 退出睡眠:双总线Flash B
    HAL_Delay_us(50);
    rt_flash_enable_lock(1);
#endif 
#endif

4.1.5 PSRAM 待机的配置

待机时需使 PSRAM 进入半睡眠(half-sleep)状态,可在BSP_Power_Up()BSP_Power_Down()中添加如下接口:

  • PSRAM 进入半睡眠:

#if defined(BSP_USING_PSRAM1)
    rt_psram_enter_low_power("psram1");
#endif
  • PSRAM 退出半睡眠:

#if defined(BSP_USING_PSRAM1)
    rt_psram_exit_low_power("psram1");
#endif

4.2 Sensor 待机功耗优化(核心场景)

sensor 读取数据和算法处理会周期性的运行,从功耗优化的角度,从以下两个方面着手:

  1. 选择合适的通信接口:接口功耗低且读取sensor数据的时间短;

  2. 优化处理时间,以便尽快进入睡眠

4.2.1 通信接口选择

一般来讲,MCU与sensor器件接口主要包括以下几种:

通信接口

速度(Hz)

优势

劣势

优化措施

I2C

- 100k
- 200k
- 400k

引脚少(2 线), 支持多设备

速度最慢

  1. 选用 400k Hz 时钟,搭配 2.2k/4.7k 上拉电阻;

  2. rt_i2c_mem_read/write() 减少传输间隔;

  3. 连续寄存器用 FIFO 连读;

  4. 支持 DMA 则启用

SPI

- 2M
- 4M
- 8M
- 12M
- 24M
- 48M

速度最快

引脚多(4/6 线)

  1. 选用 8M~24M Hz 时钟;

  2. 启用 DMA;

  3. 缓冲区用 RAM 存储

UART

- 1M
- 2M
- 3M
- 4M
- 6M

引脚少(2 线), 速度适中

无时钟信号, 需波特率匹配

  1. 选用更高的波特率;

  2. RX 端启用 DMA

4.2.2 算法存储位置调整

代码和数据存放的位置决定了算法处理的时间,访问速度SRAM > PSRAM > Flash。因此在RAM够用的情况下,尽可能的把访问频繁的code以及data放在ram中,将提高运行效率。
注意: Solution 2.0中,所有工程都开启了PSRAM Write Back,因此写PSRAM的效率和SRAM相差不大。但建议算法线程的栈一定要放在SRAM中,避免PSRAM cache访问命不中造成的换入换出。

以下是传感器代码与数据的存储位置配置示例:

4.2.2.1 示例1:将Sensor代码(RO段)放入PSRAM

用途
通过脚本配置,将传感器相关代码(如驱动、算法逻辑等只读代码段)存储到PSRAM,优化运行效率。

配置脚本

// RW_PSRAM_RET:PSRAM存储区域(ZI数据段,非缓存,保留)
RW_PSRAM_RET PSRAM_DATA_START_ADDR {  
  ido_algo*.o (+RO)                  // 所有以ido_algo开头的.c文件生成的代码(RO段)
  sdrv*.o     (+RO)                  // 所有以sdrv开头的.c文件生成的代码(RO段)
  *.o         (sys_timer_handle)     // 所有包含sys_timer_handle符号的.c文件代码(RO段)
  *.o         (ido_algo_activity_result) // 所有包含ido_algo_activity_result符号的.c文件代码(RO段)
  *ido_alg_m33_V1_0_42*lib (+RO)     // 所有包含ido_alg_m33_V1_0_42的库文件代码(RO段)
  app_sensor_thread.o (+RO)          // app_sensor_thread.c文件生成的代码(RO段)
  *gsensor*.o         (+RO)          // 所有包含gsensor的.c文件生成的代码(RO段)
}

脚本含义:

  • 利用通配符*匹配相关文件 / 符号,批量将传感器相关代码(RO 段,只读代码)存入 PSRAM;

  • (+RO)表示指定存储代码段(Read-Only,只读数据 / 指令)。

4.2.2.2 示例2:将 Sensor 数据(RW/ZI 段)放入 SRAM

用途:
将传感器相关数据(已赋值变量、未赋值变量)存储到 SRAM,提升数据读写速度。

配置脚本

// RW_IRAM_RET:SRAM存储区域
RW_IRAM_RET +0 {    
  *ido_alg_m33_V1_0_42*lib (+RW +ZI)  // 包含ido_alg_m33_V1_0_42的库中,已赋值变量(RW)和未赋值变量(ZI)
  ido_algo*.o (+RW +ZI)               // 所有以ido_algo开头的.c文件中,已赋值变量(RW)和未赋值变量(ZI)
}

脚本含义:

  • (+RW):指定存储已初始化且赋值的变量(Read-Write,读写数据);

  • (+RW +ZI):同时存储已赋值变量(RW)和未赋值变量(ZI,Zero-Initialized,初始化为 0 的变量);

  • 通过通配符批量匹配传感器相关数据,存入 SRAM 以提高访问效率。

4.2.3 睡眠唤醒优化

  • 唤醒时机:按 Sensor 采样周期唤醒(如心率 1 次/分钟,Gsensor 5 次/秒),避免频繁唤醒;

  • 唤醒后处理:快速完成数据采集与算法计算,立即返回低功耗模式,减少唤醒时长。

4.3 待机功耗拆解方法

拆解方法

操作步骤

适用场景

示例(以“总待机功耗 100μA”为例)

加法拆解

  1. 测量“最简待机功耗”(仅核心系统,无外设);

  2. 逐个启用功能(如 BT→BLE→计步→心率);

  3. 增量功耗=当前总功耗-最简功耗

新系统
功能模块清晰

最简功耗 30μA

启用 BT 后 50μA(BT 增量 20μA)

启用心率后 100μA(心率增量 50μA)

减法拆解

  1. 测量“全功能总功耗”;

  2. 逐个剥离功能;

  3. 功能功耗=剥离前功耗-剥离后功耗

现有系统
需定位高功耗功能

全功能 100μA

剥离心率后 50μA(心率功耗 50μA)

剥离 BT 后 30μA(BT 功耗 20μA)

4.4 辅助工具:功耗拆解命令

通过命令单独启用/禁用功能,便于精准测量:

  • 启用计步:sensor enable step

  • 禁用心率:sensor disable hr

  • 查看功能状态:sensor status all

5. 关机低功耗分析与配置

5.1 关机模式与参考功耗

平台

关机模式

参考功耗(μA@3.8V)

核心特性

56x

Standby

HDK561:10.76
HDK563:13.59
HDK6700:13.55

关闭外设供电,HCPU/LCPU 均进入 Standby

52x

Hibernate

HDK521:2.34
HDK523:2.2
HDK525:2.24

仅保留唤醒电路,IO 高阻(唤醒源除外)

58x

Hibernate

em_587_nor A1: 2.2

5.2 Standby / Hibernate配置

在 menuconfig 中启用“Standby 关机”:

fishy

选中时,表示standby关机;没选中,表示Hibernate关机。

5.3 Standby 关机优化.

5.3.1 Standby 关机功耗分析

以HDK56x 平台为例。

5.3.1.1 基础机制

HDK56x 进入 Standby 关机时,HCPU 与 LCPU 需协同进入低功耗状态:

  • HCPU:关闭 PSRAM、Flash、LCD、TP 等外设供电,关闭大部分唤醒源,核心休眠;

  • LCPU:关闭传感器、蓝牙等外设,尽可能切断外设供电。

5.3.1.2 常见问题及解决方案
问题1:LCPU 进入 Standby 失败,整机漏电 ~1mA

核心原因:大核(HCPU)与小核(LCPU)通过 data_service 传输的数据未接收完毕。

解决措施: 通过 ipc_queue_check_idle() 确认数据传输状态,未完成时增加等待延时:

  • HCPU 端调整pm_shutdown()

void pm_shutdown(void)
{
#ifdef BSP_PM_STANDBY_SHUTDOWN
    // 省略部分代码

    // 关闭所有唤醒源
    HAL_HPAON_DisableWakeupSrc(HPAON_WAKEUP_SRC_RTC);
    /****************/
    rt_thread_mdelay(150); // 数据未传输完成时,增加延时
    /****************/
    HAL_HPAON_DisableWakeupSrc(HPAON_WAKEUP_SRC_LPTIM1);
    HAL_HPAON_DisableWakeupSrc(HPAON_WAKEUP_SRC_LP2HP_IRQ);

    MODIFY_REG(hwp_pmuc->LPSYS_SWR, PMUC_LPSYS_SWR_PSW_RET_Msk,
            MAKE_REG_VAL(1, PMUC_LPSYS_SWR_PSW_RET_Msk, PMUC_LPSYS_SWR_PSW_RET_Pos));
    BSP_Standby_PowerDown();

    sys_set_is_power_on(false);
    rt_thread_mdelay((RT_TICK_MAX / 2) - 1);
    // 省略部分代码
#endif
}
  • LCPU 端调整: power_off_standby_cb()

static void power_off_standby_cb(void)
{
    rt_kprintf("%s!\n", __func__);

#if defined(BF0_LCPU) || defined(SOC_SF32LB52X)
    button_service_mock_in_standby(); // 接管 "btn0" 服务,确保待机状态下按键功能正常
#endif

    ipc_send_lcpu_msg_to_hcpu(LCPU_PWR_OFF_RSP, NULL, 0); // 向 HCPU 发送关机响应消息
    /****************/  
    rt_thread_mdelay(300); /* 增加延时,避免 LCPU 端 data service 数据未读取完成 */
    /****************/
    // 接管 "SENSORS_APP" 服务,确保传感器相关资源在待机前正常释放
    datac_handle_t lcpu_service = datac_open();
    RT_ASSERT(DATA_CLIENT_INVALID_HANDLE != lcpu_service); // 断言检查服务句柄有效性
    datac_subscribe(lcpu_service, "SENSORS_APP", standby_service_cb, 0);
    // 省略部分代码(如其他外设资源释放、待机状态确认等逻辑)
}
问题2:睡眠模式请求/释放未配对,导致睡眠失败
  • 核心原因

    • rt_pm_request(PM_SLEEP_MODE_IDLE)(申请IDLE睡眠模式)与 rt_pm_release(PM_SLEEP_MODE_IDLE)(释放IDLE睡眠模式)未成对调用,导致系统睡眠状态计数器异常,无法正常触发Standby关机。

  • 分析方法
    通过打印全局变量 __pm.modes[PM_SLEEP_IDLE] 的值进行判断:

    • 若该值 大于 0:说明存在未释放的 rt_pm_request 调用(即申请次数多于释放次数),需在对应业务逻辑中补充 rt_pm_release 接口,确保“申请-释放”次数完全匹配。

    • 示例场景:若在传感器初始化时调用 rt_pm_request 禁止睡眠,需在传感器销毁时调用 rt_pm_release 恢复睡眠权限,否则会导致睡眠模式被持续占用。

问题3:关机功耗高于参考值
  • 核心原因

    • 外设掉电后IO配置未及时更新,仍维持可能产生漏电的状态(如器件已断电,但IO仍配置为上拉),符合前文提到的“漏电模型1”或“漏电模型2”。

  • 排查与解决方向

    • 重点关注外设:Flash、PSRAM、心率传感器、加速度计等与IO强关联的器件;

    • 配置检查逻辑:在 BSP_Standby_PowerDown() 或类似关机准备函数中,增加外设掉电后的IO配置更新代码:

      • 示例:若心率传感器掉电,需将其复位IO(reset pin)从“上拉”改为“高阻”或“下拉”,避免悬空或冲突电平;

    • 验证方法:通过万用表测量关键IO的电平状态,确认外设掉电后IO无持续电流通路。

5.3.2 Hibernate 关机功耗分析

5.3.2.1 Hibernate 模式下的 IO 状态
  • 普通 IO(无唤醒功能)
    进入Hibernate后自动切换为高阻态,内部无漏电通路,对外呈现高阻特性(无需额外配置);

  • 唤醒 IO(带唤醒功能)
    额外集成唤醒输入电路,需通过“内部PMU上下拉”或“外部上下拉电阻”固定电平——若电平悬空,会触发“漏电模型3”(IO电平在0~VDDIO间波动,导致NMOS/PMOS半导通漏电)。

5.3.2.2 不同平台唤醒 IO 漏电分析及配置
(1)55X 平台
  • 关键特性
    Hibernate关机后,pinmux模块的上下拉配置会掉电失效,且唤醒IO无内置PMU上下拉电路,完全依赖外部硬件设计;

  • 漏电风险
    若唤醒IO外部悬空,漏电电流约 0~200uA(因电路板寄生参数差异波动);

  • 解决方案
    在硬件设计阶段,为唤醒IO增加外部上下拉电阻(建议10kΩ~100kΩ),软件无需额外配置(仅需确保Hibernate前IO电平与外部电阻匹配)。

(2)52X 平台
  • 关键特性
    Hibernate关机后,pinmux上下拉掉电,但唤醒IO(如PA28~PA44)带可配置的不掉电PMU上下拉,可通过寄存器单独控制;

情况1:PMU上下拉未配置/外部电平不确定
  • 漏电风险
    PMU上下拉默认未使能,唤醒IO悬空,符合“漏电模型3”,漏电约0~200uA;

  • 正确配置
    (在 pm_shutdown() 函数中补充):

    // 配置PA28~PA44唤醒IO:使能上下拉 + 设为下拉(避免悬空)
    hwp_rtc->PAWK1R = 0x0001ffff; // PA28~PA44上下拉使能(bit0=PA28,bit1=PA29...)
    hwp_rtc->PAWK2R = 0x0000;     // 所有唤醒IO设为下拉(0=下拉,1=上拉)
    
情况2:PMU 上下拉与外部电平冲突
  • 核心问题
    PMU 上下拉配置方向与唤醒 IO 外部实际电平相反,形成持续漏电路径,符合前文“漏电模型2”(低电平与上拉冲突或高电平与下拉冲突)。

  • 错误示例
    若唤醒 IO PA24 外部硬件设计为固定低电平(如接GND),但软件配置为 PMU 内部上拉,会导致电流通过上拉电阻流向外部低电平,产生持续漏电:

    // 错误配置:PMU内部上拉与外部低电平冲突
    HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_PULLUP, 1);
    
  • 原因分析

    • 上拉配置使 IO 引脚维持高电平趋势,而外部低电平强制拉低引脚,两者形成电压差(差值约等于系统供电电压,如3.3V)。根据欧姆定律,该电压差会驱动电流持续流过 PMU 内部上拉电阻,形成固定漏电路径——即使系统进入 Hibernate 模式,该电流仍会存在,导致关机功耗高于参考值。

  • 解决方案:遵循“配置与外部电平匹配”原则,分两步操作:

    1. 硬件电平确认

      • 通过原理图或万用表测量,明确唤醒 IO 外部实际电平(如接 GND 为低电平、接 VCC 为高电平、接其他模块为动态电平需额外评估);

    2. 软件配置调整:根据外部电平修改 PMU 上下拉参数,避免电压差产生:

      • 若外部为 低电平(如接 GND):将 IO 配置为“PMU 下拉”或“高阻态”,禁止上拉;

      • 若外部为 高电平(如接 VCC):将 IO 配置为“PMU 上拉”或“高阻态”,禁止下拉;

      • 若外部为 动态电平(如接传感器输出):需在进入 Hibernate 前,确保外部模块已掉电或输出固定电平,再匹配 IO 配置。

  • 正确配置示例(外部低电平场景)
    若唤醒 IO PA24 外部接 GND(低电平),需将 PMU 配置改为下拉,代码如下:

    // 正确配置:外部低电平时,启用 PMU 下拉,避免电压差
    HAL_PIN_Set(PAD_PA24, GPIO_A24, PIN_PULLDOWN, 1);
    
  • 验证方法
    配置完成后,进入 Hibernate 模式,用万用表测量唤醒 IO 引脚电流 —— 若电流接近 0(或小于 1uA),说明漏电路径已消除;若仍有明显电流,需重新检查外部电平与软件配置的匹配性。

6. 总结

低功耗优化的核心是 “精准定位 + 针对性配置”

  1. 工具选型:移动场景用 PPK2,实验室用 34465A/EMK850x;

  2. 漏电规避:按 3 种模型检查 IO 配置,重点关注唤醒源 IO;

  3. 待机优化:基础配置降频 / 选时钟,Sensor 优化通信 / 存储 / 唤醒;

  4. 关机优化:56x 关注 Standby 数据同步,52x 关注唤醒 IO 上下拉。

通过以上方法,可将系统功耗控制在参考范围内,满足低功耗产品需求。