STM32G070 RTC 日历溢出导致的问题

STM32设置RTC的代码如下:

RTC_HandleTypeDef hrtc;

/* RTC init function */
void MX_RTC_Init(void)
{

  /* USER CODE BEGIN RTC_Init 0 */

  /* USER CODE END RTC_Init 0 */

  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};

  /* USER CODE BEGIN RTC_Init 1 */

  /* USER CODE END RTC_Init 1 */
  /** 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.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }

  /* USER CODE BEGIN Check_RTC_BKUP */
  uint32_t iSetFlag = 0x5050;
	if(iSetFlag != HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0))
	{
  /* USER CODE END Check_RTC_BKUP */

  /** Initialize RTC and set the Time and Date
  */
  sTime.Hours = 12;
  sTime.Minutes = 30;
  sTime.Seconds = 30;
  sTime.SubSeconds = 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_WEDNESDAY;
  sDate.Month = RTC_MONTH_NOVEMBER;
  sDate.Date = 17;
  sDate.Year = 21;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN RTC_Init 2 */
	//写入标志位,RTC有外部电源供电,该标志位不会改变,上电不会再次初始化时间
  HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,iSetFlag);
	}
  /* USER CODE END RTC_Init 2 */

}

现象

当吧时间设置到极限时间2099-12-31 23:59:59 关机后再次开机,设置的时间为初始值,而且每次开机都是从初始值开始运行。

原因分析

查看代码逻辑

uint32_t iSetFlag = 0x5050;
if(iSetFlag != HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR0))
{
 /*
 ...
 RTC初始化
*/
 HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,iSetFlag);//写入标志位
}

上述代码中向寄存器RTC_BKP_DR0中写入0x5050,当使用了RTC的备用电源,单片机掉电时RTC_BKP_DR0寄存器保存,当再次上电时就不再执行初始化的代码,这就保证了RTC的正确性。
从现象上来说,RTC_BKP_DR0的值再次上电后并不是0x5050。
在这里插入图片描述
从官方手册中可知,在使用了Vbat供电时,TAMP 备份 x 寄存器 (TAMP_BKPxR)不会复位,导致备份寄存器复位的原因可能为两个

  1. 至少有一个内部或者外部入侵标志置1;
  2. 禁止读取保护(RDP)。
    程序中并未进行禁止读取保护的操作,所以重点查找哪里产生了入侵。
    在这里插入图片描述
    两个外部入侵事件和4个内部入侵事件,代码中并没有配置外部入侵引脚,排除外部。
    在这里插入图片描述
    RTC日历溢出会产生一个tamp_itamp5的内部入侵事件源。
    在这里插入图片描述
    在这里插入图片描述
    TAMP control register 1的复位值为0xFFFF 0000,也就是说位20上电默认是1,使能内部入侵5,所以当设置时间99 年 12 月 31 日 23:59:59产生入侵事件,导致了TAMP 备份 x 寄存器 (TAMP_BKPxR)复位,再次上电,RTC会初始化。
    备份寄存器 (TAMP_BKPxR) 在 RTC 域中实现,可在 VDD 电源关闭时通过 VBAT 保持上电状态。
    所以当产生了入侵事件之后,入侵事件在VBAT保持下是记录的,要想去除入侵事件,一个是写寄存器,另一个办法就是扣掉VBAT电池。

实验

设置RTC产生日历溢出事件,再次开机RTC初始化,重新设置时间,再次开机RTC仍初始化;
扣掉VBAT电池,再次开机RTC初始化,重新设置时间,再次开机RTC不再初始化,时间与上次设置一致。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值