返回列表 发新帖我要提问本帖赏金: 50.00元(功能说明)

[STM32F1] STM32 低功耗待机模式与RTC周期唤醒

[复制链接]
1790|6
 楼主| forgot 发表于 2023-2-6 15:21 | 显示全部楼层 |阅读模式

      STM32等类似Cortex-M3的MCU在系统或电源复位以后,MCU就会处于程序运行状态。当用户不需继续运行程序时,可以利用进入低功耗模式来节省电池电量,当需要重新运行时,可以通过特定条件进行唤醒程序继续或重新工作。特别是在电池供电的智能终端上有着比较广泛的应用。
STM32F103三种低功耗模式状态说明:
1、睡眠模式:内核停止运行,所有外设仍然处于工作状态。
2、停止模式:所有的时钟都已停止,调压器可以被置于普通模式或低功耗模式。
3、待机模式:所有的时钟都已停止,内部1.8V部分的供电被切断,电压调节器关闭。可以达到最低的电能消耗。

微信截图_20230206141047.png

三种模式电流功耗大小排序为:
运行 > 睡眠 > 停止 > 待机。
其中运行模式与睡眠模式功耗为mA级,停止模式与待机模式为uA级,其中待机最小可以达到<5uA。
如何进入?
睡眠模式:
执行WFI或WFE指令可以使MCU进入睡眠状态。

停止模式:
在以下条件下执行WFI或WFE指令:
1、设置Cortex-M3系统控制寄存器中的SLEEPDEEP位;
2、清除电源控制寄存器(PWR_CR)中的PDDS位 进入;
3、通过设置PWR_CR中LPDS位选择电压调节器的模式;

待机模式:
在以下条件下执行WFI或WFE指令:
1、设置Cortex-M3系统控制寄存器中的SLEEPDEEP位;
2、设置电源控制寄存器(PWR_CR)中的PDDS位;
3、清除电源控制/状态寄存器(PWR_CSR)中的WUF位;
如何退出?
睡眠模式:
如果是执行WFI指令进入睡眠模式,任意一个外设中断都能将系统从睡眠模式唤醒。如果是执行WFE指令进入睡眠模式,一旦发生唤醒事件时,微处理器都将从睡眠模式退出。

停止模式:
如果是执行WFI进入停止模式,任一外部中断线为中断模式可以唤醒。如果是执行WFE进入停止模式。任一外部中断线为事件模式可以唤醒。

待机模式:
待机模式唤醒只有4种:外部复位、IWDG复位、WKUP引脚上的上升沿或RTC闹钟事件的上升沿。并且从待机唤醒后,除了电源控制/状态寄存器,所有寄存器被复位。唤醒后的代码执行等同于复位后的执行。

睡眠模式进入与退出:
微信截图_20230206143045.png

停止模式进入与退出
微信截图_20230206143033.png

待机模式进入与退出
微信截图_20230206143022.png
待机模式是功耗最低的一种模式,外部复位、IWDG复位、WKUP引脚上的上升沿比较简单。主要实验RTC闹钟事件唤醒。RTC具有三个中断源:秒中断、闹钟中断与溢出中断。
首先配置开启中断分组与电源控制器时钟:
  1. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

  2. RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);

然后配置RTC模块参数,由于使用的是外部32.768K的晶振:
RTC_SetPrescaler(32767);可以实现1S1次计数。

开启RTC_IT_ALR闹钟中断:
RTC_ITConfig(RTC_IT_ALR, ENABLE);

配置闹钟参数:
RTC_SetAlarm(RTC_GetCounter() + SLEEP_TIME);SLEEP_TIME就是多长时间发生一次闹钟。
RTC配置代码:
  1. void RTC_Init(void)
  2. {
  3.     u16 BKP_Value = 0x5A5A;

  4.     NVIC_InitTypeDef NVIC_InitStructure;
  5.     RCC_APB1PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);

  6.     NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
  7.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  8.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  9.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  10.     NVIC_Init(&NVIC_InitStructure);

  11.     if(BKP_ReadBackupRegister(BKP_DR1) != BKP_Value) {
  12.         PWR_BackupAccessCmd(ENABLE);
  13.         RCC_LSEConfig(RCC_LSE_ON);
  14.         while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET)IWDG_ReloadCounter();
  15.         RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  16.         RCC_RTCCLKCmd(ENABLE);
  17.         RTC_WaitForLastTask();
  18.         RTC_WaitForSynchro();
  19.         RTC_WaitForLastTask();
  20.         RTC_SetPrescaler(32767);
  21.         RTC_WaitForLastTask();
  22.         RTC_SetCounter(0);
  23.         RTC_WaitForLastTask();
  24.         RTC_SetAlarm(RTC_GetCounter() + SLEEP_TIME);
  25.         RTC_WaitForLastTask();
  26.         RTC_ITConfig(RTC_IT_ALR, ENABLE);
  27.         RTC_WaitForLastTask();
  28.         BKP_WriteBackupRegister(BKP_DR1, BKP_Value);
  29.         RTC_WaitForLastTask();
  30.         PWR_BackupAccessCmd(DISABLE);
  31.     } else {
  32.         PWR_BackupAccessCmd(DISABLE);
  33.         RTC_WaitForSynchro();
  34.         RTC_ITConfig(RTC_IT_ALR, ENABLE);
  35.         RTC_WaitForLastTask();
  36.     }
  37. }

RTC中断代码:在中断中重新清除相关标志并重新配置参数。
  1. void RTC_IRQHandler(void)
  2. {
  3.     IWDG_Feed();
  4.     if (RTC_GetITStatus(RTC_IT_SEC) != RESET) {
  5.         RTC_ClearITPendingBit(RTC_IT_SEC);
  6.     }
  7.     if(RTC_GetITStatus(RTC_IT_ALR)!= RESET) {
  8.         RTC_ClearITPendingBit(RTC_IT_ALR);
  9.         PWR_BackupAccessCmd(ENABLE);
  10.         RTC_WaitForLastTask();
  11.         RTC_SetAlarm(RTC_GetCounter() + SLEEP_TIME);
  12.         RTC_WaitForLastTask();
  13.         PWR_BackupAccessCmd(DISABLE);
  14.     }
  15.     RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);

  16.     if(PWR_GetFlagStatus(PWR_FLAG_WU) != RESET) {
  17.         PWR_ClearFlag(PWR_FLAG_WU);
  18.     }
  19.     if(PWR_GetFlagStatus(PWR_FLAG_SB) != RESET) {
  20.         PWR_ClearFlag(PWR_FLAG_SB);
  21.     }
  22. }

这样就可以实现在任务代码中调用PWR_EnterSTANDBYMode();进入低功耗,MCU会在每隔SLEEP_TIME之后进行唤醒,
可以通过该办法周期性唤醒实现上电必要端口检测等条件来确定是否进入运行模式或者是继续进入低功耗模式来节约电池电量。
说明:RTC配置部分已经经过实验确定可以周期唤醒,有需要的可以直接使用。



打赏榜单

21ic小管家 打赏了 50.00 元 2023-03-13
理由:签约作者奖励

软核硬核 发表于 2023-2-7 14:13 | 显示全部楼层
现在很多产品都需要低功耗模式。
LLGTR 发表于 2023-2-7 14:13 | 显示全部楼层
这篇文章讲解的不错,基本上都是这么操作的。

评论

谢谢  发表于 2023-2-7 15:02
芯路例程 发表于 2023-2-7 14:14 | 显示全部楼层
进入低功耗时,有一些外设也需要失能,要不功耗还是高。

评论

是的,老铁  发表于 2023-2-7 15:01
cjl504 发表于 2023-2-10 09:04 来自手机 | 显示全部楼层
电池供电的便携设备,都需要低功耗,讲解很详细。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2112

主题

14683

帖子

59

粉丝
快速回复 在线客服 返回列表 返回顶部