单片机WFI指令真的可以进入低功耗状态吗?

strongerHuang 2026-09-05 08:00

WFI(Wait For Interrupt)指令,常用于让 MCU 进入低功耗状态。

单片机WFI指令真的可以进入低功耗状态吗?图1

但很多工程师不知道的是:执行 WFI 并不一定保证 MCU 会进入低功耗模式,在某些情况下它会被直接当做 NOP 执行。

单片机WFI指令真的可以进入低功耗状态吗?图2

如果在执行 WFI 的那一刻,NVIC 里已经存在一个"使能且优先级足够"的 pending 中断,那么WFI就会被当做NOP执行。

听起来有点抽象,看下面几个例子就明白了: 

1)示例1:pending + 使能 → WFI 被当 NOP

SCB->SCR |= (1<<2);   
NVIC_EnableIRQ(TIM3_IRQn);
NVIC_SetPendingIRQ(TIM3_IRQn); 
__WFI();
现象: MCU 没有进入 DeepSleep,电流无明显下降。单片机WFI指令真的可以进入低功耗状态吗?图3

原因: TIM3 中断已经 pending 且使能,处理器判定"有中断待处理",WFI 立即返回,等效于 NOP。

2)示例 2:pending 但未使能 → 正常进入 DeepSleep

单片机WFI指令真的可以进入低功耗状态吗?图4
现象:MCU 正常进入 DeepSleep,电流降至 
μA 级。
单片机WFI指令真的可以进入低功耗状态吗?图5
原因: 虽然 TIM3 的 pending 位被置位,但中断未使能,NVIC 不会向处理器提交该异常,WFI 条件检查通过,正常休眠。


3)示例 3:__disable_irq() + pending → 仍然不进 DeepSleep

SCB->SCR |= (1<<2);   
NVIC_EnableIRQ(TIM3_IRQn);
NVIC_SetPendingIRQ(TIM3_IRQn); 
__disable_irq(); 
__WFI();
原因:__disable_irq() 设置 PRIMASK = 1,屏蔽所有可配置中断。此时执行 WFI,处理器仍然检测到 pending 异常(TIM3),WFI 被当做 NOP 执行。

4) 示例4:中断服务函数中调用 WFI——优先级决定一切
void EXTI2_3_IRQHandler(void)
{
    if (std_exti_get_pending_status(EXTI_LINE_GPIO_PIN3))
    {
        std_exti_clear_pending(EXTI_LINE_GPIO_PIN3);             
    }
     
  SCB->SCR |= (1<<2); 
  NVIC_EnableIRQ(TIM3_IRQn);
  NVIC_SetPriority(TIM3_IRQn, NVIC_PRIO_0);
  NVIC_SetPendingIRQ(TIM3_IRQn); 
    
 __WFI();   
}

现象: WFI 没有进入 DeepSleep。

原因: TIM3 优先级(0)高于当前正在执行的 EXTI 中断优先级(1)。Cortex-M 规则是:只有 pending 中断的优先级严格高于当前异常优先级时,WFI 才会被唤醒。这里 TIM3 优先级更高,处理器判定它可以在退出当前 ISR 后立即抢占,因此 WFI 不生效。

如果将 TIM3 优先级改为 1 或 2(≤ 当前优先级),则 TIM3 无法抢占,WFI 正常进入 DeepSleep。

WFI 的"检查 pending 中断"机制意味着:任何在 WFI 执行瞬间已经 pending 且使能的中断,都会阻止 MCU 进入低功耗模式。即使某个外设中断不是你配置的 DeepSleep 唤醒源(比如 TIM3 在 DeepSleep 下时钟被关),它的 NVIC pending 位仍然可能在进入 WFI 前被意外置位,从而阻止休眠。所以如果你不希望出现上述情况,在进入DeepSleep前要调用NVIC_ClearPendingIRQ()清除掉相关标志位,或者清除标志位且从源头上关掉这个中断,唤醒后需要的话再重新开启。

------------ END ------------

关于科技区角:国内科技展会垂直内容策划服务商,提供从论坛内容全案策划、会展市场化IP打造到精准专业观众一站式邀约服务,以产业内容吸引高质量B端人群,打通展会从议题设计、演讲嘉宾邀约、宣传预热、精准邀观到供需对接全链路。
声明:内容取材于网络,仅代表作者观点,如有内容违规问题,请联系处理。
单片机
more
单片机开发中常用的7种滤波算法!
不会写单片机不会画电路板?做完这个四轴飞行器,我把STM32和PCB全搞懂了!
单片机中断变量加volatile的好处......
单片机OTA传输协议深入分析
单片机虚拟EEPROM模块的应用
如何将单片机变量“钉”在Standby RAM中?
【有奖评测 】最强Cortex-M85单片机!RA8D1套件(显示屏+摄像头)免费评测
同样的单片机代码,编译后的hex为啥会变?
最强Cortex-M85单片机,测评免费送开发板!
6个月从零掌握单片机开发!软硬件全流程实战,配套开发板+项目驱动教学!
Copyright © 2025-成都区角科技有限公司
蜀ICP备2025143415号-1
  
川公网安备51015602001305号