STM32CubeMX低功耗模式——待机模式(standby)RTC唤醒

  • 使用CubeMX生成工程
  • 代码处理
  • 实验结果
  • 总结

在ST的单片机中,一般低功耗模式都有stop(停机)模式和standby(待机)模式两种,这篇博客主要是分享一下standby模式,并且通过RTC实时时钟的闹钟将单片机从低功耗模式中唤醒的方法。为了方便演示,实验流程是,通过串口命令来设置单片机进入低功耗模式,再通过RTC的闹钟将单片机从低功耗状态唤醒,进入正常模式。

使用CubeMX生成工程

1.根据使用的单片机来配置生成工程,我使用的是NUCLEO-F303RE来做实验
2.配置需要使用到的外设

首先要设置单片机的时钟源,在这里我是用的是内部高速时钟源和外部的低速时钟源。因为RTC需要使用一个低速时钟源。
激活RTC功能,并设置RTC的闹钟

第一步:配置数据格式为二进制格式(Binary data format),便于后期处理。
第二步:自动异步分频使能,这里可以自动将RTC的时钟源分频成1HZ
第三步:选择使能闹钟屏蔽标识,例如图中的参数设置,表示在秒相同的时候触发,也就是一分钟触发一次闹钟。同理,可以设置一秒触发,一天触发一次或者一周触发一次。

在这里我还设置了串口,用于在实验中显示输出。

最后使能相关的外设的中断。
3.设置好工程名称和保存位置,选择自己用的开发工具和版本,然后生成工程代码

代码处理

首先引用和定义一些必要的头文件和参数

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */#include "usart_user.h"
#include "string.h"/* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */RTC_DateTypeDef gDateType;  //获取RTC日期
RTC_TimeTypeDef gTimeType;  //获取RTC时间RTC_DateTypeDef sDateType;  //设置RTC日期
RTC_TimeTypeDef sTimeType;  //设置RTC时间static char cmd_setTime[] = "AT+SETTIME";   //设置RTC时间命令
static char cmd_standby[] = "AT+STANDBY";   //进入standby模式命令/* USER CODE END PTD */

main函数循环中用于处理命令的部分

 /* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(USART_RX_Finish)   //判断串口接收完成{USART_RX_Finish = 0;   //清除串口接收完成标识if(strncmp(USART_RX_BUF,cmd_setTime,strlen(cmd_setTime)) == 0) //判断命令,处理RTC时钟设置{sTimeType.Hours = (USART_RX_BUF[(strlen(cmd_setTime) + 1)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 2)]-'0');sTimeType.Minutes = (USART_RX_BUF[(strlen(cmd_setTime) + 4)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 5)]-'0');sTimeType.Seconds = (USART_RX_BUF[(strlen(cmd_setTime) + 7)]-'0')*10 +(USART_RX_BUF[(strlen(cmd_setTime) + 8)]-'0');printf("设置RTC时间为 %02d:%02d:%02d \r\n",sTimeType.Hours,sTimeType.Minutes,sTimeType.Seconds);if(HAL_RTC_SetTime(&hrtc,&sTimeType,RTC_FORMAT_BIN)!=HAL_OK)    //设置RTC时间{printf("HAL_RTC_SetTime ERR \r\n");}printf("设置RTC时间成功!\r\n");}if(strncmp(USART_RX_BUF,cmd_standby,strlen(cmd_standby)) == 0) //判断命令,进入standby模式{printf("Executing test (standby) \r\n");GPIO_AnalogState_Config(); //设置IO口为模拟输入状态__HAL_RCC_PWR_CLK_ENABLE();HAL_PWR_EnterSTANDBYMode();    //进入standby模式printf("进入待机模式失败\r\n");}}if((PWR->CSR & PWR_CSR_WUF )== PWR_CSR_WUF)  //清除闹钟中断的标识{PWR->CR |= PWR_CR_CWUF;}HAL_Delay(200);HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin);   //翻转LD2,显示单片机处于正常工作状态}/* USER CODE END 3 */

获取RTC时间和日期的函数,以及RTC的闹钟中断回调函数

/* USER CODE BEGIN 4 *//*获取RTC的时钟和日期*/
void get_date (RTC_DateTypeDef *sDateStruc,RTC_TimeTypeDef *sTimeStruc)
{if(HAL_RTC_GetTime(&hrtc,sTimeStruc,RTC_FORMAT_BIN) != HAL_OK){printf("HAL_RTC_GetTime ERR \r\n");}if(HAL_RTC_GetDate(&hrtc,sDateStruc,RTC_FORMAT_BIN) != HAL_OK){printf("HAL_RTC_GetDate ERR \r\n");}}/*RTC闹钟的回调函数*/
void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{get_date(&gDateType,&gTimeType);printf("当前RTC时间为 %02d:%02d:%02d \r\n",gTimeType.Hours,gTimeType.Minutes,gTimeType.Seconds);}/* USER CODE END 4 */

设置IO口为模拟输入状态的函数,这个函数主要是为了在低功耗状态下,尽量控制IO上不必要的漏电流产生。

/* USER CODE BEGIN 2 */void GPIO_AnalogState_Config(void)
{GPIO_InitTypeDef GPIO_InitStruct;/*Set all GPIO in analog state to reduce power consumption*/__HAL_RCC_GPIOA_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOC_CLK_ENABLE();GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Pin = GPIO_PIN_All;HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);__HAL_RCC_GPIOA_CLK_DISABLE();__HAL_RCC_GPIOB_CLK_DISABLE();__HAL_RCC_GPIOC_CLK_DISABLE();
}/* USER CODE END 2 */

到这里基本就已经实现了单片机的standby模式了,并且可以通过RTC的闹钟实现休眠一分钟后唤醒。但是每次唤醒后都会让RTC时钟的时间重置,所以最后我通过判断后备寄存器的方式,来保证RTC的时间参数在唤醒时不被重置。具体代码如下:

void MX_RTC_Init(void)
{RTC_TimeTypeDef sTime = {0};RTC_DateTypeDef sDate = {0};RTC_AlarmTypeDef sAlarm = {0};/** Initialize RTC Only */hrtc.Instance = RTC;hrtc.Init.HourFormat = RTC_HOURFORMAT_24;hrtc.Init.AsynchPrediv = 127;hrtc.Init.SynchPrediv = 255;hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;if (HAL_RTC_Init(&hrtc) != HAL_OK){Error_Handler();}/* USER CODE BEGIN Check_RTC_BKUP */if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1) != 0xA5A5) //判断后备寄存器是否被赋值{/* USER CODE END Check_RTC_BKUP *//** Initialize RTC and set the Time and Date */sTime.Hours = 0;sTime.Minutes = 0;sTime.Seconds = 0;sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sTime.StoreOperation = RTC_STOREOPERATION_RESET;if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}sDate.WeekDay = RTC_WEEKDAY_MONDAY;sDate.Month = RTC_MONTH_JANUARY;sDate.Date = 1;sDate.Year = 0;if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1, 0xA5A5); //为后备寄存器写入值}/** Enable the Alarm B */sAlarm.AlarmTime.Hours = 0;sAlarm.AlarmTime.Minutes = 0;sAlarm.AlarmTime.Seconds = 0;sAlarm.AlarmTime.SubSeconds = 0;sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS|RTC_ALARMMASK_MINUTES;sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;sAlarm.AlarmDateWeekDay = 1;sAlarm.Alarm = RTC_ALARM_B;if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN) != HAL_OK){Error_Handler();}
}

到这里,待机模式(standby)下RTC唤醒就已经实现了。

实验结果


在电路上,程序复位后,LD2会周期闪烁,然后再发送“AT+STANDBY”命令后,LD2熄灭,然后等待大概1分钟(时间和你发送进入待机模式的时间有关系),LD2重新开始周期闪烁。

经过万用表测量,最后单片机的待机功耗为5.8uA

总结

在利用RTC闹钟唤醒standby模式中,需要关注的问题有:
1.关于功耗控制,需要对不使用的IO口进行漏电流的控制,因此,最好将没有使用的IO口都配置为模拟输入状态。
2.利用RTC闹钟进行唤醒时,需要注意闹钟中断触发后,中断标识是否被清除,否则,standby模式很可能在进入后立马退出。
3.如果要在退出standby模式后,RTC时钟需要继续按照设定的时间计时,需要通过后备寄存器来判断单片机是否是第一次启动。

STM32CubeMX低功耗模式——待机模式(standby)RTC唤醒相关推荐

  1. STM32CubeMX学习笔记(17)——电源管理(PWR)低功耗待机模式

    一.低功耗模式简介 系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗.由用户根据应用选择具体的低功耗模式,以在低功耗.短启动时间和可用唤醒源之间寻求最佳平衡. 睡眠模 ...

  2. 【STM32笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

    [STM32笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_5340 ...

  3. 【极海APM32替代笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)

    [极海APM32替代笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_ ...

  4. 【STM32】电源控制、低功耗模式(实例:待机模式)

    STM32F1xx官方资料: <STM32中文参考手册V10>-第4章4.3小节 低功耗模式 STM32的电源控制 STM32的电源框图 STM32的工作电压(VDD)为2.0-3.6V. ...

  5. 计算机怎么进入待机模式,电脑怎么进入待机模式

    问题一:怎么样能直接让电脑直接进入待机状态呢?要快捷方式~~在控制面板中打开"电源选项",切换到"高级"标签,将"在按下计算机电源按钮时"设 ...

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

    STM32等类似Cortex-M3的MCU在系统或电源复位以后,MCU就会处于程序运行状态.当用户不需继续运行程序时,可以利用进入低功耗模式来节省电池电量,当需要重新运行时,可以通过特定条件进行唤醒程 ...

  7. TM32L0系列之02 RTC唤醒待机模式

    STM32L0系列之02 RTC唤醒待机模式 前言 使用芯片:STM32L051R8T6 软件平台:KEIL V5.STM32CubeL0 库函数:HAL 一.硬件介绍 1.单片机的系统时钟为:32M ...

  8. STM32的RTC闹钟唤醒待机模式

    通过RTC闹钟不能唤醒待机模式下的STM32,但是当注释掉下面这一句程序的时候,就能通过RTC闹钟唤醒. PWR_WakeUpPinCmd(ENABLE);//使能唤醒管脚功能 这就给我们一种错误的判 ...

  9. STM32/AMP32F407进入低功耗待机模式后立马被唤醒的解决办法

    最近项目用到低功耗,但是调试发现进入待机就被唤醒的问题,清除WU.SB两个唤醒标志位,也依然被立马唤醒一次. /* 进入待机模式 */HAL_PWR_EnterSTANDBYMode(); 通过极海的 ...

  10. STM32L4的待机模式闹钟唤醒方法

    很多低功耗应用中有关standby模式的应用超时唤醒STM32单片机用的是rtc计数模式,一般是秒级别的,但是rtc的定时器计数器长度有限,以我应用中16M工作频率计算下来,最多只能计数33秒,而我们 ...

最新文章

  1. 设置echarts的grid、tooltip、柱状图渐变色、折线图渐变色
  2. 交换机SHOW命令,不知道路由器可以参考不·
  3. BZOJ4943 [NOI2017] 蚯蚓
  4. eclipse项目导出错误处理
  5. typedef 字符串_typedef在C中使用字符数组(定义别名来声明字符串)的示例
  6. TortoiseGit 下载、安装、配置_入门试炼_01
  7. 45:十进制到八进制(OpenJudge在线题库 :NOI / 1.13编程基础之综合应用)
  8. Hugo中文文档 快速开始
  9. Teradata 金融数据模型FS-LDM
  10. BAD packet signature 18245
  11. 数据分析|模糊综合评价法
  12. 西门子SIMATIC S7-1500,ET 200SP,HMI触摸屏面板产品型号
  13. Wps文档文件转换成pdf,支持doc-docx-ppt-pptx-xls
  14. 【整理】TAC码是什么?TAC码和IMEI有什么关系?
  15. 算法基础系列第三章——图论之最小生成树问题
  16. 毫秒转化天小时分钟秒
  17. 遇人不淑之逗比程序员
  18. 只要你懂得人性,就不怕没钱赚!
  19. 映射变换(缩放、旋转、剪切)
  20. vim几个小技巧(批量替换,列编辑)

热门文章

  1. 光孝寺招聘员工!月薪15000,早九晚五,免费饭菜,有证者优先,工作六根清净,而且.......
  2. 智慧教育平台android,智慧教育平台APP 1.0.2 安卓版
  3. PayPal支付开发
  4. 金融风控建模全流程(Python,收藏)
  5. Linux下使用nmap扫描端口
  6. TestStand自定义报表生成-添加列
  7. 8583:全面掌握ISO8583报文协议zz
  8. Java jdk的下载与安装
  9. MySQL基础——DDL语句
  10. SSM框架整合思想及步骤