项目场景:
上传至服务器的数据里面带有时间戳,通过后台发现RTC的时间一直为一个时间,通过读取HAL库的源码后,修复了该问题。
问题描述:
调用STM32 HAL库中的RTC日期、时间获取函数,发现时间一直为同一个时间。
/******************************************************************************* ** 函数原型:RTC_TimeTypeDef RTC_Time_Get(void) ** 函数功能:获取前RTC时间 ** 输入参数:无 ** 输出参数:时间 ** 备 注: *******************************************************************************/ RTC_TimeTypeDef RTC_Time_Get(void) { RTC_TimeTypeDef stimestructureget; HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN); return stimestructureget; }
/******************************************************************************* ** 函数原型:RTC_DateTypeDef RTC_Date_Get(void) ** 函数功能:获取前RTC日期 ** 输入参数:无 ** 输出参数:日期 ** 备 注: *******************************************************************************/ RTC_DateTypeDef RTC_Date_Get(void) { RTC_DateTypeDef sdatestructureget; HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN); return sdatestructureget; } //主函数读取 void main(void) { uint8_t buff[10]; buff[0] = RTC_Date_Get().Month; //当前时间 buff[1] = RTC_Date_Get().Date; buff[2] = RTC_Time_Get().Hours; buff[3] = RTC_Time_Get().Minutes; buff[4] = RTC_Time_Get().Seconds; }
原因分析:
通过阅读HAL库的 RTC源码,发现HAL_RTC_GetTime()的解释:
/**
* @brief Get RTC current time.
* @note You can use SubSeconds and SecondFraction (sTime structure fields returned) to convert SubSeconds
* value in second fraction ratio with time unit following generic formula:
* Second fraction ratio * time_unit= [(SecondFraction-SubSeconds)/(SecondFraction+1)] * time_unit
* This conversion can be performed only if no shift operation is pending (ie. SHFP=0) when PREDIV_S >= SS
* @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.
* @param hrtc RTC handle
* @param sTime Pointer to Time structure with Hours, Minutes and Seconds fields returned
* with input format (BIN or BCD), also SubSeconds field returning the
* RTC_SSR register content and SecondFraction field the Synchronous pre-scaler
* factor to be used for second fraction ratio computation.
* @param Format Specifies the format of the entered parameters.
* This parameter can be one of the following values:
* @arg RTC_FORMAT_BIN: Binary data format
* @arg RTC_FORMAT_BCD: BCD data format
* @retval HAL status
*/
即必须在HAL_RTC_GetTime()之后调用HAL_RTC_GetDate()来解锁高阶日历阴影寄存器中的值,以确保时间和日期值之间的一致性,否则会被上锁。这和我们平常读日期的顺序不一样,先读年月日,在读时间,STM32则相反,先读时间,在读日期。
解决方案:
先调用读时间函数,再调用读日期函数,即可解决问题。
void main(void)
{
uint8_t buff[10];
buff[2] = RTC_Time_Get().Hours;
buff[3] = RTC_Time_Get().Minutes;
buff[4] = RTC_Time_Get().Seconds;
buff[0] = RTC_Date_Get().Month; //当前时间
buff[1] = RTC_Date_Get().Date;
}