PWR电源控制

参考:bilibili:江协科技,看着视频写了个文字版的,相当于总结笔记,也方便以后查看。

简介:
        PWR负责管理STM32内部的电源供电部分,可以实现可编程电压检测器和低功耗模式的功能,这里主要讲解低功耗模式。
        低功耗模式包括睡眠模式(sleep)、停机模式(stop)和待机模式(standby),可在系统空闲时,降低STM32的功耗,延长设备的使用时间。
下面是电源框图,可以看出主要分为了三个区域:VDDA供电区域,VDD供电区域和1.8V供电区域还有最下面的后备供电区域。其中,VDD供电区域中有电压调节器,可以电压调节至1.8V,然后为1.8V区域供电。
大致看一下电源框图,了解各部分是由哪个供电区域供电。
下面是低功耗模式表:
我们可以看到各个模式的进入条件,唤醒条件和模式对电路的操作。
首先,我们来看睡眠模式。
        进入条件为WFI或WFE指令,如果是WFI指令进入睡眠模式,则唤醒需要中断来唤醒,如果由WFE指令进入睡眠模式,唤醒需要事件来唤醒。
        睡眠模式只是将CPU时钟关闭,对其他无影响。进入睡眠模式后,程序停止运行,各个寄存器的数据都还在。
        关于睡眠模式,我们可以通过设置系统控制寄存器中的SLEEPONEXIT位的值来选择睡眠模式的机制:如果SLEEPONEXIT位被清除,当WRI或WFE被执行时,微控制器立即进入睡眠模式。如果SLEEPONEXIT位被置位,系统从最低优先级的中断处理程序中退出时,微控制器就立即进入睡眠模式。即:SLEEPONEXIT = 0时,立刻进入睡眠模式,SLEEPONEXIT = 1时,先处理完中断处理程序后再进入睡眠模式。
        了解了睡眠模式,我们尝试去写睡眠模式的代码,我们可以做串口的实验,由OLED屏显示,代码如下:
int main(void)
{
	OLED_Init();
	OLED_ShowString(1,1,"RxData:");
	Serial_Init();
	
	while(1)
	{
		if(Serial_GetRxFlag() == 1)
		{	RxData = Serial_GetRxData();
			Serial_SendByte(RxData);
			OLED_ShowHexNum(1,8,RxData,2);
		}

		OLED_ShowString(2, 1, "Running:");
		Delay_ms(500);
		OLED_ShowString(2, 1, "        ");
		Delay_ms(500);
		
		__WFI();
	}
}
我们可以看到,主循环的最后一行调用了__WFI函数进入了睡眠模式。
程序现象:
        睡眠模式下,当我们在串口助手上发送数据时产生中断,标志位改变,然后接收数据显示数据,OLED屏幕上会闪烁一次Running。
        
如果没有进入睡眠模式,我们在主循环中会不断地检测标志位,不断地显示Running,这会导致无意义的耗电,睡眠模式可以减少此类耗电。
睡眠模式的进入条件是WFI或WFE指令,所以不需要PWR外设的函数。
接着,我们来看停机模式:
        进入条件:将 SLEEPDEEP设置为1,表示深度睡眠模式,将PDDS设为0,表示停机模式,LPDS可以设置电压调节器,LPDS = 0,电压调节器开启,LPDS = 1,电压调节器处于低功耗模式,最后调用WFI或WFE指令即可。
        唤醒条件为:任一外部中断。
        停机模式下1.8V供电区域的的所有时钟都被停止,PLL、HSI和HSE RC振荡器的功能被禁止,SRAM和寄存器内容被保留下来。在停止模式下,所有的I/O引脚都保持它们在运行模式时的状态。意思就是CPU和外设暂停工作,但是电压调节器没有关,存储器和寄存器里的数据还在,只能由外部中断来唤醒。
        了解了停机模式,下面来尝试下一下停机模式的代码,由于只能由外部中断来唤醒,所以串口的中断就不行了,串口实验做不了,可以使用对射式红外传感器计次来做实验。
代码如下:
int main(void)
{
	OLED_Init();
	CountSensor_Init();
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);

	OLED_ShowString(1,1,"Count:");

	while(1)
	{
		OLED_ShowNum(1,7,CountSensor_Cet(),5);
		
		OLED_ShowString(2, 1, "Running");
		Delay_ms(100);
		OLED_ShowString(2, 1, "       ");
		Delay_ms(100);
		
		PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
		SystemInit();
	}
}
        由于要使用PWR外设的库函数,所以要先开启PWR外设的时钟,在while循环中,最后调用 PWR_EnterSTOPMode函数进入停机模式,传入的参数为PWR_Regulator_ON表示电压调节器关闭,PWR_STOPEntry_WFI表示使用WFI指令。
        在 PWR_EnterSTOPMode之后还有一个SystemInit函数。这是由于,当一个中断或唤醒事件导致退出停止模式时, HSI RC振荡器被选为系统时钟。我们本来是选用HSE作为系统时钟的,但是唤醒后选HSI作为系统时钟了,这样主频会降低,为了保证其他部分不出现未知的错误,我们PWR_EnterSTOPMode调用一次SystemInit函数重新选择HSE作为系统时钟。
程序现象:
        烧录后闪烁一次Running后进入停机模式,当红外传感器检测到信号时产生外部中断,然后唤醒,唤醒后会OLED屏上闪烁一次Running,之后又进入停机模式。
最后,来看待机模式
        进入条件:将 SLEEPDEEP设置为1,表示深度睡眠模式,将PDDS设为1,表示待机模式,然后调用WFI或WFE指令即可。
        唤醒条件:当一个外部复位(NRST 引脚 ) IWDG 复位、 WKUP 引脚上的上升沿或 RTC 闹钟事件的上升沿发生时 ,微控制器从待机模式退出。从待机唤醒后,除了电源控制 / 状态寄存器, 所有寄存器被复位。
        待机模式可实现系统的最低功耗,整个1.8V供电区域被断电。PLL、HSI和HSE振荡器也被断电。SRAM和寄存器内容丢失。只有备份的寄存器和待机电路维持供电。在待机模式下,所有的IO引脚变为高阻态。
        了解了待机模式,下面来尝试下一下待机模式的代码,我们可以使用RTC实时时钟的闹钟事件来推出待机模式。
代码如下:
int main(void)
{
	uint32_t Alarm;
	OLED_Init();
	MyRTC_Init();
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
	
	OLED_ShowString(1, 1, "CNT :");
	OLED_ShowString(2, 1, "ALR :");
	OLED_ShowString(3, 1, "ALRF:");
	
	PWR_WakeUpPinCmd(ENABLE);
	
	Alarm = RTC_GetCounter() + 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, 1, "       ");
		Delay_ms(1000);
		
		OLED_Clear();
		
		PWR_EnterSTANDBYMode();
	}
}
        由于要使用PWR外设的库函数,所以要先开启PWR外设的时钟,之后我们设置闹钟的值为当前计数器的值加10,也就是10秒,每10秒会退出一次待机模式。而 PWR_WakeUpPinCmd函数可以使能唤醒引脚的功能。调用了这个函数,在WKUP引脚的上升沿也可以推出待机模式。在while循环中,最后调用 PWR_EnterSTANDBYMode函数进入待机模式。
        退出待机模式后,程序从头执行,所以PWR_EnterSTANDBYMode函数之后不要再写代码了,因为不会执行到。
        OELD_Clear函数是为了模拟模块关闭的效果。
程序现象:
        OLED屏幕会显示一下当前计数器的值和闹钟的值,然后清屏,进入待机模式,在10秒后,当前计数器的值等于闹钟值,退出待机模式,程序从头开始,重新设置闹钟值,再显示,之后再进入待机模式。我们也可以使用WKUP引脚的上升沿来退出待机模式,在STM32F103C8T6中,WKUP引脚是PA0,我们可以在PA0引脚接入飞线,当另一端接入VCC时产生上升沿,退出待机模式。
到此为止,三种低功耗模式就讲解完了。
        
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值