欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

STM32进入Standby模式并唤醒

程序员文章站 2022-06-08 19:42:31
...

项目背景

设备具备电池、电源适配器两种供电方式,实现出厂时最低功耗(即进入待机模式),到用户开始使用时需要手动唤醒,开始复位运行。在检测到设备是交流供电时,设备全速运行;电测到是电池供电时,定时采集数据,采集完毕进入停止模式,定时器唤醒等待下次数据采集。(stm32f103ret6)
备注:本节只记录待机模式的进入和唤醒,停止模式的实现方式见STM32进入STOP模式并唤醒实验总结

用待机模式的理由及与停止模式的区别

  1. 选用待机模式

设备出厂,电池装在电路板上,封闭在模具当中,在到用户开始使用之前,必须保持最低功耗。停止模式下CPU电流消耗在20uA左右,而待机模式的电流消耗只有2uA。

  1. 和停止模式的区别

STM32进入Standby模式并唤醒
因为SRAM和寄存器的内容会保存,即能PC指针能记录程序当前运行的位置,从停止模式唤醒时,能继续沿着到时进入停止模式处继续往下运行。(故运行时,设备检测到是电池供电时,选用停止模式:采集完数据进入停止模式,2小时后(根据需求自定义)定时唤醒采集,依此循环)

STM32进入Standby模式并唤醒
SRAM和寄存器内容不会保存,即待机模式唤醒相当于系统复位,从头运行(设备测试完成,整机入库时,通过外部按键等方式触发进入待机模式)
STM32进入Standby模式并唤醒

待机模式实现

STM32进入Standby模式并唤醒
进入待机模式三个步骤说明:

1.将系统控制寄存器第二位置1,当进入深度睡眠时,允许停止系统时钟(系统控制寄存器参考《Cortex-M3权威指南》)
STM32进入Standby模式并唤醒
2.使能PWR_CR的PDDS位,使得深度休眠时进入待机模式
3.清除WUF唤醒标志(WUF标志由硬件置位,当系统是WKUP唤醒复位而不是上电等复位时会置位。应用中可以用来读取PWR_CSR的WUF位是否为1来判断系统复位是不是待机唤醒)
4.
以上三个步骤由库函数PWR_EnterSTANDBYMode()实现
STM32进入Standby模式并唤醒

进入待机模式
void Standby_Entering(void)
{
	RCC_APB2PeriphResetCmd(0x01fc, DISABLE);		//准备进入待机模式,复位所有IO,降低功耗(参照手册,根据需要复位对应IO)
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);//需要配置电源控制寄存器,所以使能时钟,否则不能正常使用命令进入待机状态和唤醒
	PWR_WakeUpPinCmd(ENABLE);					//使能WKUP引脚唤醒功能,否则WKUP引脚上升沿不能唤醒
	PWR_EnterSTANDBYMode();					//进入待机模式
}

void Standby_Configure(void)
{
	GPIO_InitTypeDef	GPIO_InitStructure;
	//EXTI_InitTypeDef  EXTI_InitStructure;
	//NVIC_InitTypeDef NVIC_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Mode =  GPIO_Mode_IPD;
	GPIO_Init(WAKEUP_PORT, &GPIO_InitStructure);

/*如果PA0只是用于唤醒,这部分可以不要,唤醒不是中断,中断控制器已经停止工作,如果正常模式下需要用到,可根据需要添加,这时候是中断事件
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;   
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
	NVIC_Init(&NVIC_InitStructure); 
	*/
}
中断处理(注:唤醒之后相当于复位,不会执行中断函数里的内容)
void EXTI0_IRQHandler(void)
{
	EXTI_ClearITPendingBit(EXTI_Line0);		//清除LINE0上的中断标志位
}

void main(void)
{
	...
	Standby_Configure();
	...
	//读取PWR_CSR的WUF位检测复位来源,这也就是为什么在进入待机模式之前需要清除WUF唤醒标志,这样检测到唤醒标志就能确定发生了唤醒复位
	
	if(PWR_GetFlagStatus(PWR_FLAG_WU) == SET)//从待机唤醒后,除了电源控制/状态寄存器(PWR_CSR),所有寄存器被复位
	{
		//是待机唤醒复位,可帮助调试
	}
	else
	{
		//上电复位、软件复位等非唤醒复位
	}
	while(1)
	{
		if(外部按键标志)				//根据硬件和个人需求确定什么时候进入待机模式
		{
			Standby_Entering();
		}

		//数据采集、发送
		//进入停止模式
		//定时从停止模式唤醒	
	}
}
相关标签: STM32f103