修改了stm32f1xx_hal_rtc.c文件中的三个函数,将年月日信息保存到RTC备份区中。
RTC_DateUpdate( );
HAL_RTC_GetDate( );
HAL_RTC_SetDate();
具体代码如下:
static void RTC_DateUpdate(RTC_HandleTypeDef* hrtc, uint32_t DayElapsed)
{
uint32_t year = 0, month = 0, day = 0;
uint32_t loop = 0;
/* Get the current year*/
//year = hrtc->DateToUpdate.Year;
/* Get the current month and day */
//month = hrtc->DateToUpdate.Month;
//day = hrtc->DateToUpdate.Date;
/************************** *************************************/
//从备份寄存器读年月日!!!
year= HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR2);//cg
month= HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR3);//cg
day= HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR4);//cg
/************************** *************************************/
for (loop = 0; loop < DayElapsed; loop++)
{
if((month == 1) || (month == 3) || (month == 5) || (month == 7) || \
(month == 8) || (month == 10) || (month == 12))
{
if(day < 31)
{
day++;
}
/* Date structure member: day = 31 */
else
{
if(month != 12)
{
month++;
day = 1;
}
/* Date structure member: day = 31 & month =12 */
else
{
month = 1;
day = 1;
year++;
}
}
}
else if((month == 4) || (month == 6) || (month == 9) || (month == 11))
{
if(day < 30)
{
day++;
}
/* Date structure member: day = 30 */
else
{
month++;
day = 1;
}
}
else if(month == 2)
{
if(day < 28)
{
day++;
}
else if(day == 28)
{
/* Leap year */
if(RTC_IsLeapYear(year))
{
day++;
}
else
{
month++;
day = 1;
}
}
else if(day == 29)
{
month++;
day = 1;
}
}
}
/* Update year */
hrtc->DateToUpdate.Year = year;
/* Update day and month */
hrtc->DateToUpdate.Month = month;
hrtc->DateToUpdate.Date = day;
/* Update day of the week */
hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(year, month, day);
/************************** *************************************/
//将年月日保存到备份寄存器,否则断电会丢失!!!
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR2, year);
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR3, month);
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR4, day);
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR5, hrtc->DateToUpdate.WeekDay);
/*************************************************************/
}
HAL_StatusTypeDef HAL_RTC_GetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
{
RTC_TimeTypeDef stime = {0};
/* Check input parameters */
if((hrtc == NULL) || (sDate == NULL))
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RTC_FORMAT(Format));
/* Call HAL_RTC_GetTime function to update date if counter higher than 24 hours */
if (HAL_RTC_GetTime(hrtc, &stime, RTC_FORMAT_BIN) != HAL_OK)
{
return HAL_ERROR;
}
/* Fill the structure fields with the read parameters */
//屏蔽下面得到年月日
//sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
//sDate->Year = hrtc->DateToUpdate.Year;
//sDate->Month = hrtc->DateToUpdate.Month;
//sDate->Date = hrtc->DateToUpdate.Date;
/************************** *************************************/
//从备份寄存提取年月日,否则断电会丢失!!!
sDate->Year = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR2);
sDate->Month = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR3);
sDate->Date = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR4);
sDate->WeekDay = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_DR5);
/************************** *************************************/
HAL_StatusTypeDef HAL_RTC_SetDate(RTC_HandleTypeDef *hrtc, RTC_DateTypeDef *sDate, uint32_t Format)
{
uint32_t counter_time = 0U, counter_alarm = 0U, hours = 0U;
/* Check input parameters */
if ((hrtc == NULL) || (sDate == NULL))
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RTC_FORMAT(Format));
/* Process Locked */
__HAL_LOCK(hrtc);
hrtc->State = HAL_RTC_STATE_BUSY;
if (Format == RTC_FORMAT_BIN)
{
assert_param(IS_RTC_YEAR(sDate->Year));
assert_param(IS_RTC_MONTH(sDate->Month));
assert_param(IS_RTC_DATE(sDate->Date));
/* Change the current date */
hrtc->DateToUpdate.Year = sDate->Year;
hrtc->DateToUpdate.Month = sDate->Month;
hrtc->DateToUpdate.Date = sDate->Date;
}
else
{
assert_param(IS_RTC_YEAR(RTC_Bcd2ToByte(sDate->Year)));
assert_param(IS_RTC_MONTH(RTC_Bcd2ToByte(sDate->Month)));
assert_param(IS_RTC_DATE(RTC_Bcd2ToByte(sDate->Date)));
/* Change the current date */
hrtc->DateToUpdate.Year = RTC_Bcd2ToByte(sDate->Year);
hrtc->DateToUpdate.Month = RTC_Bcd2ToByte(sDate->Month);
hrtc->DateToUpdate.Date = RTC_Bcd2ToByte(sDate->Date);
}
/* WeekDay set by user can be ignored because automatically calculated */
hrtc->DateToUpdate.WeekDay = RTC_WeekDayNum(hrtc->DateToUpdate.Year, hrtc->DateToUpdate.Month, hrtc->DateToUpdate.Date);
sDate->WeekDay = hrtc->DateToUpdate.WeekDay;
//将年月日保存到备份寄存器,否则断电会丢失!!!
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR2, hrtc->DateToUpdate.Year);//hkh
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR3, hrtc->DateToUpdate.Month);//hkh
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR4, hrtc->DateToUpdate.Date);//hkh
HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_DR5, hrtc->DateToUpdate.WeekDay);//hkh
/* Reset time to be aligned on the same day */
/* Read the time counter*/
counter_time = RTC_ReadTimeCounter(hrtc);
/* Fill the structure fields with the read parameters */
hours = counter_time / 3600U;
if (hours > 24U)
{
/* Set updated time in decreasing counter by number of days elapsed */
counter_time -= ((hours / 24U) * 24U * 3600U);
/* Write time counter in RTC registers */
if (RTC_WriteTimeCounter(hrtc, counter_time) != HAL_OK)
{
/* Set RTC state */
hrtc->State = HAL_RTC_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_ERROR;
}
/* Read current Alarm counter in RTC registers */
counter_alarm = RTC_ReadAlarmCounter(hrtc);
/* Set again alarm to match with new time if enabled */
if (counter_alarm != RTC_ALARM_RESETVALUE)
{
if (counter_alarm < counter_time)
{
/* Add 1 day to alarm counter*/
counter_alarm += (uint32_t)(24U * 3600U);
/* Write new Alarm counter in RTC registers */
if (RTC_WriteAlarmCounter(hrtc, counter_alarm) != HAL_OK)
{
/* Set RTC state */
hrtc->State = HAL_RTC_STATE_ERROR;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_ERROR;
}
}
}
}
hrtc->State = HAL_RTC_STATE_READY ;
/* Process Unlocked */
__HAL_UNLOCK(hrtc);
return HAL_OK;
}