久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

標題: 6月ST專欄(4)-STM32Cube_FW_F4中RTC_Calendar例程的BUG [打印本頁]

作者: 小融1號    時間: 2017-1-16 15:56
標題: 6月ST專欄(4)-STM32Cube_FW_F4中RTC_Calendar例程的BUG

前言
實時時鐘(RTC)是一個獨立的 BCD 定時器/計數器,用來提供準確的日歷和時間信息。準確性是其重要的指標。
   
問題
某客戶在其產品的設計中,使用了 STM32F429IIT6。客戶在使用過程發現一個問題,雖然已經有使用電池對 VBAT 進行供電, 但是在經常頻繁的 VDD 上下電之后,發現時鐘會比準確的時間慢幾秒鐘。
  
融創芯城PCB\PCBA自動報價系統上線啦,各位做電子產品的朋友,歡迎訪問比價、訂購
調研

1.了解問題
向客戶了解其使用的固件庫,得知他的程序是參考 STM32Cube_FW_F4_V1.3.0\Projects\STM324x9I_EVAL\Examples\RTC 中的 RTC_Calendar 例程。于是找來 STM32439I-EVAL2 來進行驗證,測試發現,STM32Cube_FW_F4_V1.3.0\Projects\STM324x9I_EVAL\Examples\RTC   中的 RTC_Calendar   例程確實存在頻繁上下電會導致時間變慢的情況;而對標準外設庫 STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Project\STM32F4xx_StdPeriph_Examples\RTC   中的RTC_Calendar   例程進行測試,則不存在此問題。所以,懷疑  STM32Cube_FW_F4_V1.3.0\Projects\STM324x9I_EVAL\Examples\RTC   中的 RTC_Calendar 例程存在 Bug。
2.問題分析
仔細閱讀
STM32Cube_FW_F4_V1.3.0\Projects\STM324x9I_EVAL\Examples\RTC 中的 RTC_Calendar 例程,分析一下 main.c 主程序,
“if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)”是用來判斷 RTC 是否是已經被配 置過的,所以懷疑的重點可放在這之前的“if(HAL_RTC_Init(&RtcHandle) != HAL_OK)”中的 HAL_RTC_Init()函數。
  
進入位于 stm32f4xx_hal_rtc.c 中的 HAL_RTC_Init()函數,再進入其調用的位于 stm32f4xx_hal_msp.c 中的
HAL_RTC_MspInit()函數,在這個函數中,可以看到以下代碼:
/*##-1- Configue LSE as RTC clock soucre ###################################*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI | RCC_OSCILLATORTYPE_LSE;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSEState = RCC_LSE_ON;
RCC_OscInitStruct.LSIState = RCC_LSI_OFF;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
if(HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}

這段代碼中由于選中了 LSE,在其所調用的 HAL_RCC_OscConfig()中對 LSE 進行了重新配置。在 stm32f4xx_hal_rcc.c 中找到 HAL_RCC_OscConfig()函數,發現其對 LSE 重新配置的時候,對 LSE 進行關閉,然后再配置。
  
到此,回來再看 main.c,由于
“if(HAL_RTC_Init(&RtcHandle) != HAL_OK)”位于 “if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)”之前,從程序流程來看,每次 VDD 上電,都會進 行一次  HAL_RTC_Init(),也就是說,每次上電都會有一個關閉  LSE   再打開的動作,這個動作多了,時間變慢的現象就變得很 明顯了。
3.問題解決
問題原因很明顯了,那么解決辦法也很簡單,只需要將 HAL_RTC_Init()這個初始化函數挪到判斷 RTC   是否是已經被配置過的 if…else…語句里邊就行了。如果是RTC   已經被配置過的,就不需要再重新初始化一次了。如下:
/*##-1- Configure the RTC peripheral #######################################*/
RtcHandle.Instance = RTC;
/*##-2- Check if Data stored in BackUp register0: No Need to reconfigure RTC#*/
/* Read the BackUp Register 0 Data */
if(HAL_RTCEx_BKUPRead(&RtcHandle, RTC_BKP_DR0) != 0x32F2)
{
/* Configure RTC prescaler and RTC data registers */
/* RTC configured as follow:
- Hour Format = Format 24
- Asynch Prediv = Value according to source clock
- Synch Prediv = Value according to source clock
- OutPut = Output Disable
- OutPutPolarity = High Polarity
- OutPutType = Open Drain */
RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24;
RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV;
RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV;
RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE;
RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
if(HAL_RTC_Init(&RtcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}

/* Configure RTC Calendar */
RTC_CalendarConfig();
}
else
{
/* Check if the Power On Reset flag is set */
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PORRST) != RESET)
{
/* Power on reset occured: Turn LED2 on */
BSP_LED_On(LED2);
}
/* Check if Pin Reset flag is set */
if(__HAL_RCC_GET_FLAG(RCC_FLAG_PINRST) != RESET)
{
/* External reset occured: Turn LED4 on */
BSP_LED_On(LED4);
}
/* Enable the PWR clock */
__PWR_CLK_ENABLE();
/* Allow access to RTC */
HAL_PWR_EnableBkUpAccess();
/* Wait for RTC APB registers synchronisation */
if(HAL_RTC_WaitForSynchro(&RtcHandle) != HAL_OK)
{
/* synchronisation Error */
Error_Handler();
}
/* Clear the RTC Alarm Flag */
__HAL_RTC_ALARM_CLEAR_FLAG(&RtcHandle,RTC_FLAG_ALRAF);
/* Clear the EXTI Line 17 Pending bit (Connected internally to RTC Alarm) */
__HAL_RTC_EXTI_CLEAR_FLAG(RTC_EXTI_LINE_ALARM_EVENT);
/* Clear Reset Flag */
__HAL_RCC_CLEAR_RESET_FLAGS();
}
結論
由于
STM32Cube_FW_F4_V1.3.0\Projects\STM324x9I_EVAL\Examples\RTC 中的 RTC_Calendar 例程沒有注意到HAL_RTC_Init()函數里邊會有關閉 LSE   的動作,而每次上電都會運行這個函數,每次上電都會導致時間變慢,上電的次數多了,變慢就很明顯了。所以,例程上是有 Bug 的,需要進行修復。

  

處理
需要將  HAL_RTC_Init()這個初始化函數的位置做個修改。如果 RTC  未被配置過,則進行配置;如果是已經被配置過的,就不需要再重新初始化一次了。標準外設庫 STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\Project\STM32F4xx_StdPeriph_Examples\RTC   中的 RTC_Calendar   例程是沒有問題的,參考此例程,修改得一基于 STM32Cube_FW_F4 的 RTC_Calendar 例程,見附件。
建議
上電時對 LSE 進行重新初始化可能會導致 RTC 計時不準確,所以在實際應用過程中應該對此注意一下。


文章來源:微信公眾號   融創芯城(一站式電子元器件、PCB、PCBA購買服務平臺,項目眾包平臺,方案共享平臺)






歡迎光臨 (http://www.zg4o1577.cn/bbs/) Powered by Discuz! X3.1
主站蜘蛛池模板: 奇米超碰在线 | 欧美v免费 | 国产精品一区一区 | 在线免费激情视频 | 亚洲精品久久久9婷婷中文字幕 | 成人免费观看视频 | 国产亚洲精品一区二区三区 | 亚洲成人毛片 | 天堂视频一区 | 日日干日日色 | 久久99一区二区 | 91久久综合 | 午夜欧美a级理论片915影院 | 日日干夜夜操 | 亚洲精品久久久久久久久久久久久 | 国产精品一区二区电影 | 激情欧美日韩一区二区 | 天天av综合 | 亚洲天堂一区二区 | 狠狠伊人 | 九九99精品 | 草草视频在线观看 | 狠狠入ady亚洲精品经典电影 | 久久免费看 | 亚洲专区在线 | 蜜桃精品噜噜噜成人av | 日韩午夜影院 | 午夜久久久 | 国产精品成人在线 | 国产成人av在线播放 | av手机免费在线观看 | 久久久久国产精品一区二区 | 精品国产一二三区 | 鲁视频| 免费一级片 | 亚洲精品久久久久久一区二区 | 337p日本欧洲亚洲大胆鲁鲁 | 久久精品国产精品青草 | 成人一区二区三区在线 | 99精品电影 | 成人免费精品视频 |