1
完善资料让更多小伙伴认识你,还能领取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配置截图。 附件不会上传。 |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1178浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 05:00 , Processed in 1.184148 second(s), Total 50, Slave 41 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号