PWR(电源控制)

📅 2026/7/16 4:34:36 👁️ 阅读次数 📝 编程学习
PWR(电源控制)

PWR简介

STM32内部供电方案:

该图可以分为三个部分,VDDA模拟供电,VDD数字供电,VBAT后备供电。

其中VDD数字供电的右边部分是由电压调节器供电

低功耗模式:

LPDS用来设置电压调节器

注意停机和待机模式的HSI(内部高速时钟)和HSE(外部高速时钟)虽然关闭了,但LSI(外部低速时钟)和LSE(内部低速时钟)没有关闭。

模式选择

三种模式的特性:

唤醒事件:


注意:我们的程序默认的是HSE外部高速时钟通过PLL倍频得到72Mhz主频,而退出停止模式时它并不会开启HSE和PLL,而是选用HSI内部高速时钟(8Mhz)作为主频,所以我们退出停止模式时要重新开启HSE外部高速时钟(调用SystemIni函数配置)

睡眠模式+串口模式接收+接收初始化模板

intmain(void){uint32_tRXData;// 睡眠调试配置:保持SWD时钟在睡眠模式下运行,否则STLink连不上DBGMCU->CR|=DBGMCU_CR_DBG_SLEEP;Serial_Init();OLED_Init();OLED_ShowString(1,1,"Num:");while(1){if(Serial_GetRXFlag()==1){RXData=Serial_GetRXData();OLED_ShowHexNum(1,5,RXData,3);}OLED_ShowString(2,1,"Running");Delay_ms(500);OLED_ShowString(3,1," ");Delay_ms(500);}_WFI();}

这里是发送一个数据进入中断,然后退出睡眠模式。

停止模式+对射式红外传感器初始化模板:

intmain(void){RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//停止模式要配置PWR寄存器,所以要开启时钟。CountSensor_Init();OLED_Init();OLED_ShowString(1,1,"Count:");while(1){OLED_ShowNum(1,7,CountSensor_Get(),5);OLED_ShowString(2,1,"Running");Delay_ms(500);OLED_ShowString(2,1," ");Delay_ms(500);//第一个参数是开启电压调节器,第二个参数是选择WFI还是WFE开启停止模式(这里选择WFI)PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);SystemInit();//配置时钟,重新开启HSE外部高速时钟(72Mhz)}}

这里是外部中断退出停止模式,因为睡眠模式并没有用到PWR寄存器,所以并不用开启,但停止模式要配置寄存器,所以这里开启PWR时钟。

接着调用PWR_EnterSTOPMode进入停止模式,里面有两个参数选择,第一个选择电压调节器是打开还是处于低功耗模式,低功耗模式下唤醒会有一定的延时;第二个参数选择外部中断唤醒还是事件唤醒。停机模式只能由外部中断唤醒。

待机模式+实时时钟初始化模板:

intmain(void){MyRTC_Init();OLED_Init();RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//开启PWR时钟OLED_ShowString(1,1,"CNT:");OLED_ShowString(2,1,"ALR:");OLED_ShowString(3,1,"ALRF:");PWR_WakeUpPinCmd(ENABLE);//因为RTC_GetCounter()只能写不能读,所以要定义一个变量来查看。uint32_tAlarm=RTC_GetCounter()+10;RTC_SetAlarm(Alarm);//开启RTC闹钟,每10秒开一次OLED_ShowNum(2,6,Alarm,10);while(1){MyRTC_ReadTime();OLED_ShowNum(1,6,RTC_GetCounter(),10);//显示秒数OLED_ShowNum(3,6,RTC_GetFlagStatus(RTC_FLAG_ALR),1);//获取RTC闹钟标志位OLED_ShowString(4,1,"Running");Delay_ms(500);OLED_ShowString(4,1," ");Delay_ms(500);PWR_EnterSTANDBYMode();//进入待机模式}}

这里是RTC闹钟和WKUP上升沿退出待机模式。

因为进入待机模式后程序会重新开始运行,调用PWR_EnterSTANDBYMode()函数后,该函数的后面程序都不能运行了。

注意因为进入待机模式,GPIO口会处于高阻态,而OLED屏幕之所以还会亮是因为接入了VCC和GND所以可以亮,但并不能正常工作,这里可以从它每10秒才更新数据可以看出,而让OLED不亮的方法可以调用OLED_Clear()函数清屏就行了。

常用函数:
PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI); //第一个参数是开启电压调节器,第二个参数是选择WFI还是WFE开启停止模式(这里选择WFI)
SystemInit(); //配置时钟,重新开启HSE外部高速时钟(72Mhz)
RTC_SetAlarm( Alarm); //开启RTC闹钟,每10秒开一次
RTC_GetFlagStatus(RTC_FLAG_ALR); //获取RTC闹钟标志位
PWR_EnterSTANDBYMode(); //进入待机模式