一、低功耗模式介绍
低功耗模式:在系统或者电源复位后,微控制器出于运行状态之下,HCLK为CPU提供时钟,内核执行代码。当CPU不需要继续运行时,可以利用多种低功耗模式来节省功耗,例如等待某个事件触发。
STM32的三种低功耗模式:
1、睡眠模式:内核停止,外设如:NVIC,系统时钟Systick仍运行。
2、停止模式:所有时钟都已停止。1.8V内核电源工作。PLL,HIS和HSE RC振荡器功能禁止。寄存器和SRAM内容保留。
3、待机模式:1.8V内核电源关闭。只有备份寄存器和待机电路维持供电。寄存器和SRAM内容全部丢失。实现最低功耗。
在运行模式下,可以通过降低系统时钟或关闭APB和AHB总线上未使用的外设时钟的方式来降低功耗
STM32F4的待机模式:
待机模式下的I/O状态:
在待机模式下,除复位引脚、RTC_AF1引脚(PC31)和WKUP引脚(PA0)以外,所有I/O引脚都处于高阻状态。待机模式理想状态下,只需要2.2uA电流。停机模式下典型电流350uA。
用户可根据最低电源功耗,最快启动时间和可用的唤醒源等条件,选择合适的低功耗模式。
二、相关寄存器
PWR_CR电源控制寄存器
1)设置PDDS位进入深度睡眠时进入待机模式。
2)设置CWUF位,清除之前的WUF唤醒位。
PWR_CSR电源控制/状态寄存器
1)设置EWUP,使能WKUP引脚用于待机唤醒。
2)WUF唤醒标志,用来判断是否发生唤醒事件。
特别说明
对于使能了RTC闹钟中断或者RTC周期唤醒等中断的时候,进入待机模式前,必须按如下操作处理:
1、禁止RTC中断(ALRAIE、ALRBIE、WUTIE、TAMPIE和TSIE等)
2、清零对应中断标志位。
3、清除PWR唤醒(WUF)标志(通过设置PWR_CR的CWUF位实现)
4、重新使能RTC对应中断。
5、进入低功耗模式
在有用到RTC相关中断的时候,必须按以上步骤执行后,才可以进入待机模式,否则可能无法唤醒。
三、低功耗模式配置实验
固件库中低功耗操作函数:
void PWR_EnterSTOPMode();//进入停机模式
void PWR_EnterSTANDBYMode(void);//进入待机模式
void PWR_WakeUpPinCmd(FunctionalState NewState);//使能Wakeup引脚唤醒
FlagStatus PWR_GetFlagStatue(uint32_t PWR_FLAG);
void PWR_ClearFlag(uint32_t PWR_FLAG);
待机唤醒配置步骤:
1、使能电源时钟
因为要配置电源控制寄存器,所以必须先使能电源时钟。
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
2、RTC相关处理:关闭RTC相关中断。
3、设置WK_UP引脚作为唤醒源
设置PWR_CSR的EWUP位,使能WK_UP用于将CPU从待机模式唤醒。
PWR_WakeUpPinCmd(ENABLE);//使能唤醒管脚功能
4、设置SLEEPDEEP位,设置PDDS位,执行WFI指令,进入待机模式。
void PWR_EnterSTANDBYMode(void);
//部分代码,目的:按下一个按键就会执行上面所述的步骤
int main()
{KEY_Init();//初始化按键while(1){if(KEY_Scan(0)==KEY0_PRES)//判断KEY0是否按下{ RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能电源时钟//关闭RTC相关中断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_ALRA|RTC_IT_ALRB);//清除RTC相关中断标志位PWR_WakeUpPinCmd(ENABLE);PWR_ClearFlag(PWR_FLAG_WU);//清除Wake up标志PWR_EnterSTANDBYMode();//进入待机唤醒模式}}
}
四、程序执行过程
void Sys_Enter_Stanby(void)
{while(WKUP_KD);//等待WK_UP按键松开(在有RTC中断时,必须等WK_UP松开再进入待机)RCC_AHB1PeriphResetCmd(0x04ff,ENABLE);//复位所有IO口,使其成为高阻状态RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PER时钟PWR_BackupAccessCmd(ENABLE);//后备区域访问使能//关闭RTC相关中断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);//设置WKUP用于唤醒PWR_EnterSTANDBYMode();//进入待机模式
}
u8 Check_WKUP(void)
{u8 t=0;u8 tx=0;//记录松开的次数LED0=0;//亮灯while(1){if(WKUP_KD)//已经按下{t++;tx=0;}else{tx++;if(tx>3)//超过90ms内没有WKUP信号{LED0=1;return 0;//错误的按键,按下次数不够}}delay_ms(30);if(t>=100)//按下超过三秒{LED0=0;//点亮LED0return 1;//按下三秒以上}}
}
//连续按下三秒以上,就认为按下,然后亮灯。否则不亮