STM32學習-RTC實時時鐘
—————————————————————————————————————————————————————————
無論是誰,你的一天也只有二十四小時。
你可以玩,可以睡大覺,可以去學習,也可以去探索那片從未到達的那片海。
時間不會為任何人停留,你可以選擇原地踏步,當然你也可以選擇勇攀高峰。
—————————————————————————————————————————————————————————————
RTC(Real Time Clock)實時時鐘
RTC是個獨立的定時器。RTC擁有一個連續計數的計數器,在相應軟體的配置下,可以提供時鐘日曆的功能。修改計數器的值可以重新設定當前的時間和日曆。
RTC模組和時鐘配置系統(RCC_BDCR暫存器)是在後備區域,即系統復位或者從待機模式喚醒後RTC的設定和時間的維持不變,但是在系統復位後,會自動禁止訪問後備暫存器和RTC。防止對後備區(BKP)的意外寫操作。(讀RTC暫存器有解釋)所以在設定時間之前,先要取消後備域的(BKP)防寫。
BKP備份暫存器
①備份暫存器是42個16位的暫存器,可用來儲存84個位元組的資料
②它們在備份區域,當VDD電源切斷,仍然由V(BAT)鈕釦電池維持供電
③當系統在待機模式下被喚醒,或者系統復位或者電源復位,它們也不會復位。
④執行以下的操作將使能對後備區域的訪問
設定暫存器RCC_APB1ENR的PWREN和BKPEN位,使能電源和後備時鐘
設定暫存器PWB_CR的DBP位,使能對RTC和後備暫存器的訪問。
RTC框圖
RTC 由兩個主要部分組成 ,第一部分(APB1 介面)用來和 APB1 匯流排相連。此單元還包含一組 16 位暫存器,可通過 APB1 匯流排對其進行讀寫操作。APB1 介面由 APB1 匯流排時鐘驅動,用來與 APB1 匯流排連線。
另一部分(RTC 核心)由一組可程式設計計數器組成,分成兩個主要模組。第一個模組是 RTC 的預分頻模組,它可程式設計產生 1 秒的 RTC 時間基準 TR_CLK。RTC 的預分頻模組包含了一個 20位的可程式設計分頻器(RTC 預分頻器)。如果在 RTC_CR 暫存器中設定了相應的允許位,則在每個TR_CLK 週期中 RTC 產生一箇中斷(秒中斷)。第二個模組是一個 32 位的可程式設計計數器,可被初始化為當前的系統時間,一個 32 位的時鐘計數器,按秒鐘計算,可以記錄 4294967296 秒,約合 136 年左右,作為一般應用,這已經是足夠了的。
RTC 還有一個鬧鐘暫存器 RTC_ALR,用於產生鬧鐘。系統時間按 TR_CLK 週期累加並與儲存在 RTC_ALR 暫存器中的可程式設計時間相比較,如果 RTC_CR 控制暫存器中設定了相應允許位,比較匹配時將產生一個鬧鐘中斷。
自己理解:RTC有三個時鐘源,一般我們選擇外部的LSE,經過RTC_PRL預分頻之後產生TR_CLK時鐘,在TR_CLK時鐘的作用下,RTC_CNT計數器(32位)每個週期加1操作。永不停息的操作,RTC_ALR是鬧鐘比較暫存器,當RTC_ALR和RTC_CNT相等的時候才生鬧鐘中斷,同時還有秒中斷。溢位中斷。
RTC相關暫存器
①RTC控制暫存器 (RTC_CRH, RTC_CRL)
②RTC預分頻裝載暫存器 (RTC_PRLH, RTC_PRLL)
③RTC預分頻餘數暫存器 (RTC_DIVH, RTC_DIVL)
④RTC計數器暫存器 (RTC_CNTH, RTC_CNTL)
⑤RTC鬧鐘暫存器 (RTC_ALRH,RTC_ALRL)
配置RTC暫存器過程
第一 查詢RTOFF位,直到RTOFF的值變為“1”
第二 置CNF為1,進入配置模式
第三 對RTC暫存器進行操作
第四 清除CNF標誌位,退出配置模式
第五 查詢RTOF,直到RTOFF位變為“1”,以確認寫操作已經完成
當且CNF的標誌位被清除時,寫操作才能進行,這個過程至少需要 三個RTCLK週期
RTC的配置過程
①使能PWR和BKP時鐘:RCC_APB1PeriphClockCmd();② 使能後備暫存器訪問: PWR_BackupAccessCmd();
③ 配置RTC時鐘源,使能RTC時鐘:
RCC_RTCCLKConfig();
RCC_RTCCLKCmd();
如果使用LSE,要開啟LSE:RCC_LSEConfig(RCC_LSE_ON);
④設定RTC預分頻係數:RTC_SetPrescaler();
⑤ 設定時間:RTC_SetCounter();
⑥開啟相關中斷(如果需要):RTC_ITConfig();
⑦編寫中斷服務函式:RTC_IRQHandler();
⑧部分操作要等待寫操作完成和同步。
RTC_WaitForLastTask();//等待最近一次對RTC暫存器的寫操作完成
RTC_WaitForSynchro(); //等待RTC暫存器同步