STM32F412/413 STOP模式下HAL_RTC_GetTime读取时间异常求助
STM32F412/F413 STOP模式唤醒后RTC读取异常的解决方案
问题根源
STOP模式下,RTC核心模块依靠外部LSE持续运行,但APB1总线时钟会被关闭,导致RTC的影子寄存器(RTC_TR、RTC_DR,HAL库读取时间/日期的数据源)停止更新。当处理器从STOP模式唤醒后,APB1时钟恢复,RTC需要几个RTCCLK周期(LSE为32768Hz时约91us)完成影子寄存器与核心时钟的同步,此时直接读取会拿到睡眠前的旧值,导致sleepTime计算为0。
解决方案
方法1:使用HAL库同步函数(推荐)
唤醒后调用HAL_RTC_WaitForSynchro(),该函数会自动等待RTC影子寄存器同步完成(检测RTC_ISR寄存器的RSF标志位),确保读取到最新时间:
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) ; RTC_TimeTypeDef sTimeBefore, sTimeAfter ; RTC_DateTypeDef sDateBefore, sDateAfter ; int sleepTime = 0 ; int totalSleepTime = 0 ; while(sleep) { ReadRTC(&sTimeBefore, &sDateBefore); HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON , PWR_STOPENTRY_WFE ) ; // 等待RTC影子寄存器同步完成 HAL_RTC_WaitForSynchro(&hrtc); ReadRTC(&sTimeAfter, &sDateAfter); sleepTime = CalculateSleepTime(sTimeBefore, sDateBefore, sTimeAfter, sDateAfter); totalSleepTime += sleepTime; if (totalSleepTime > x) sleep = 0 ; }
方法2:手动检测RSF标志位
如果需要更精细的超时控制,可以直接读取RTC_ISR的RSF位,等待其置1后再读取时间:
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS) ; RTC_TimeTypeDef sTimeBefore, sTimeAfter ; RTC_DateTypeDef sDateBefore, sDateAfter ; int sleepTime = 0 ; int totalSleepTime = 0 ; while(sleep) { ReadRTC(&sTimeBefore, &sDateBefore); HAL_PWR_EnterSTOPMode( PWR_LOWPOWERREGULATOR_ON , PWR_STOPENTRY_WFE ) ; // 等待RSF标志置1,超时时间根据LSE频率调整(此处设为10ms) uint32_t timeout = 10000; while((__HAL_RTC_GET_FLAG(&hrtc, RTC_FLAG_RSF) == RESET) && timeout--) { HAL_Delay(1); } // 可添加超时错误处理 if(timeout == 0) { // 同步超时,执行错误逻辑 } ReadRTC(&sTimeAfter, &sDateAfter); sleepTime = CalculateSleepTime(sTimeBefore, sDateBefore, sTimeAfter, sDateAfter); totalSleepTime += sleepTime; if (totalSleepTime > x) sleep = 0 ; }
注意事项
- 必须保持
ReadRTC中先调用HAL_RTC_GetTime再调用HAL_RTC_GetDate的顺序,这是HAL库要求的,否则会导致读取错误。 HAL_RTC_WaitForSynchro()的默认超时时间为1000ms,足够覆盖LSE同步所需的极短时间,无需额外调整。
内容的提问来源于stack exchange,提问作者Shai Amar
相关产品推荐
相关产品推荐

