【STM32笔记】__WFI();进入不了休眠的可能原因(系统定时器SysTick一直产生中断)
【STM32笔记】低功耗模式配置及避坑汇总
前文:
blog.csdn.net/weixin_53403301/article/details/128216064
【STM32笔记】HAL库低功耗模式配置(ADC唤醒无法使用、低功耗模式无法烧录解决方案)
__WFI();为汇编指令
/**
\brief Wait For Interrupt
\details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
*/
#define __WFI __wfi
其作用就是设备休眠 并等待任意中断实践唤醒
实际调用:
__WFI();
但是 基本上直接都执行不了
最常见的就是中断没清理掉
在Keil的调试中可以看到活跃的中断
EPA分别表示Enable Pending Active
前两个表示开启但未发生 Active表示正在发生
所以进入休眠前需要调用中断清理
如:
__disable_irq();
或:
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); //清理唤醒标志 防止立刻唤醒
等标志
另外 实测发现 即使没有中断或唤醒标志 也会导致__WFI();无法进入 特别是程序刚开始运行的时候 这里其实就是没消抖 需要延时一会(哪怕1us)
delay_us(1);
__WFI();
delay_us中其实是对系统定时器SysTick进行赋值并计数 计数后会关闭 其实进不了低功耗就是因为这个被开启了 中断一直有
直接关闭/开启系统定时器也可以
SysTick->CTRL = 0;
再者 在进行调试时 如果采用单步调试(也相当于一种中断) 则会执行__WFI();后立马执行下一句
所以可以在__WFI();之前和之后打一个断点 用全速跑来判断是否进入
如果开启了系统滴答定时器,记得关闭系统滴答定时器,因为系统滴答定时器的中断也会唤醒CPU。
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
HAL_Delay(1000);//延时1000毫秒
/* 采用位带操作实现LED翻转 */
PCout(13) = !PCin(13);
if(times > 4)
{
//HAL_SuspendTick();//停止系统滴答计时器
CLEAR_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//失能系统滴答定时器
HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI);//WFI指令进入睡眠模式
times = 0;
SET_BIT(SysTick->CTRL, SysTick_CTRL_ENABLE_Msk);//使能系统滴答定时器
//HAL_ResumeTick();//恢复系统滴答计时器
}
times++;//循环次数加一
}