待机唤醒原理与实验
一.参考资料探索者STM32F4开发板《STM32F4开发指南-库函数版本》-第22章 待机唤醒实验
STM32F4xx官方资料:《STM32F4xx中文参考手册》-第5章5.3小节 低功耗模式
二.待机唤醒
很多单片机有低功耗模式,STM32也不例外。在系统或者电源复位后,微控制器出于运行状态之下,HCLK为CPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。
1.STM32的3种低功耗模式:睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行。
停止模式:所有时钟都已停止。1.8V内核电源工作。
PLL,HIS和HSE RC振荡器功能禁止。
寄存器和SRAM内容保留。待机模式:1.8V内核电源关闭。
只有备份寄存器和待机电路维持供电。
寄存器和SRAM内容全部丢失。实现最低功耗。
用户根据最低电源消耗,最快启动时间和可用的唤醒源等条件,选择一种最佳的低功耗模式
在运行模式下,可以通过下面方式降低功耗:① 降低系统时钟。
② 关闭APB和AHB总线上未被使用的外设时钟。
2.STM32F4的待机模式
待机模式理想状态下,只需要2.2uA电流。停机模式下典型电流为350uA。
3.PWR_CR电源控制寄存器
设置PDDS位进入深度睡眠时进入待机模式。
设置CWUF位,清除之前的WUF唤醒位。
4.PWR_CSR电源控制/状态寄存器
设置EWUP,使能WKUP 引脚用于待机唤醒。
WUF唤醒标志,用来判断是否发生唤醒事件。
5.特别说明
6.固件库中低功耗操作函数
文件:stm32f4xx_pwr.c / stm32f4xx_pwr.hvoid PWR_EnterSTOPMode();//进入停机模式
void PWR_EnterSTANDBYMode(void);//进入待机模式
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
FlagStatus PWR_GetFlagStatus(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);
文件: core_cm4.h__WFI() ;
__WFE() ;
7.PWR_EnterSTANDBYMode函数void PWR_EnterSTANDBYMode(void)
{
/* Select STANDBY mode */
PWR->CR |= PWR_CR_PDDS;
/* Set SLEEPDEEP bit of Cortex System Control Register */
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
/* This option is used to ensure that store operations are completed */
#if defined ( __CC_ARM )
__force_stores();
#endif
/* Request Wait For Interrupt */
__WFI();
}
8.PWR_EnterSTOPMode函数void PWR_EnterSTOPMode(uint32_t PWR_Regulator, uint8_t PWR_STOPEntry)
{
uint32_t tmpreg = 0;
tmpreg = PWR->CR;
tmpreg &= CR_DS_MASK;
tmpreg |= PWR_Regulator;
PWR->CR = tmpreg;
SCB->SCR |= SCB_SCR_SLEEPDEEP;
if(PWR_STOPEntry == PWR_STOPEntry_WFI){
__WFI();
}else{
__WFE();
}
SCB->SCR &= (uint32_t)~((uint32_t)SCB_SCR_SLEEPDEEP);
}
9.待机唤醒配置步骤使能电源时钟。
因为要配置电源控制寄存器,所以必须先使能电源时钟。RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);RTC相关处理:关闭RTC相关中断。
设置WK_UP引脚作为唤醒源。
设置PWR_CSR的EWUP位,使能WK_UP用于将CPU从待机模式唤醒。PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。void PWR_EnterSTANDBYMode(void);
三.待机模式代码int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200); //初始化串口波特率为115200
LCD_Init(); //初始化LCD FSMC接口
KEY_Init();
POINT_COLOR=RED;
LCD_ShowString(30,40,210,24,24,"WarShip STM32 ^_^");
while(1)
{
if(KEY_Scan(0)==KEY0_PRES)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); //使能PWR外设时钟
PWR_BackupAccessCmd(ENABLE);//后备区域访问使能
RTC_ITConfig(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA,DISABLE);//关闭RTC相关中断
RTC_ClearITPendingBit(RTC_IT_TS|RTC_IT_WUT|RTC_IT_ALRB|RTC_IT_ALRA);//清楚RTC相关中断标志位。
PWR_ClearFlag(PWR_FLAG_WU);//清除Wake-up 标志
PWR_WakeUpPinCmd(ENABLE); //使能唤醒管脚功能
PWR_EnterSTANDBYMode(); //进入待命(STANDBY)模式
}
delay_ms(10);
}
}
实验程序较为复杂,主要是为了实现同一个引脚PA0引脚(WakeUp引脚),长按3秒进入待机模式,在待机模式下,长按3秒待机唤醒。
程序思路:在待机模式下,WKUP用来唤醒。按下WKUP,就会从待机模式唤醒。
正常情况下(没有进入低功耗模式),WKUP是可以作为正常的输入口,或者中断触发引脚来使用。