一.PWR基本信息
PWR负责管理STM32內部时钟的电源供电部分,可以实现可编程电压检测器和低功耗模式的功能。
可编程电压检测器(PVD)可以监控VDD电源电压,当VDD下降到PVD阈值以下或上升到PVD阈值之上时,PVD会触发中断,用于执行紧急关闭任务
低功耗模式包括睡眠模式(Sleep)、停机模式(Stop)、和待机模式(Standby),可在系统空闲时,降低STM32的功耗,延长设备时间
1.电源框图
VDDA供电区域: 主要负责模拟部分供电(A/D转换器,温度传感器,复位模块,PLL);使用VDDA(正极)/VSSA(负极)供电引脚
VDD供电区域: 左边区域:I/O电路,待机电路(唤醒逻辑,IWDG);
1.8V供电区域: 通过电压调节器进入1.8V供电区域(CPU核心,储存器,内置数字外设);使用VSS/VDD引脚
**后备供电区域:**LSE 32K晶体振荡器,后备寄存器,RCC BDCR寄存器,RTC;使用VBAT供电引脚
2.低功耗模式
睡眠: WFI(等待中断),任何外设发生任意中断,芯片就会醒来
WFE(等待事件),可以是外部中断的事件模式或者没有配置NVIC的使能中断
睡眠模式会使1.8V区域时钟CPU时钟关闭其他无影响,VDD区域无影响,电压调节器开
停机: 把SLEEPDEEP置1设置PDDS=0,配置WFI,WFE,LPDS=0(电压调节器开)LPDS=1(电压调节器低功耗),外部中断才能唤醒,关闭所有1.8V区域时钟,VDD区域HSI\HSE的振荡器关闭,电压调节器开启或者处于低功耗
待机: 把SLEEPDEEP置1,设置PDDS=1,配置WFI,WFE,WKUP引脚上升沿\RTC闹钟事件\NRST引脚的外部复位\IWDG复位,1.8V的时钟关闭,VDD区域HSI\HSE的振荡器关闭,电压调节器关闭
PDDS=0停机模式
PDDS=1待机模式
3.基本流程
修改主频: 调用SystemCoreClock函数之后修改主频
睡眠模式: 调用__WFI();进入睡眠模式发送数据显示数据否则数据不会显示
停止模式: 开启PWR时钟,调用PWR_EnterSTOPMode();函数进入停止模式
待机模式: 设置闹钟,开启待机模式,使用闹钟信号唤醒待机模式
Wakeup();函数接高电平唤醒
待机模式时因为属于低功耗可能在部分显示屏上不显示数据属于正常,只要代码内部能跑就行
二.代码实现(只写main.c)
1.修改主频
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
int main(void)
{
OLED_Init ();
OLED_ShowString (1,1,"SYSCLK:");
OLED_ShowNum (1,8,SystemCoreClock,8);//调用SystemCoreClock函数显示主频
while(1)
{
//每隔500ms显示Running
OLED_ShowString (2,1,"Running");
Delay_ms(500);
OLED_ShowString (2,1," ");
Delay_ms(500);
}
}
2.睡眠模式+串口发送+接收
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "Serial.h"
uint8_t RxData;
int main(void)
{
OLED_Init ();
OLED_ShowString(1,1,"RxData:");
Serial_Init();
while(1)
{
if(Serial_GetRxFlag() == 1)
{
RxData = Serial_GetRxData();//串口接收接受数据赋值给RxDAta
Serial_SendByte (RxData);//串口发送数据
OLED_ShowHexNum (1,8,RxData,2);
}
//发送数据之后闪烁Running
OLED_ShowString (2,1,"Running");
Delay_ms(500);
OLED_ShowString (2,1," ");
Delay_ms(500);
__WFI();//启动睡眠模式
}
}
3.停止模式+对射式红外传感器计次
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "CountSensor.h"
int main(void)
{
RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR ,ENABLE );//开启PWR时钟
OLED_Init ();
CountSensor_Init();
OLED_ShowString(1,1,"count:");
while(1)
{
OLED_ShowNum(1,7,Sensor_GetCount(),5);
OLED_ShowString(2,1,"Running");
Delay_ms(100);
OLED_ShowString(2,1," ");
Delay_ms(100);
PWR_EnterSTOPMode(PWR_Regulator_ON,PWR_STOPEntry_WFI);//停止模式开启电压调制器睡眠模式选择WFI
SystemInit ();//重新配置时钟
}
}
4.待机模式+RTC实时时钟
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "OLED.h"
#include "MyRTC.h"
int main(void)
{
OLED_Init ();
MyRTC_Init();
RCC_APB1PeriphClockCmd (RCC_APB1Periph_PWR ,ENABLE );//开启PWR时钟
OLED_ShowString (1,1,"CNT:");//秒计数器
OLED_ShowString (2,1,"ALM:");//闹钟
OLED_ShowString (3,1,"ALMF:");//闹钟标志位
// PWR_WakeUpPinCmd(ENABLE );//开启上升沿触发
uint32_t Alarm;
Alarm = RTC_GetCounter() + 10;//闹钟时间设置秒计数器时间加10
RTC_SetAlarm(Alarm);//闹钟值写入闹钟
OLED_ShowNum (2,6,Alarm,10);//显示闹钟
while(1)
{
OLED_ShowNum (1,6,RTC_GetCounter(),10);//显示秒计数器计数器值
OLED_ShowNum (3,6,RTC_GetFlagStatus(RTC_FLAG_ALR),1);//显示闹钟标志位
OLED_ShowString (4,1,"Running");
Delay_ms(100);
OLED_ShowString (4,1," ");
Delay_ms(100);
OLED_ShowString (4,9,"Standby");
Delay_ms(1000);
OLED_ShowString (4,9," ");
Delay_ms(100);
OLED_Clear ();
PWR_EnterSTANDBYMode();//启动待机模式
}
}