STM32/STM32L151 RTC唤醒低功耗STOP(停机模式)
最近工作一直在做低功耗相关的产品,这次用到了STM32L151的STOP模式,RTC定时唤醒STOP模式需要注意以下几点内容:
1.RTC需要正确配置,启动外部低速32.768Khz(外挂晶振)用来启用定时,经过测试还是比较准确的,如果外部没有挂晶振则可以用内部的低速时钟
2.做低功耗的话就是要将功耗降下来:所以IO的配置还是比较重要的,经过测试将不用的IO配置为模拟输入可以有效降低功耗(是否上下拉则看外设是否外接),在进入停止模式之前关闭中断/ADC/I2C等开启的外设,唤醒之后需要重新初始化外设
3.由于停机模式下,所有的时钟都停止了,下面的框图是RTC的时钟源描述所用选用的LSE
4.补充下关于STOP模式的描述:
下面描述的是:进入STOP模式下内部振荡器将关闭,寄存器内容保持原来的配置,IO保持进入模式之前的配置运行(这几点尤为重要)
这里描述退出STOP MODE的方式:中断或者中断事件(MSI振荡器选择系统时钟)
说说MSI基本校准原理:
通过32.768K晶振连接到TIM21当中,产生参考值与当前MSI振荡器进行对比,找到一个适合的差值,写入MSI校准寄存器中!即可完成。
在X-CUBE-RC-CALIB的参考代码中MSI MinError这种经典方案可以用来做校准。10个周期下来大概消耗 1.4s时间完成校准
接下来就用代码分模块描述关于RTC 和STOP:
RTC初始化部分
//RTC定时函数初始化
//需要注意外部时钟LSE初始化的时间太短的话是无法等待就绪的//等待LSE晶振时间
#define HSE_STARTUP_TIMEOUT_Num 0xFFFFF void SYS_RTCInit(uint32_t wkuptime)
{uint8_t RTCStateFlag = 0;__IO uint32_t XTUpCounter = 0;static NVIC_InitTypeDef NVIC_InitStructure;static EXTI_InitTypeDef EXTI_InitStructure;static RTC_InitTypeDef RTC_InitStructure;static RTC_TimeTypeDef RTC_TimeStructure;static RTC_DateTypeDef RTC_DateStruct;//使能PWR时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);/*!< Allow access to RTC 使能后备寄存器访问*/PWR_RTCAccessCmd(ENABLE);RCC_RTCResetCmd(ENABLE);RCC_RTCResetCmd(DISABLE);/*!< 使能外部低速时钟 */RCC_LSEConfig(RCC_LSE_ON);/*!< 等待外部低速时钟就绪 */while ((RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET)&&(XTUpCounter<HSE_STARTUP_TIMEOUT_Num)) {XTUpCounter++;}if(XTUpCounter>=HSE_STARTUP_TIMEOUT_Num){XTUpCounter = 0;RCC_LSICmd(ENABLE);/*!< 等待外部低速时钟就绪 */while ((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)&& (XTUpCounter<HSE_STARTUP_TIMEOUT_Num)){XTUpCounter++;}if(XTUpCounter<HSE_STARTUP_TIMEOUT_Num){RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI); //选择内部晶振作为RTC时钟源RTCStateFlag = 2;}else{RTCStateFlag = 0;}}else{RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);//选择外部晶振作为RTC时钟源RTCStateFlag = 1;}
/*****************************************************/if(RTCStateFlag != 0){/*!< 使能RTC时钟 */RCC_RTCCLKCmd(ENABLE);/*!< Wait for RTC APB registers synchronisation 等待时钟同步*/RTC_WaitForSynchro();/* 配置RTC数据寄存器以及时钟分频 */RTC_InitStructure.RTC_AsynchPrediv = 0X7F;//同步 设置预分频为1S一次RTC_InitStructure.RTC_SynchPrediv = 0XFF; //异步 255 RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;//24小时制/* 检查RTC初始化 */if(RTC_Init(&RTC_InitStructure) == ERROR){while(1);}/* Set the date: Thursday January 11th 2018,2018/01/25 星期四 */RTC_DateStruct.RTC_Year = 0x18;RTC_DateStruct.RTC_Month = RTC_Month_January;RTC_DateStruct.RTC_Date = 0x27;RTC_DateStruct.RTC_WeekDay = RTC_Weekday_Thursday;RTC_SetDate(RTC_Format_BCD, &RTC_DateStruct);/* Set the time to 10h 09mn 15s AM ,早上10:09:15*/RTC_TimeStructure.RTC_H12 = RTC_H12_PM;RTC_TimeStructure.RTC_Hours = 0x21;RTC_TimeStructure.RTC_Minutes = 0x57;RTC_TimeStructure.RTC_Seconds = 0x33; RTC_SetTime(RTC_Format_BCD, &RTC_TimeStructure);/* 配置外部中断控制线20,实现RTC唤醒 */EXTI_ClearITPendingBit(EXTI_Line20);EXTI_InitStructure.EXTI_Line = EXTI_Line20;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_Init(&EXTI_InitStructure);/*使能 RTC 中断 */// NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);NVIC_InitStructure.NVIC_IRQChannel = RTC_WKUP_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);//先关闭TRC中断使能RTC_WakeUpCmd(DISABLE); //为唤醒功能选择RTC配置好的时钟源RTC_WakeUpClockConfig(RTC_WakeUpClock_CK_SPRE_16bits);//设置WAKE UP自动重装载寄存器RTC_SetWakeUpCounter(wkuptime);//(32768hz/128)-1 = 255 1S//清除RTC唤醒中断标志RTC_ClearFlag(RTC_FLAG_WUTF);//使能RTC唤醒中断RTC_ITConfig(RTC_IT_WUT, ENABLE);//使能唤醒功能RTC_WakeUpCmd(ENABLE);}
}
进入STOP的函数模块:进入STOP模式之前关闭所有外设,配置IO状态,退出STOP模式后重新选择系统时钟
/***待机模式下:所有时钟停止,RTC(LSE)中断唤醒,休眠前配置IO状态,唤醒后 RCC时钟源切换到外部高速时钟
*/
void RCC_Enter_Stop(void)
{__IO uint32_t StartUpCounter1 = 0;ADC_Cmd(ADC1,DISABLE); //关闭ADC1 电池电压检测I2C_Cmd(I2C1,DISABLE); //关闭I2C1Delay_ms(500);/* Enter Stop Mode */PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); //停机模式/***唤醒后mcu时钟源选择外部高速时钟***//* Enable HSE */RCC_HSEConfig(RCC_HSE_ON);/* Wait till HSE is ready */while ((RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET)&& (StartUpCounter1<HSE_STARTUP_TIMEOUT_Num)){StartUpCounter1++;}if(StartUpCounter1<HSE_STARTUP_TIMEOUT_Num){/* Enable PLL */RCC_PLLCmd(ENABLE);/* Wait till PLL is ready */while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); /* Select PLL as system clock source */RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);/* Wait till PLL is used as system clock source */while (RCC_GetSYSCLKSource() != 0x0C){}}}
主函数
void main()
{/*外设初始化*/SYS_RTCInit(60 * 2); //RTC定时初始化,定时时间2分钟while(1){/*这里存放你的工作代码 */RCC_Enter_Stop(); //工作休眠/*唤醒后重新初始化外设IO*//*串口,I2C等等*/}}
以上就是RTC唤醒低功耗 STOP模式的代码模块,预祝大家工作顺利 :)
STM32/STM32L151 RTC唤醒低功耗STOP(停机模式)相关推荐
- 【STM32笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)
[STM32笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_5340 ...
- STM32CubeMX(stm32F030C8T6) 之RTC闹钟唤醒停机模式-STM32开发实战 (2)
一.概述 本例程是用STOP休眠模式,用RTC的周期性自动唤醒功能来唤醒芯片. 根据手册的说明:这里有个可编程的可自动重装的向下计数器,按照相应的时钟频率赋予适当的值,每当向下计数到0时便产生一个唤醒 ...
- 【STM32】RTC休眠唤醒(停机模式)、独立看门狗开启状态下
本文章基于STM32F103RC: 在开启独立看门狗的状态下,进入停机模式,由RTC定时闹钟唤醒系统. 直接上代码: #include "main.h" static void R ...
- 【STM32笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)
[STM32笔记]HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒.串口唤醒和回调无法一起使用.接收数据不全的问题) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csd ...
- 【极海APM32替代笔记】低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER)
[极海APM32替代笔记]低功耗模式下的RTC唤醒(非闹钟唤醒,而是采用RTC_WAKEUPTIMER) [STM32笔记]低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_ ...
- STM32——浅谈睡眠模式、停机模式、待机模式
若要理解低功耗,则先要说一下STM32的事件和中断 事件是中断的触发源,开放了对应的中断屏蔽位,则事件可以触发相应的中断.在STM32中,中断与事件不是等价的,一个中断肯定对应一个事件,但一个事件不一 ...
- stm32芯片休眠模式_STM32睡眠模式低功耗(停止模式)
目前stm32已经非常流行了,那么本文讨论下stm32低功耗模式,不多说先上手册内容! 这是英文文档 不好看懂是吧,下面看中文文档! 我对比了 STM32F0 和 STM32F1 两者进入低功耗是一样 ...
- TM32L0系列之02 RTC唤醒待机模式
STM32L0系列之02 RTC唤醒待机模式 前言 使用芯片:STM32L051R8T6 软件平台:KEIL V5.STM32CubeL0 库函数:HAL 一.硬件介绍 1.单片机的系统时钟为:32M ...
- STM32的3种低功耗模式
STM32的3种低功耗模式: 睡眠模式:内核停止,外设如NVIC,系统时钟Systick仍运行. 停止模式:所有时钟都已停止:1.8V内核电源工作:PLL,HIS和HSERC振荡器功能禁止:寄存器和S ...
- STM32睡眠模式低功耗(停止模式)
目前stm32已经非常流行了,那么本文讨论下stm32低功耗模式,不多说先上手册内容! 这是英文文档 不好看懂是吧,下面看中文文档! 我对比了 STM32F0 和 STM32F1 两者进入低功耗是一样 ...
最新文章
- 阻塞与非阻塞的IO网络读写
- 实现网页中增加刷新按钮、链接的方法 搜集
- 다양한 저장매체의 속도를 측정
- oc语言和c语言,C语言及OC语言初期学习心得
- 若川的 2021 年度总结,弹指之间
- solidity开发以太坊代币智能合约
- 「R」ggplot2拼图包patchwork推荐与使用
- 【转载】使用Epoll的框架例子二
- 编译报错程序集版本高于所引用的程序集的版本
- win10 打开注册表
- 将Excel中的信息生成奖状
- JOHNSON算法:流水作业最优调度问题
- 2018年深圳杯论文_2018年深圳杯数学建模挑战赛通知及题目
- 【7gyy】密码丢了?揭秘你的密码是如何被偷走的
- 程序员赚零钱食用指南
- 分享一个火遍全网的 Python 框架,爆赞!
- VBA小模板:一个奖励放回的普通抽奖用VBA怎么写?
- python sqlachemy模糊查询报错
- 解决部署Hexo后出现的The custom domain for your GitHub Pages site is pointed at an outdated IP address警告
- 详解跨境电商企业信息化建设的关键点:业财一体化