电源管理——电源检测及低功耗

控制功耗—>电源管理

1.1电源监视器

在stm32芯片内部,用于检测VDD的电压,以实现复位功能和紧急掉电功能


1.上电复位和掉电复位(POR与PDR)
     当检测到VDD的电压低于阈值VPOR及VPDR时,  芯片自动保持在复位状态;
     电压低于VPOR(约1.92V)--->保持在上电复位状态(POR)--(电压持续上升至大于VPOR )->芯片开始正常运行--(电压下降至低于VPDR(约1.88V))->进入掉电复位状态(PDR);

在这里插入图片描述

2.可编程电压检测器PVD

STM32提供,也是实时检测 VDD电压;
用户可以利用PVD对VDD电压与电源控制寄存器(PWR_CR)中的PLS[2:0]位进行比较来监控电源,这几位选择监控电压的阀值。
通过设置PVDE位来使能PVD。
电源控制/状态寄存器(PWR_CSR)中的PVDO标志用来表明VDD是高于还是低于PVD的电压值。该事件在内部连接到外部中断的第16线,如果该中断在外部中断寄存器中是使能的,该事
件就会产生中断。当VDD下降到PVD阀值以下和(或)当VDD上升到PVD阀值之上时,根据外部中断第16线的上升/下降边沿触发设置,就会产生PVD中断。例如,

 电压低于编程的VPVD阈值(可通过电源控制寄存器PWR_CSR设置)--->向内核产生一个PVD中断(EXTI16线中断)==》使内核在复位前进行紧急处,
 这一特性可用于用于执行紧急关闭任务。
 使用PVD可配置8个等级。

在这里插入图片描述
我们一般使用典型值

PVD 监控实验:

PVD初始化:
void PVD_Config(void)
8 {
9 NVIC_InitTypeDef NVIC_InitStructure;
10 EXTI_InitTypeDef EXTI_InitStructure;
11
12 /*使能 PWR 时钟 */
13 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
14
15 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
16
17 /* 使能 PVD 中断 */
18 NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn;
19 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
20 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
21 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
22 NVIC_Init(&NVIC_InitStructure);
23
24 /* 配置 EXTI16 线(PVD 输出) 来产生上升下降沿中断*/
25 EXTI_ClearITPendingBit(EXTI_Line16);
26 EXTI_InitStructure.EXTI_Line = EXTI_Line16;
27 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
28 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
29 EXTI_InitStructure.EXTI_LineCmd = ENABLE;
30 EXTI_Init(&EXTI_InitStructure);
31
32 //配置 PVD 级别 PWR_PVDLevel_2V6
33 // (PVD 检测电压的阈值为 2.6V, VDD 电压低于 2.6V 时产生 PVD 中断)
35 /*具体级别根据自己的实际应用要求配置*/
36 PWR_PVDLevelConfig(PWR_PVDLevel_2V6);
37
38 /* 使能 PVD 输出 */
39 PWR_PVDCmd(ENABLE);
40 }



在这段代码中,执行的流程如下:
(1) 配置 PVD 的中断优先级。由于电压下降是非常危急的状态,所以请尽量把它配置
成最高优先级。
(2) 配置了 EXTI16 线的中断源,设置 EXTI16 是因为 PVD 中断是通过 EXTI16 产生
中断的(GPIO 的中断是 EXTI0-EXTI15)(3) 使用库函数 PWR_PVDLevelConfig 设置 PVD 监控的电压阈值等级,各个阈值等
级表示的电压值请查阅表 41-1 或 STM32 的数据手册。
(4) 最后使用库函数 PWR_PVDCmd 使能 PVD 功能。
PVD中中断函数:
void PVD_IRQHandler(void)
8 {
9 /*检测是否产生了 PVD 警告信号*/
10 if (PWR_GetFlagStatus (PWR_FLAG_PVDO)==SET) {
11 /* 亮红灯,实际应用中应进入紧急状态处理 */
12 LED_RED;
13
14 }
15 /* 清除中断信号*/
16 EXTI_ClearITPendingBit(EXTI_Line16);
17
18 }
Main函数:
int main(void)
7 {
8 LED_GPIO_Config();
9
10 //亮绿灯,表示正常运行
11 LED_GREEN;
12
13 //配置 PVD,当电压过低时,会进入中断服务函数,亮红灯
14 PVD_Config();
15
16 while (1) {
17
18 /*正常运行的程序*/
19
20 }
21
22 }

PVD检测的电压是VDD电压。

1.2 STM32的电源系统

在这里插入图片描述
可以看到上图有VDD、VSS、VDDA、VSSA、VREF+等标识,这些是什么意思呢?有什么特点呢?如何看懂STM32系统的电源框架图呢?
看图:
在这里插入图片描述
STM32的电源系统主要分为备份域电路、内核电路以及ADC电路三部分:

(1)ADC电源及参考电压(VDDA供电区域)
  ADC使用一个独立的电源供电,为了提高转换的精确度,
过滤和屏蔽来自印刷电路板上的毛刺干扰。
工作电源使用VDDA引脚输入,VSSA作为独立的地连接,VRED引脚为ADC提供测量使用的参考电压。
2)调压器供电电路(VDD/1.8V供电区域)
          在 STM32 的电源系统中调压器供电的电路是最主要的部分;
          调压器为备份域及待机电路以外的所有数字电路供电,其中包括内核、数字外设以及 RAM,调压器的输出电压约为 1.8V,因而使用调压器供电的这些电路区域被称为 1.8V 域。
          调压器可以运行在“运行模式”、“停止模式”以及“待机模式”。
          在运行模式下, 1.8V 域全功率运行;
          在停止模式下 1.8V 域运行在低功耗状态, 1.8V 区域的所有时钟都被关闭,相应的外设都停止了工作,但它会保留内核寄存器以及SRAM 的内容;
          在待机模式下,整个 1.8V 域都断电,该区域的内核寄存器及SRAM 内容都会丢失(备份区域的寄存器不受影响)
3)备份域电路(后备供电区域)
        STM32 的 LSE 振荡器、 RTC 及备份寄存器这些器件被包含进备份域电路中;
        可以通过VBAT引脚获取供电电源,实际应用中一般使用3V的纽扣电池供电;
        有一个电源开关结构,它的功能类似双二极管。仅当VDD掉电时,备份域电路由纽扣电池通过VBAT供电,保证电路持续运行,以此保留关键数据。
         

在这里插入图片描述

1.3 STM32的功耗模式

功耗由高到低:运行-》睡眠-》停止-》待机
三种模式下能耗图:
在这里插入图片描述

上电复位后STM32处于运行状态时,当内核不需要继续运行,可选择进入三种低功耗模式:

三种模式进入方式及影响:*
在这里插入图片描述

三种模式的一般运用:
睡眠模式
在这里插入图片描述
停止模式:
在这里插入图片描述
待机模式:
在这里插入图片描述

三种模式解析




  1.睡眠模式
                 仅关闭内核时钟,内核停止运行,但片上外设、CM3核心的外设还照常运行;
              两种方式进入睡眠模式:等待“中断”唤醒(WFI)和由“事件”唤醒(WFE)
               睡眠模式的各种特性:
                 立即睡眠(执行WFI或WFE指令时立即进入睡眠模式);
                 退出时睡眠(退出优先级最低的中断服务程序后才进入睡眠模式);
                 进入方式(1.内核寄存器的SLEEPDEEP=0,然后调用WFI或WFE指令即可进入睡眠模式;2.内核寄存器的SLLEPONEXIT=0时,进入“立即睡眠”;3.SLEEPONEXIT=0,进入“退出时睡眠”);
                 唤醒方式(使用WFI指令睡眠--->任意中断唤醒;使用WFE指令睡眠--->由事件唤醒);
                 睡眠时(关闭内核时钟,内核停止;外设正常运行,不再执行新的代码;此状态会保留睡眠前的内核寄存器、内存的数据);
                 无唤醒延迟;
                 唤醒后(由中断唤醒--->先进入中断,退出后接着执行WFI指令后程序;由事件唤醒--->直接接着执行WFE后的程序)          

        2. 停止模式 
       进一步关闭其它所有时钟,因此所有外设停止工作。但是1.8区域的部分电源未关闭,还保留了内核的寄存器、内存的信息--->唤醒后仍可以在停止处继续执行代码。
      可以由任意一个外部中断(EXTI)唤醒。
      在此模式中可以选择电压调节器为开模式或低功耗模式。
       停止模式的各种特性:
             调压器低功耗模式(停止模式下调压器可工作在正常模式或低功耗模式);
              进入方式(内核处理器的SLEEPDEEP=1,PWR_CR寄存器中的PDDS=0,然后调用WFI或WFE指令即可进入停止模式;PWR_CR寄存器的LPDS=0时,调压器工作在正常模式,LPDS=1时工作在低功耗模式);
              唤醒方式(使用WFI指令睡眠--->使用任意EXTI线的中断唤醒;使用WFE指令睡眠--->使用任意配置为事件模式的EXTI线事件唤醒);
              停止时(内核停止,片上外设也停止。这个状态会保留停止前的内核寄存器、内存的数据);
              唤醒延迟(基础延迟为HSI振荡器的启动时间,若调压器工作在低功耗模式,还需加上调压器切换至正常模式下的时间);
              唤醒后(由中断唤醒--->先进入中断,退出后接着执行WFI指令后的程序;由事件唤醒--->直接接着执行WFE后的程序。PS:唤醒后,STM32会使用HSI作为系统时钟);      

         3.待机模式
                进一步把1.8V区域的电源也关闭了==》在此模式唤醒后,只能对芯片复位,重新检测boot条件,从头开始执行程序。
                四种唤醒方式:WKUP(PA0)引脚的上升沿、RTC闹钟事件、NRST引脚的复位、IWDG(独立看门狗)复位。
                待机模式的各种特性:
                  进入方式(SLEEPDEEP=1,PWR_CR寄存器中的PDDS=1和唤醒状态位WUP=0,然后调用WFI或WFE指令);
                  唤醒方式(WKUP引脚的上升沿, RTC 闹钟、唤醒、入侵、时间戳事件或NRST 引脚外部复位及 IWDG 复位);
                 待机时(内核停止,片上外设也停止;内核寄存器、内存的数据会丢失;除复位引脚、 RTC_AF1 引脚及 WKUP 引脚,其它 I/O口均工作在高阻态。);
                 唤醒延迟(芯片复位的时间);
                 唤醒后(相当于芯片复位,从头开始执行代码)

低功耗实验:


 void  EXTI3_IRQHandler ()
			 
		 {
		if (EXTI_GetITStatus(EXTI_Line_Pin)==1)
		{   
			
		 EXTI_ClearITPendingBit(EXTI_Line_Pin);
			
        //中断不做任何东西,只为唤醒

		 }
	 }

void key_exti_config()
{
	  GPIO_InitTypeDef   GPIO_InitStructre;
	  EXTI_InitTypeDef   EXTI_InitStructre;
	  NVIC_InitTypeDef   NVIC_InitStructre;
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
	
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
      GPIO_InitStructre.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	  GPIO_InitStructre.GPIO_Pin =GPIO_Pin_3;
	  GPIO_Init(EXTI_GPIO, &GPIO_InitStructre);

	  GPIO_EXTILineConfig(GPIO_PortSourceGPIOE, GPIO_PinSource3);
	
	
     EXTI_InitStructre.EXTI_Line=EXTI_Line3;
     EXTI_InitStructre.EXTI_Mode=EXTI_Mode_Interrupt;
     EXTI_InitStructre.EXTI_Trigger=EXTI_Trigger_Falling ;
     EXTI_InitStructre.EXTI_LineCmd=ENABLE;
     EXTI_Init(&EXTI_InitStructre);
     EXTI_ClearITPendingBit(EXTI_Line_Pin);


     NVIC_InitStructre.NVIC_IRQChannel= EXTI3_IRQn;
     NVIC_InitStructre.NVIC_IRQChannelPreemptionPriority=1;
     NVIC_InitStructre.NVIC_IRQChannelSubPriority=1;
     NVIC_InitStructre.NVIC_IRQChannelCmd=ENABLE;
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     NVIC_Init(&NVIC_InitStructre);
    
  } 

睡眠模式:



int main(void)
{
	 LED_init();
     key_exti_config();
     led0=0;
    SysTick_Daylay_ms(1000);
 __WFI(); 
    led0=1;
}

/*
睡眠模式只需要在加入__WFI() 指令(并不需要打开PWR时钟),就可以让程序运到这里的时候进入睡眠,并且,该指令是中断唤醒的,
(该实验设计了一个外部按键中断,按下对应的按键后,程序就会唤醒。程序就会往下执行熄灭LED)任何中断都可以唤醒睡眠模式,停止模式是外部中断。  
如果想让程序进入睡眠并且事件唤醒,则可以采用__WFE()指令。  
睡眠模式仅仅是对1.8V供电区域内核时钟进行了关闭,并没有对内核断电,让内核数据得到了保存,唤醒后,程序会往后执行
对1.8V 供电区域的外设时钟也没进行关闭,外设仍然可用,这种场景很适合DMA搬运数据的时候。
 */
    

停止模式:

//在前面的基础上,只修改了main函数
int main(void)
{
    u8 i=3;
	 LED_init();
     key_exti_config();
   while(i--){    
        led0=1; 
       SysTick_Daylay_ms(1000); //正常延时一秒,采用的是HSE时钟
        led0=0;  
  SysTick_Daylay_ms(1000);
}
//PWR_Regulator_ON电压调节器采用了正常供电模式。
 PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);//进入停止模式,进入该模式后HSI和HSE都被关闭,重新唤醒后,系统默认选择HSI   (8MHZ)
while(1){  //退出停止模式,时钟采用了HSI,如果需要重新恢复延时正常,那需要在进入该语句之前将时钟配置成HSE.
 
        led1=0;
     SysTick_Daylay_ms(1000);//这里采用了HSI,这里相当于延时了9秒
    //HSE出现故障时,HSI将被选为系统时钟,记住是“系统时钟”,不是被选为锁相环时钟时钟源,所以HSI(8MHZ)将没有经过分频或倍频直接被作为系统时钟,经过一分频变成AHB时钟,所以到GPIO的时钟是8MHZ. 比平时(72MHZ),慢了9倍。
        led1=1;
SysTick_Daylay_ms(1000);  
}  

/*现象:进入停止模式之后,进入停止模式前的灯,还会亮,外部中断唤醒之后,开始led开始亮灭闪烁。
停止模式在睡眠模式的基础上,关闭了1.8供电区域的数字外设时钟,SHE、SHI振荡器关闭。

待机模式:

在前面的基础上,只修改了main函数
int main(void)
{
	 LED_init();
     key_exti_config();
     led=0;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//待机模式下要开启。
PWR_WakeUpPinCmd(ENABLE);//此为固定唤醒脚,而且并不需要对其IO进行配置,直接写上这句就可以。
PWR_EnterSTANDBYMode(); 
while(1){  
SysTick_Daylay_ms(1000);
    led1=0;
 SysTick_Daylay_ms(1000);  
    
      led1=1; 
}
/**进入待机模式,要开启PWR时钟**,如果想设置了wakeup引脚中断,务必在
PWR_EnterSTANDBYMode();这句话前配置,不然相当于没设定wakeup引脚唤醒,进待机后,按下wakeup,也不会唤醒。
/*待机模式,在停止模式的基础上,电压调节器对1.8V区域,进行了断电,让内核寄存器,内存数据丢失,所以进入待机模式之后,程序会从头开始运行,这有点像我们对手机进行了关机
所以该程序唤醒之后并不会执行后面的while 循环,程序又开始从头开始执行。
*/
 }

1.4
STM32F103进入睡眠模式或者待机模式或者停机模式,IO脚原先设置的电平值是否会改变?

1、睡眠模式(Cortex-M3内核停止,外设运行)
     这个时候,如果不锁定IO的话,有外部触发的IO电平会改变。
2、停止模式(所有时钟停止)
     这个时候,外设已经停止工作,保持原来的电平,锁不锁都一样,无论外部则呢么变化,IO口电平不会发生变化。
3、待机模式(1.8V电源关闭)
     在此情况下,IO都是高阻,除了复位引脚和唤醒引脚电平会变化。

怪不得我的灯在进入停止模式的时候,灯还是亮着,进入待机模式的时候就灭了。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值