基于STM32的电源管理—实现低功耗(详细讲解+代码)
基于STM32的电源管理—实现低功耗(详细讲解+代码)
什么是电源管理?
电源对电子设备的重要性不言而喻,它是保证系统稳定运行的基础。在很多应用场合中都对电子设备的功耗要求非常苛刻,如某些传感器信息采集设备,仅靠小型的电池提供电源,要求工作长达数年之久,且期间不需要任何维护;由于智慧穿戴设备的小型化要求,电池体积不能太大导致容量也比较小,所以也很有必要从控制功耗入手,提高设备的续行时间。因此,STM32有专门的电源管理外设监控电源并管理设备的运行模式,确保系统正常运行,并尽量降低器件的功耗。
STM32的电源管理外设监控电源
电源监控器
STM32芯片主要通过引脚VDD从外部获取电源,在它的内部具有电源监控器用于检测VDD的电压,以实现复位功能及掉电紧急处理功能,保证系统可靠地运行。
当检测到VDD的电压低于阈值VPOR及VPDR时,无需外部电路辅助,STM32芯片会自动保持在复位状态,防止因电压不足强行工作而带来严重的后果。在刚开始电压低于VPOR时(约1.92V),STM32保持在上电复位状态(POR,Power On Reset),当VDD电压持续上升至大于VPOR时,芯片开始正常运行,而在芯片正常运行的时候,当检测到VDD电压下降至低于VPDR阈值(约1.88V),会进入掉电复位状态(PDR,Power Down Reset)。
可编程电压检测器PVD
另外STM32还提供了可编程的电压监测器PVD,它也是实时检测VDD的电压,当检测到电压低于编程的VPVD阈值时,会向内核产生一个PVD中断(EXTI16线中断)以使内核在复位前进行紧急处理。该电压阈值可通过电源控制寄存器PWR_CSR设置。
使用PVD可配置8个等级,见下表。其中的上升沿和下降沿分别表示类似图POR与PDR中VDD电压上升过程及下降过程的阈值。
STM32的电源系统
为了方便进行电源管理,STM32把它的外设、内核等模块跟据功能划分了供电区域,其内部电源区域划分见图STM32的电源系统。
从框图了解到,STM32的电源系统主要分为备份域电路、内核电路以及ADC电路三部分,介绍如下:
ADC电源及参考电压(VDDA供电区域)
为了提高转换精度,STM32的ADC配有独立的电源接口,方便进行单独的滤波。ADC的工作电源使用VDDA引脚输入,使用VSSA作为独立的地连接,VREF引脚则为ADC提供测量使用的参考电压。
调压器供电电路(VDD/1.8V供电区域)
在STM32的电源系统中调压器供电的电路是最主要的部分,调压器为备份域及待机电路以外的所有数字电路供电,其中包括内核、数字外设以及RAM,调压器的输出电压约为1.8V,因而使用调压器供电的这些电路区域被称为1.8V域。调压器可以运行在“运行模式”、“停止模式”以及“待机模式”。在运行模式下,1.8V域全功率运行;在停止模式下1.8V域运行在低功耗状态,1.8V区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及SRAM的内容;在待机模式下,整个1.8V域都断电,该区域的内核寄存器及SRAM内容都会丢失(备份区域的寄存器不受影响)。
备份域电路(后备供电区域)
STM32的LSE振荡器、RTC及备份寄存器这些器件被包含进备份域电路中,这部分的电路可以通过STM32的VBAT引脚获取供电电源,在实际应用中一般会使用3V的钮扣电池对该引脚供电。
在图中备份域电路的左侧有一个电源开关结构,它的功能类似图双二极管结构中的双二极管,在它的“1”处连接了VBAT电源,“2”处连接了VDD主电源(一般为3.3V),右侧“3”处引出到备份域电路中。当VDD主电源存在时,由于VDD电压较高,备份域电路通过VDD供电,节省钮扣电池的电源,仅当VDD掉电时,备份域电路由钮扣电池通过VBAT供电,保证电路能持续运行,从而可利用它保留关键数据。
STM32的功耗模式(重点)
按功耗由高到低排列,STM32具有运行、睡眠、停止和待机四种工作模式。上电复位后STM32处于运行状态时,当内核不需要继续运行,就可以选择进入后面的三种低功耗模式降低功耗,这三种模式中,电源消耗不同、唤醒时间不同、唤醒源不同,用户需要根据应用需求,选择最佳的低功耗模式。三种低功耗的模式说明见表STM32的低功耗模式说明。
从表中可以看到,这三种低功耗模式层层递进,运行的时钟或芯片功能越来越少,因而功耗越来越低。
睡眠模式
在睡眠模式中,仅关闭了内核时钟,内核停止运行,但其片上外设,CM3核心的外设全都还照常运行。有两种方式进入睡眠模式,它的进入方式决定了从睡眠唤醒的方式,分别是WFI(wait for interrupt)和WFE(wait for event),即由等待“中断”唤醒和由“事件”唤醒。睡眠模式的各种特性见表睡眠模式的各种特性。
代码
__WFI(); //WFI指令进入睡眠
非常简单的,利用WFI指令(内核,在core_cm3.h)进入睡眠模式,可使用任意终端唤醒,继续执行睡眠指令之后的程序
停止模式
在停止模式中,进一步关闭了其它所有的时钟,于是所有的外设都停止了工作,但由于其1.8V区域的部分电源没有关闭,还保留了内核的寄存器、内存的信息,所以从停止模式唤醒,并重新开启时钟后,还可以从上次停止处继续执行代码。停止模式可以由任意一个外部中断(EXTI)唤醒,在停止模式中可以选择电压调节器为开模式或低功耗模式。停止模式的各种特性见表停止模式的各种特性。
代码
调用库函数:
/* 进入停止模式,设置电压调节器为低功耗模式,等待中断唤醒 */
PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);
非常简单的,利用库函数PWR_EnterSTOPMode进入停止模式,可使用任意终端唤醒,继续执行睡眠指令之后的程序
待机模式
待机模式,它除了关闭所有的时钟,还把1.8V区域的电源也完全关闭了,也就是说,从待机模式唤醒后,由于没有之前代码的运行记录,只能对芯片复位,重新检测boot条件,从头开始执行程序。它有四种唤醒方式,分别是WKUP(PA0)引脚的上升沿,RTC闹钟事件,NRST引脚的复位和IWDG(独立看门狗)复位。
代码(必须要使能时钟才能进入待机模式)
/* 使能电源管理单元的时钟,必须要使能时钟才能进入待机模式 */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR , ENABLE);
while(判断条件)
{
/*清除WU状态位*/
PWR_ClearFlag (PWR_FLAG_WU);
/* 使能WKUP引脚的唤醒功能 ,使能PA0*/
PWR_WakeUpPinCmd (ENABLE);
/* 进入待机模式 */
PWR_EnterSTANDBYMode();
}
需要唤醒,退出待机模式
可以使用WKUP、复位引脚的上升沿以及RTC闹钟标志位的方式去唤醒亦或者是IWDG复位唤醒
//检测复位来源
if(PWR_GetFlagStatus(PWR_FLAG_WU) == SET)
{
LED_BLUE;
printf("\r\n 以唤醒执行操作 \r\n");
}
else
{
LED_GREEN;
printf("\r\n 非待机唤醒复位 \r\n");
}
在以上讲解的睡眠模式、停止模式及待机模式中,若备份域电源正常供电,备份域内的RTC都可以正常运行,备份域内的寄存器的数据会被保存,不受功耗模式影响。
总结
总的来说低功耗就分为这几种模式,具体的实现还是要参考项目需求去调用正确的库函数,希望对大家有帮助,谢谢!