Stm32 CubeIDE对RTC的日期、时间读写,后备存储的读写,一折腾又是好多的问题,现在梳理一下,后面的不要过多踩坑了。
用STM32CubeIDE生成代码
这里有时间和日期的设置,在代码中也会生成相应的代码,首次设置后必须注释掉,否者每次开机都是相同的时间和日期。
在rtc.c文件中注释掉下面代码:
/** Initialize RTC and set the Time and Date
*/
// sTime.Hours = 0x0;
// sTime.Minutes = 0x0;
// sTime.Seconds = 0x0;
// sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
// sTime.StoreOperation = RTC_STOREOPERATION_RESET;
// if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
// {
// Error_Handler();
// }
// sDate.WeekDay = RTC_WEEKDAY_FRIDAY;
// sDate.Month = RTC_MONTH_DECEMBER;
// sDate.Date = 0x1;
// sDate.Year = 0x23;
//
// if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
// {
// Error_Handler();
// }
设置时间日期的代码:
RTC_TimeTypeDef sTime_now = {0};
RTC_DateTypeDef Date;
Date.Year = 23;
Date.Month = 12;
Date.Date = 4;
Date.WeekDay = 1;
HAL_RTC_SetDate(&hrtc, &Date, RTC_FORMAT_BIN);
sTime_now.Hours = 14;
sTime_now.Minutes = 00;
sTime_now.Seconds = 0;
HAL_RTC_SetTime(&hrtc, &sTime_now, RTC_FORMAT_BIN);
RTC_FORMAT_BIN 是表示二进制模式 不是RTC_FORMAT_BCD模式
RTC_FORMAT_BCD模式是指16进制的高位当10进制使用,也就是说12分钟,在RTC_FORMAT_BCD中是0x12,在RTC_FORMAT_BIN 中是0x0C。
时间日期的读取:
RTC_DateTypeDef Date;
RTC_TimeTypeDef Time;
HAL_RTC_GetTime(&hrtc, &Time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &Date, RTC_FORMAT_BIN);
printf("%02d-%02d-%02d\r\n",Date.Year, Date.Month, Date.Date); // Date.WeekDay表示日期
printf("%02d:%02d:%02d\r\n", Time.Hours, Time.Minutes, Time.Seconds);
以上代码有个事项要一定注意,就是必须把HAL_RTC_GetTime(&hrtc, &Time, RTC_FORMAT_BIN);放在前面,我一开始就是不注意,把读取日期放在前面,读取时间放在了后面,导致读取时间读不到最新的时间的问题,只要你注意看,英文有解释的:
@note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the
values in the higher-order calendar shadow registers to ensure
consistency between the time and date values.
Reading RTC current time locks the values in calendar shadow registers
until current date is read to ensure consistency between the time and
date values.
这么一个小细节又是折腾好久啊。
本来以为这样就搞定了,又出现问题,就是在复位的瞬间时间是不走时的,问题出现在初始化这里,再修改一下啊:
RTC_HandleTypeDef hrtc;
/* RTC init function */
void MX_RTC_Init(void)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
hrtc.Instance = RTC; //必须放在if外面
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR19) != 0x55AA1234)
{
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR19, 0x55AA1234);
}
}
以上代码也说明了后备数据的读写:
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR19, 0x55AA1234); //写后备数据
其中RTC_BKP_DR19可以取值的范围是RTC_BKP_DR0~RTC_BKP_DR19一共20个4位的字节,共80字节。
读取是
HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR19);