1. 程式人生 > >STM32 HAL庫RTC模組列印時間不準的問題

STM32 HAL庫RTC模組列印時間不準的問題

正點原子 STM32F7阿波羅開發板,CubeMx生成工程,使用HAL庫的RTC模組時,發現了列印時間不準的問題,現記錄查證過程。

1、CubeMx的配置反覆查證過,沒有問題。 

2、main函式中加入測試程式碼如下:

    RTC_DateTypeDef stRtcDate;     RTC_TimeTypeDef stRtcTime; if  ( (HAL_OK == HAL_RTC_GetDate(&hrtc, &stRtcDate, RTC_FORMAT_BIN)) && (HAL_OK == HAL_RTC_GetTime(&hrtc, &stRtcTime, RTC_FORMAT_BIN)) ) {      printf("%d-%d-%d_%d:%d:%d.%d",           stRtcDate.Year,  stRtcDate.Month,   stRtcDate.Date,           stRtcTime.Hours, stRtcTime.Minutes, stRtcTime.Seconds, stRtcTime.SubSeconds); }

迴圈執行結果為:

[14:26:18.128]收←◆18-10-22_20:10:10.66

[14:26:19.532]收←◆18-10-22_20:10:10.219

[14:26:20.935]收←◆18-10-22_20:10:10.115

[14:26:22.340]收←◆18-10-22_20:10:10.12

[14:26:23.742]收←◆18-10-22_20:10:10.165

也就是說,定時不準確,大概1秒列印一遍,但列印的時間秒一直不變!

3、經過反覆查證,發現HAL_RTC_GetTime介面的一些注意事項:

/**   * @brief  Gets RTC current time.   * @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   * @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.   * @retval HAL status   */ HAL_StatusTypeDef HAL_RTC_GetTime(RTC_HandleTypeDef *hrtc, RTC_TimeTypeDef *sTime, uint32_t Format);

注意最後的note中,“You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values”,也就是說, HAL_RTC_GetTime介面呼叫必須在HAL_RTC_GetDate介面之前!

4、驗證:將程式碼改為:

    RTC_DateTypeDef stRtcDate;     RTC_TimeTypeDef stRtcTime; if  (  (HAL_OK == HAL_RTC_GetTime(&hrtc, &stRtcTime, RTC_FORMAT_BIN))  && (HAL_OK == HAL_RTC_GetDate(&hrtc, &stRtcDate, RTC_FORMAT_BIN)) ) {      printf("%d-%d-%d_%d:%d:%d.%d",           stRtcDate.Year,  stRtcDate.Month,   stRtcDate.Date,           stRtcTime.Hours, stRtcTime.Minutes, stRtcTime.Seconds, stRtcTime.SubSeconds); }

結果如下:

[14:33:26.200]收←◆18-10-22_20:10:9.16

[14:33:27.602]收←◆18-10-22_20:10:11.169

[14:33:29.006]收←◆18-10-22_20:10:12.65

[14:33:30.409]收←◆18-10-22_20:10:14.218

[14:33:31.812]收←◆18-10-22_20:10:15.115

 可見結果正常,如果深入分析兩個介面定義,先讀時間,會鎖存當前時間及日期,再讀出日期,能夠保證日期時間的一致性;若介面呼叫順序反了,則在下次讀時間的時候,會立即再次鎖存時間,因此變化很小。

因此,需要注意呼叫順序。