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);