你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F103 RTC 休眠唤醒后 读到的时间不对

[复制链接]
憨客鱼 提问时间:2026-3-11 19:39 / 未解决

我使用RTC 进行休眠唤醒,进入休眠电流值 OK, RTC 也能唤醒,但是唤醒后 RTC 读到的时间就不对了,请问是什么原因

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);

sTime.Seconds  = sTime.Seconds  + 30;
if(sTime.Seconds>=60)
{
    sTime.Seconds = sTime.Seconds -60;
    sTime.Minutes = sTime.Minutes +1;
}
if(sTime.Minutes >=60)
{
    sTime.Minutes = sTime.Minutes  -60;
    sTime.Hours  = sTime.Hours  +1;

}

g_sAlarm.AlarmTime.Hours = sTime.Hours ; g_sAlarm.AlarmTime.Minutes = sTime.Minutes; g_sAlarm.AlarmTime.Seconds = sTime.Seconds; g_sAlarm.Alarm= RTC_ALARM_A;

// HAL_PWR_EnableBkUpAccess();

HAL_RTC_SetAlarm_IT(&hrtc, &g_sAlarm, RTC_FORMAT_BIN);

HAL_Delay(1);


HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);

__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);

HAL_PWR_EnableBkUpAccess();                 

// HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); // HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI);
HAL_PWR_EnterSTANDBYMode();

SystemClock_Config();

// SystemClock_RestoreFromStop(); MX_GPIO_Init(); MX_TIM6_Init(); MX_ADC1_Init(); // MX_RTC_Init(); // My_RTC_Init(); MX_SPI2_Init(); MX_UART4_Init(); HAL_Delay(10); Fun_Main_Init();

收藏 评论12 发布时间:2026-3-11 19:39

举报

12个回答
摩洛哥的制砖匠人 回答时间:3 天前

外部电池,外部晶振

butterflyspring 回答时间:3 天前
看到代码中进入了 STANDBY 模式。 这个模式唤醒后代码会从头新执行,类似与复位。

After waking up from Standby mode, program execution restarts in the same way as after a
Reset (boot pins sampling, vector reset is fetched, etc.).

所以检查一下代码开始,是不是没有判断RTC被初始化过还是上电复位,从而决定是否需要重新初始化RTC。
如果没有这一步,那么每次唤醒都会初始化RTC从而使得时间不能连续。 库中有例程可以参考。

STM32F103 RTC standby wakeup.PNG

xmshao 回答时间:3 天前
  1. 你唤醒后或者复位后,你这样操作:

    清 RSF → 等 RSF 置 1 → 再读时间,再读日期。

  2. 读操作不要只读一部分,时分秒日期都要读取,先读时间 后读日期。

憨客鱼 回答时间:前天 10:56

butterflyspring 发表于 2026-3-12 10:02
看到代码中进入了 STANDBY 模式。 这个模式唤醒后代码会从头新执行,类似与复位。</p>
<p>After waking up from S ...

我把MX_RTC_Init 函数下面这段代码// 掉了,但是还是不对,是不是可以认为,只要RTC 初始化过了,时间就不对了,那我该怎么处理呢,我尝试用一个寄存器做标注,但是重启后这个寄存器好像也呗初始化了

/ USER CODE BEGIN Check_RTC_BKUP /

/ USER CODE END Check_RTC_BKUP /

/* Initialize RTC and set the Time and Date / /* sTime.Hours = 0; sTime.Minutes = 0; sTime.Seconds = 0;

if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; DateToUpdate.Month = RTC_MONTH_JANUARY; DateToUpdate.Date = 1; DateToUpdate.Year = 0;

if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } */

憨客鱼 回答时间:前天 11:18

xmshao 发表于 2026-3-12 17:10</p>
<ol>
<li>
<p>你唤醒后或者复位后,你这样操作:</p>
<p>清 RSF → 等 RSF 置 1 → 再读时间,再读日期。

[md]好像没找到这个寄存器

c7a6c801-d150-44d9-9eb9-af9cd49b2fe2.png

9727db05-2b7d-47a1-8a77-c3c1bac330ac.png
9727db05-2b7d-47a1-8a77-c3c1bac330ac.png
9727db05-2b7d-47a1-8a77-c3c1bac330ac.png
xmshao 回答时间:前天 12:03

我找了下,有的。 不同系列寄存器有点不一样,F1系列在RTC_CRL。

image.png

关键地方,就是你每次读日历时,保证按照先读TIME,再读DATE的步骤进行很重要。

butterflyspring 回答时间:前天 15:05
可以参考库中的例程,用备份域寄存器作为标志来判断是否掉过电。
\STM32Cube_FW_F1_V1.8.6\Projects\STM3210E_EVAL\Examples\RTC\RTC_Calendar




STM32F103 RTC DEMO CODE .PNG

xmshao 回答时间:前天 17:25

憨客鱼 发表于 2026-3-13 10:56
我把MX_RTC_Init 函数下面这段代码// 掉了,但是还是不对,是不是可以认为,只要RTC 初始化过了,时 ...

[md]怎么来回初始化呢。

你初始化后,建个标志. STM32F1系列里常用个备份域寄存器来做标志。

每次复位后检查该标志,如果该标志已经被你设置过了,就跳过RTC的初始化。

憨客鱼 回答时间:前天 18:01

butterflyspring 发表于 2026-3-13 15:05
可以参考库中的例程,用备份域寄存器作为标志来判断是否掉过电。
\STM32Cube_FW_F1_V1.8.6\Projects\STM321 ...

RTC_CalendarConfig 找不到这个函数啊

憨客鱼 回答时间:前天 18:41

xmshao 发表于 2026-3-13 17:25
怎么来回初始化呢。</p>
<p>你初始化后,建个标志. STM32F1系列里常用个备份域寄存器来做标志。

[md]不好意思,刚才搞晕了,这个方法的却是可以知道是不是休眠重启,但是这样休眠重启后RTC数据还是不对啊

憨客鱼 回答时间:前天 18:46

xmshao 发表于 2026-3-13 12:03
我找了下,有的。 不同系列寄存器有点不一样,F1系列在RTC_CRL。</p>
<p>![image.png](data/attachment/forum/ ...

[md]if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!=0X32F2) { HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x32F2); // RTC_CalendarConfig(); MX_RTC_Init(); } else { hrtc.Instance->CRL &=~0x08; while((hrtc.Instance->CRL&0x08)==0x08); hrtc.Instance->CRL |=0x08; }

改成这样 还是不对

xmshao 回答时间:昨天 09:46

憨客鱼 发表于 2026-3-13 18:41
不好意思,刚才搞晕了,这个方法的却是可以知道是不是休眠重启,但是这样休眠重启后RTC数据还是不对 ...

[md]保证VDD和VBAT至少有一个存在的情况下,复位芯片或低功耗唤醒是不会影响RTC工作的。

你先保证正常模式下 RTC正在工作,读取正常。确保LSE工作稳定、代码正常。

然后再验证低功耗,或重启,重启的话必须保证VDD和VBAT至少一个有电~!

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版