完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
最近工作一直在做低功耗相关的产品,这次用到了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 if(XTUpCounter>=HSE_STARTUP_TIMEOUT_Num) { XTUpCounter = 0; RCC_LSICmd(ENABLE); /*!< 等待外部低速时钟就绪 */ while ((RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)&& (XTUpCounter if(XTUpCounter 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); //关闭I2C1 Delay_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 if(StartUpCounter1 /* 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模式的代码模块,预祝大家工作顺利 :) |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1752 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1611 浏览 1 评论
1052 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
721 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1666 浏览 2 评论
1924浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
711浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
560浏览 3评论
583浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
544浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-18 12:32 , Processed in 0.815060 second(s), Total 78, Slave 62 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号