完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
用CUBEMX生成STM32F103xx RTC时钟例程,系统掉电后日期参数会重置,时间参数正常运行,前提是加了电池供电。
直接上解决方案。 大体思路就是在第一次配置日期时间的时候把日期值加入后备区域寄存器保存起来,我用的是103RBT6,所以后备区域寄存器只有 10个,这里要注意一下。断电或复位以后 if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051)这条语句不成立,所以从else处执行,先把保存在后备区域寄存器的日期值 提取出来,再更新到设置日期这个函数里,此函数HAL_RTC_SetDate(),由于掉电或复位后,有电池在供电,所以实时时钟计数器是一直在更新的,HAL_RTC_SetDate()函数会根据计数器的值对日期做校准。开启了秒中断,所以在中断回调函数里再把日期值写入到后备寄存器中,实时 更新。 以下是修改后的CUBE生成的RTC初始化源码和中断回调函数。 定义的全局变量。 RTC_TimeTypeDef time; //时间结构体参数 RTC_DateTypeDef datebuff; //日期结构体参数 static void MX_RTC_Init(void) { /* USER CODE BEGIN RTC_Init 0 */ /* USER CODE END RTC_Init 0 */ RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef DateToUpdate = {0}; /* USER CODE BEGIN RTC_Init 1 */ __HAL_RCC_BKP_CLK_ENABLE(); //开启后备区域时钟 __HAL_RCC_PWR_CLK_ENABLE(); //开启电源时钟 /* USER CODE END RTC_Init 1 */ /**Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN Check_RTC_BKUP */ if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)!= 0x5051) { /* USER CODE END Check_RTC_BKUP */ /**Initialize RTC and set the Time and Date */ sTime.Hours = 0x23; sTime.Minutes = 0x59; sTime.Seconds = 0x50; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } DateToUpdate.WeekDay = RTC_WEEKDAY_MONDAY; DateToUpdate.Month = RTC_MONTH_DECEMBER; DateToUpdate.Date = 0x31; DateToUpdate.Year = 0x18; if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN RTC_Init 2 */ printf("%drn",DateToUpdate.Month); __HAL_RTC_SECOND_ENABLE_IT(&hrtc,RTC_IT_SEC); //开启RTC时钟秒中断 datebuff = DateToUpdate; //把日期数据拷贝到自己定义的data中 HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, 0x5051);//向指定的后备区域寄存器写入数据 HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (uint16_t)datebuff.Year); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (uint16_t)datebuff.Month); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, (uint16_t)datebuff.Date); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, (uint16_t)datebuff.WeekDay); printf("%d %d %d %d rn",datebuff.Year,datebuff.Month,datebuff.Date,datebuff.WeekDay); } else { datebuff.Year = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2); datebuff.Month = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3); datebuff.Date = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR4); datebuff.WeekDay = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR5); DateToUpdate = datebuff; if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BIN) != HAL_OK) { Error_Handler(); } __HAL_RTC_SECOND_ENABLE_IT(&hrtc,RTC_IT_SEC); //开启RTC时钟秒中断 } getRealTime(); /* USER CODE END RTC_Init 2 */ } void getRealTime(void) { HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &datebuff, RTC_FORMAT_BIN); printf("中断%d %d %d %d rn",datebuff.Year,datebuff.Month,datebuff.Date,datebuff.WeekDay); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, (uint16_t)datebuff.Year); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, (uint16_t)datebuff.Month); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR4, (uint16_t)datebuff.Date); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR5, (uint16_t)datebuff.WeekDay); printf("%d-%d-%d-%d-",datebuff.Year,datebuff.Month,datebuff.Date,datebuff.WeekDay); printf("%d:%d:%drn",time.Hours,time.Minutes,time.Seconds); } void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc) { if(hrtc->Instance == RTC) { getRealTime(); } } 有问题或者测试有错误的朋友可以在评论区留言,一起讨论共同进步。 这是CUBE配置截图。 附件不会上传。 |
|
|
|
只有小组成员才能发言,加入小组>>
3310 浏览 9 评论
2991 浏览 16 评论
3492 浏览 1 评论
9057 浏览 16 评论
4086 浏览 18 评论
1175浏览 3评论
603浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
596浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2333浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1894浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 16:03 , Processed in 1.204817 second(s), Total 79, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号