之前写的这篇文章被人评价说日期不更新,再次用到发现确实如此,再次研究HAL库发现问题,再此解决这个问题。对此感谢这位读者。
如果1秒计数加1,从0开始到溢出预计可以计数到2^32次方约136年。但是HAL库可不是这么来的。如果你从不调用HAL_RTC_GetTime,计数器的值会一直累计,直到溢出再从0开始;HAL_RTC_Init函数中主要进行如下操作:
(1)、等待时钟同步,开始配置模式等,调用HAL_RTC_MspInit 开启备份域时钟并关闭写保护,开启中断并设置中断优先级;
(2)、如果预分频参数不是RTC_AUTO_1_SECOND直接赋值,否则根据时钟设置计算预分频值,我设置的是1秒预分频,就是外部晶振32.768KHZ最后计算式32768-1=37267赋值给预分频器高位和低位:hrtc->Instance->PRLH和hrtc->Instance->PRLL,这样就是1秒计数加1。
(3)、退出配置模式写入RTC寄存器,等待操作关闭。
(4)、初始化hrtc->DateToUpdate为0年1月1日,初始化结束。
/* Initialize date to 1st of January 2000 */
hrtc->DateToUpdate.Year = 0x00U;
hrtc->DateToUpdate.Month = RTC_MONTH_JANUARY;
hrtc->DateToUpdate.Date = 0x01U;
到这时候可以写入备份寄存器,
//第一次初始化写入0X55,下次上电先读取该值 判断是否是重新已经初始化时间否则时间进行默认设
if(HAL_RTCEx_BKUPRead(&hrtc,RTC_BKP_DR1)==0x55)
{ /*因为RTC是根据按照一天24*60*365秒进行计算时间,也就是24小时制
hrtc.DateToUpdate的用于保存日期且初始化为0年1月1日
当调用HAL_RTC_GetTime根据秒数,判断是否超过一天,更新日期保存并在hrtc.DateToUpdate中,
然后计数值会减去一天的秒数,这样就不能通过读计数值算出来过了多少天
当掉电时变量也就丢失了,也就是日期就丢失了只要定时将日期保存在后备区域,
上电后先读取后备区域重新初始化hrtc.DateToUpdate变量,
当调用HAL_RTC_GetTime就可以根据hrtc.DateToUpdate变量更新日期,这样就不会丢失日期了
*/
//已经初始化过因为不调用初始化函数但是变量该赋值的还是要赋值
Date_read_BKP(&hrtc);//读取BKP区域的掉电前的日期,然后根据计数值计算掉电期间过了几天
//32位每秒计数1的话可以计数136年,不用担心溢出
HAL_RTCEx_SetSecond_IT(&hrtc); //开启1秒中断//这个函数CubeMx不会自动生成需要手动调用
HAL_RTC_GetTime(&hrtc,&Home_Time,RTC_FORMAT_BCD);
HAL_RTC_GetDate(&hrtc,&Home_Date,RTC_FORMAT_BCD);
return; //直接退出初始化
}
上一篇文章实现了重新上电后不丢日期,但是如果在断电时,RTC计数跨过23:59:59到00:00:00这个节点,就是到了第二天,或者第n天后,重新上电是不会更新日期的,原因就是HAL内的
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
实际是调用的
因篇幅问题不能全部显示,请点此查看更多更全内容