当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]STM32WLE 的休眠功耗优化,有一个容易被忽视的前提:LoRaWAN 协议栈本身并不“直接”让你调用 `HAL_PWREx_EnterSTOP2Mode()`。ST 的 `LoRaWAN_End_Node` 例程中,协议栈的调度器 `MX_LoRaWAN_Process()` 是一个永不退出的循环,它会在没有任务可运行时自动进入 Stop2 模式。如果你在它后面直接写休眠代码,那些代码永远不会被执行。正确的做法是把“进入低功耗”本身注册为一个任务,交给协议栈的调度器去执行。

STM32WLE 的休眠功耗优化,有一个容易被忽视的前提:LoRaWAN 协议栈本身并不“直接”让你调用 `HAL_PWREx_EnterSTOP2Mode()`。ST 的 `LoRaWAN_End_Node` 例程中,协议栈的调度器 `MX_LoRaWAN_Process()` 是一个永不退出的循环,它会在没有任务可运行时自动进入 Stop2 模式。如果你在它后面直接写休眠代码,那些代码永远不会被执行。正确的做法是把“进入低功耗”本身注册为一个任务,交给协议栈的调度器去执行。

Stop2 的功耗基线:1.07µA 与 360nA 的差距

数据手册给出了明确的功耗分级:Stop2 + RTC 为 1.07 µA,Standby + RTC 为 360 nA,Shutdown 为 31 nA。Stop2 保留了 SRAM 和 CPU 寄存器内容,唤醒后可以继续执行,唤醒源包括 RTC、EXTI 和 Sub-GHz 射频;Standby 只保留 SRAM2(需配置 RRS 位),系统时钟在唤醒后复位为 MSI 4MHz,外设需要重新初始化;Shutdown 则完全断电,唤醒等同于复位。

对于 LoRaWAN Class A 节点,Stop2 是默认的休眠目标。协议栈的 RX1/RX2 窗口定时器依赖 RTC,Sub-GHz 射频需要在休眠期间保持对前导码的检测能力(如果开启了 Class B 或需要接收下行),这两项在 Stop2 下都可以保留。代价是 1.07µA 的基线电流,相比 Standby 高出约 0.7µA,但换来了唤醒后无需重新初始化射频和协议栈的便利。

进入 Stop2 的正确路径:任务而非直接调用

ST 社区的一个关键回复澄清了这一点:`MX_LoRaWAN_Process()` 启动的是一个音序器,当没有任务就绪时,它会进入一个 IDLE 任务,由该任务设置 Stop 模式。因此,想要在 LoRaWAN 通信完成后进入休眠,不能在 `MX_LoRaWAN_Process()` 之后追加 `HAL_PWREx_EnterSHUTDOWNMode()`,而应该通过 `UTIL_SEQ_RegTask()` 注册一个低功耗任务,在任务回调中调用 `HAL_PWREx_EnterSTOP2Mode()`。

一个实际的低功耗工程实践给出了 STOP2 <1µA 的配置清单:CubeMX 中将未使用的 GPIO 全部设为模拟模式(杜绝浮空引脚漏电);关闭调试接口(SYS → Debug → Disable);清空 `sys_app.c` 中的日志输出函数体,关闭串口和 LED;主循环中调用 `MX_LoRaWAN_Process()`,协议栈在空闲时自动进入 Stop2。这份清单中“GPIO 全模拟”的细节值得特别注意——一条浮空的 GPIO 在输入模式下可能因外部电平不确定而产生微安级的漏电,足以让 1µA 的基线翻倍。

Stop2 唤醒后的恢复:SPI 与射频栈必须重新初始化

Stop2 模式下,SPI 外设不可用,Sub-GHz 射频栈的 SPI 接口同样不可用(射频本身可以在 Stop2 下独立运行,但其 SPI 控制接口在 Stop2 中不保持功能)。这意味着如果应用在 Stop2 唤醒后需要通过 SPI 与外部传感器通信,或者需要重新配置射频参数,必须在唤醒后重新初始化 SPI 外设,并重新建立 Sub-GHz 射频与 MCU 之间的 SPI 通信链路。

ST 社区的建议是:Sub-GHz/SPI 栈在 Stop2 下不可用,唤醒后需要完整重新初始化;如果希望 SPI 在休眠期间保持功能,应使用 Stop0 或 Stop1 模式,而非 Stop2。Stop1 的功耗高于 Stop2(具体数值需查阅数据手册中 Stop1 的 RTC 模式电流),但保留了更多外设的上下文,适合需要频繁通过 SPI 与外部器件交互的场景。

RTC Alarm 的干扰:进入 Stop2 前必须处理

一个常见的调试陷阱是:RTC Alarm 在进入 Stop2 前未正确配置,导致 MCU 刚进入休眠就被立即唤醒。LoRaWAN 协议栈使用 RTC 作为定时器服务器,RX 窗口定时器和重传退避都依赖它。如果应用层额外设置了 RTC Alarm,而该 Alarm 的到期时间落在 Stop2 期间,MCU 会被唤醒并执行 Alarm 回调,打断休眠。

处理方式取决于应用需求:如果 Alarm 仅用于应用层的周期性任务,应将其到期时间安排在预期的唤醒时刻之后,或在进入 Stop2 前暂时禁用;如果 Alarm 是唤醒源本身(例如周期唤醒发送数据),则需要确保 Alarm 的触发时机与 LoRaWAN 的 RX 窗口不冲突——否则 MCU 可能在 RX 窗口期间被 Alarm 唤醒,打乱协议栈的时序。

Standby 与 Shutdown 的适用边界

对于上报周期极长(如数小时一次)的传感器节点,Standby 的 360nA 相比 Stop2 的 1.07µA 具有吸引力。但 Standby 唤醒后系统时钟复位为 MSI 4MHz,SRAM1 内容丢失(仅 SRAM2 可通过 RRS 位保留),射频和协议栈需要完整重新初始化。如果 LoRaWAN 的 Join 状态和帧计数器存储在 SRAM 中而非 Flash/EEPROM 中,Standby 唤醒后将丢失入网状态,需要重新 Join——这通常不是期望的行为。因此,Standby 更适合那些将入网状态持久化到非易失存储、且对唤醒后重新初始化的时间开销不敏感的应用。

Shutdown 的 31nA 适用于运输模式或长期仓储场景,但在 LoRaWAN 节点正常工作中极少使用,因为每次唤醒都等同于一次冷启动。

结语

STM32WLE 的 LoRaWAN 休眠优化,核心认知是:Stop2 是 Class A 节点的默认休眠目标,1.07µA 的基线电流足以支撑数年续航,但前提是 GPIO 全部设为模拟模式、调试接口关闭、未使用外设时钟停用。进入 Stop2 的路径不是直接调用 HAL 函数,而是通过协议栈调度器注册低功耗任务。唤醒后 SPI 和射频栈必须重新初始化,RTC Alarm 需在进入休眠前妥善处理。如果应用需要 SPI 在休眠期间保持功能,Stop1 是必要的妥协。Standby 的 360nA 只在入网状态已持久化、且可接受唤醒后完整初始化的场景中才是合理选择。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭