前言
本文讲解STM32F10X的低功耗模式,部分资料参考自STM32手册。STM32F10X提供了三种低功耗模式:睡眠模式(Sleep mode)、停机模式(Stop mode)和待机模式(Standby mode)。这些低功耗模式可以有效减少系统功耗,延长电池寿命,对于需要长时间运行的电池供电设备尤为重要。
环境
- STM32F103ZET6开发板(战舰V3),72MHz主频
- 基于STM32CubeMX生成的HAL库代码
- keil5中,进行代码的编写修改
内容
因为我使用的是STM32CubeMX生成的HAL库代码,所以说PWR时钟的使能(__HAL_RCC_PWR_CLK_ENABLE();)已经在HAL_MspInit();里默认添加有了,如果是其它方式生成的代码,则可能需要手动添加。
关于唤醒的验证,我在下述验证中,就配置了PA0为外部中断模式,下拉,上升沿触发,开启对应NVIC,来实验了中断唤醒是没问题的,就是通过一条杜邦线PA0连接3.3V,拔插来触发就行了。事件唤醒还没有实验探究。
睡眠模式
睡眠模式,它使处理器暂停执行,并且可以通过外部事件或中断来唤醒。在睡眠模式下,(Cortex™-M3内核停止,所有外设包括Cortex-M3核心的外设,如NVIC、系统时钟(SysTick)等仍在运行,以便在唤醒时快速恢复正常运行。
睡眠模式的进入:两种睡眠模式,SLEEP-NOW或 SLEEP-ON-EXIT。
- SLEEP-NOW:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进入睡眠模式。
- SLEEP-ON-EXIT:如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。
睡眠模式的唤醒:两种唤醒方式,任一中断(WFI)或唤醒事件(WFE)。
- WFI:任意一个中断的触发都能唤醒该模式。
- WFE:唤醒事件
// SLEEP-NOW模式 WFI唤醒
// 滴答定时器的中断也会触发唤醒,所以说以WFI唤醒时,要先停止滴答的计数
HAL_SuspendTick(); //停止滴答定时器的计数
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick(); //启动滴答定时器的计数// SLEEP-NOW模式 WFI唤醒
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE);// SLEEP-ON-EXIT模式 WFI唤醒
HAL_PWR_EnableSleepOnExit(); // 按手册要求 SLEEPONEXIT = 1
HAL_SuspendTick(); //停止滴答定时器的计数
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_ResumeTick(); //启动滴答定时器的计数
停机模式
停止模式是在Cortex™-M3的深睡眠模式基础上结合了外设的时钟控制机制,在停止模式下电压 调节器可运行在正常或低功耗模式。此时在1.8V供电区域的的所有时钟都被停止,PLL、HSI和 HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。当一个中断或唤醒事件导致退出停止模式时,会自动选用内部高速时钟(HSI RC振荡器)为系统时钟。
该模式有着两种唤醒模式,大致也跟上述的睡眠模式一样,就不过多介绍了。
// 停机模式 WFI唤醒
HAL_SuspendTick(); //停止滴答定时器的计数
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI);
HAL_ResumeTick(); //启动滴答定时器的计数
// 停机模式 WFE唤醒
HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
待机模式
待机模式可实现系统的最低功耗。该模式是在Cortex-M3深睡眠模式时关闭电压调节器。整个 1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。
在HAL中进入待机模式很简单,只需要一行代码,就能进入,当然在待机前,还有设置唤醒源。这里的程序是设置用于WKUP引脚(PA0)上的上升沿后,进行唤醒。
待机模式唤醒,在通过唤醒源__唤醒后,代码执行等同于复位后的执行__,而不是从进入待机模式的程序继续执行的,这一点是需要注意的。待机模式下的输入/输出端口状态:在待机模式下,所有的I/O引脚处于高阻态,除了以下的引脚:1. 复位引脚(始终有效) 2. 当被设置为防侵入或校准输出时的TAMPER引脚 3. 被使能的唤醒引脚
//这里是先判断唤醒引脚PA0的状态
//因为上面说了,待机模式唤醒后等同于复位,所以说要检验待机模式的唤醒,不能直接把进入待机模式的程序直接放在程序中,否则一唤醒,又执行都进入待机模式的程序,这样就约等于死循环。
if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == 0)
{HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); //设置WKUP用于唤醒HAL_PWR_EnterSTANDBYMode(); // 进入待机模式
}
总结
功耗:睡眠模式 > 停机模式 > 待机模式
唤醒速度:睡眠模式 > 停机模式 > 待机模式