STM32低功耗睡眠模式(SLEEP)中断(INTERRUPT)唤醒实现及优化STM32 低功耗睡眠模式(SLEEP)中断(INTERRUPT)唤醒实现及优化
1. 介绍
STM32具有多种低功耗模式,当前以STM32L4系列的低功耗模式最为丰富,此处基于STM32L476和STM32CUBEIDE环境介绍睡眠模式(SLEEP)中断唤醒的实现(HAL库), 唤醒中断可为任⼀中断,本例以管脚中断为中断源。SLEEP模式只是停⽌CPU时钟和后续代码执⾏,唤醒(其实是continue的作⽤)后继续执⾏后⾯的代码,⽽不是重启之后从初始代码开始执⾏。
2. 低功耗模式
STM32L4的低功耗模式,包括传统的睡眠模式:
STM32L4系列各种低功耗模式的特性总结如下:
3. 管脚中断配置
STOP模式可以通过任⼀管脚中断(Interrupt)或事件(Event)的⽅式唤醒,这⾥介绍通⽤管脚中断唤醒的⽅式, 选择⼀个GPIO管脚进⾏配置,这⾥⽤PC13作为唤醒源。
设置PC13为GPIO_EXTI⽅式:
设置PC13为GPIO_EXTI⽅式:
为PC13选择其中⼀种中断触发⽅式,包括上升沿触发,下降沿触发和电平变化触发(即上升沿下降沿都触发):
然后使能中断:
保存后⽣成代码:
4. SLEEP模式进⼊及中断唤醒
通过HAL库函数HAL_PWR_EnterSLEEPMode(uint32_t Regulator, uint8_t SLEEPEntry)可进⼊SLEEP模式,库函数有两个参数,第⼀个参数Regulator可选PWR_MAINREGULATOR_ON或PWR_LOWPOWERREGULATOR_ON,分别对应主电源保持打开和低功耗部分的电源保持打开。第⼆个参数SLEEPEntry指定唤醒时的来源,有两个可选:PWR_SLEEPENTRY_WFI 和
PWR_SLEEPENTRY_WFE, 分别对应中断唤醒和事件唤醒,这⾥我们⽤PWR_SLEEPENTRY_WFI,即中断唤醒。
如果要进⼊SLEEP模式,实施下⾯代码:
HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
或
HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);
然后当PC13管脚上产⽣电平变化触发管脚中断,睡眠状态就会被唤醒,继续给CPU供应时钟,执⾏后⾯的代码。
5. SLEEP模式进⼊及中断唤醒的优化
当设计中存在多种中断源,包括调试器中断和其它管脚中断时,这些中断不是想⽤于唤醒SLEEP状态的中断,此时就需要增加必要的设计,实现:
1. 当指定的中断源产⽣中断时,唤醒SLEEP状态;
2. 当⾮指定的中断源产⽣中断唤醒SLEEP后,⽴即重新进⼊SLEEP模式。
实现⽅式如下,先增加⼀个判断变量flag_recog:
uint8_t flag_recog = 0;
在进⼊SLEEP模式时,采⽤如下代码:
flag_recog = 0;
while(flag_recog == 0) HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON,PWR_SLEEPENTRY_WFI);
或
flag_recog = 0;
while(flag_recog == 0) HAL_PWR_EnterSLEEPMode(PWR_LOWPOWERREGULATOR_ON,PWR_SLEEPENTRY_WFI);
这样,当异常中断引起唤醒时,因为flag_recog保持为0,所以会再次执⾏进⼊SLEEP模式的代码。
当指定的唤醒中断到来时,如这⾥的PC13,则修改中断处理函数为:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin==GPIO_PIN_13)
{
flag_recog = 1;
}
}
从⽽在中断处理函数⾥将flag_recog设置为⾮0,在退出中断处理函数后,也会退出while(flag_recog == 0)的循环,执⾏后⾯的代码。通过以上优化,提⾼了SLEEP低功耗模式应⽤的可靠性,避免异常时间的唤醒。
–End–