1 RTC 簡介
RTC—real time clock,實時時鍾,主要包含日歷、鬧鍾和自動喚醒這三部分的功能,其中的日歷功能我們使用的最多。日歷包含兩個 32bit 的時間寄存器,可直接輸出時分秒,星期、月、日、年。比起 F103 系列的 RTC只能輸出秒中斷,剩下的其他時間需要軟件來實現,429 的 RTC可謂是脫胎換骨,讓我們在軟件編程時大大降低了難度。
2 RTC 功能框圖解析
1. 時鍾源
RTC 時鍾源 —RTCCLK 可以從 LSE、LSI和 HSE_RTC 這三者中得到。其中使用最多的是 LSE,LSE 由一個外部的 32.768KHZ(6PF 負載)的晶振提供,精度高,穩定,RTC首選。LSI是芯片內部的 30KHZ晶體,精度較低,會有溫漂,一般不建議使用。HSE_RTC由 HSE 分頻得到,最高是 4M,使用的也較少。
2. 預分頻器
預分頻器 PRER 由 7 位的異步預分頻器 APRE 和 15位的同步預分頻器 SPRE組成。異步預分頻器時鍾 CK_APRE 用於為二進制 RTC_SSR 亞秒遞減計數器提供時鍾,同步預分頻器時鍾 CK_SPRE 用於更新日歷。異步預分頻器時鍾 f CK_APRE =f RTC_CLK /(PREDIV_A+1),同步預分頻器時鍾 f CK_SPRE =f RTC_CLK /(PREDIV_S+1),)。使用兩個預分頻器時,推薦將異步預分頻器配置為較高的值,以最大程度降低功耗。一般我們會使用 LSE 生成 1HZ的同步預分頻器時鍾通常的情況下,我們會選擇 LSE 作為 RTC 的時鍾源,即 f RTCCLK =f LSE =32.768KHZ。然后經過預分頻器 PRER 分頻生成 1HZ 的時鍾用於更新日歷。使用兩個預分頻器分頻的時候,為了最大程度的降低功耗,我們一般把同步預分頻器設置成較大的值,為了生成 1HZ 的同步預分頻器時鍾 CK_SPRE,最常用的配置是 PREDIV_A=127,PREDIV_S=255。計算公式為 : f CK_SPRE =f RTCCLK /{ ( PREDIV_A+1 ) * ( PREDIV_S+1 ) }= 32.768/{ ( 127+1 ) *(255+1)}=1HZ。
3. 實時時鍾和日歷
我們知道,實時時鍾一般是這樣表示的:時/分/秒/亞秒,其中時分秒可直接從 RTC 時間寄存器 (RTC_TR)中讀取。
亞秒由 RTC 亞秒寄存器 (RTC_SSR)的值計算得到,公式為:亞秒值 = ( PREDIV_S –SS[15:0] ) / ( PREDIV_S + 1 ) ,SS[15:0]是同步預分頻器計數器的值,PREDIV_S是同步預
分頻器的值。
日期包含的年月日可直接從 RTC 日期寄存器 (RTC_DR)中讀取。
當應用程序讀取日歷寄存器時,默認是讀取影子寄存器的內容,每隔兩個 RTCCLK 周期,便將當前日歷值復制到影子寄存器。我們也可以通過將 RTC_CR 寄存器的 BYPSHAD控制位置 1 來直接訪問日歷寄存器,這樣可避免等待同步的持續時間。
RTC_CLK 經過預分頻器后,有一個 512HZ 的 CK_APRE 和 1 個 1HZ 的 CK_SPRE,這兩個時鍾可以成為校准的時鍾輸出 RTC_CALIB,RTC_CALIB 最終要輸出則需映射到RTC_AF1 引腳,即 PC13輸出,用來對外部提供時鍾。
4. 鬧鍾
RTC有兩個鬧鍾,鬧鍾 A和鬧鍾 B,,當 RTC 運行的時間跟預設的鬧鍾時間相同的時候,相應的標志位 ALRAF(在 RTC_ISR 寄存器中)和 ALRBF會置 1。利用這個鬧鍾我們可以做一些備忘提醒功能。
如果使能了鬧鍾輸出(由 RTC_CR 的 OSEL[0:1]位控制),則 ALRAF和 ALRBF會連接到鬧鍾輸出引腳 RTC_ALARM,RTC_ALARM最終連接到 RTC的外部引腳 RTC_AF1(即 PC13),輸出的極性由 RTC_CR 寄存器的 POL 位配置,可以是高電平或者低電平。
5. 時間戳
時間戳即時間點的意思,就是某一個時刻的時間。時間戳復用功能 (RTC_TS) 可映射到 RTC_AF1 或 RTC_AF2,當發生外部的入侵事件時,即發生時間戳事件時, RTC_ISR寄存器中的時間戳標志位 (TSF) 將置 1,日歷會保存到時間戳寄存器( RTC_TSSSR、RTC_TSTR 和 RTC_TSDR)中。時間戳往往用來記錄危及時刻的時間,以供事后排查問題時查詢。
6. 入侵檢測
RTC 自帶兩個入侵檢測引腳 RTC_AF1(PC13)和 RTC_AF2(PI8), 這兩個輸入既可配置為邊沿檢測,也可配置為帶過濾的電平檢測。當發生入侵檢測時,備份寄存器將被復位。備份寄存器 (RTC_BKPxR) 包括 20 個 32 位寄存器,用於存儲 80 字節的用戶應用數據。這些寄存器在備份域中實現,可在 VDD 電源關閉時通過 VBAT 保持上電狀態。備份寄存器不會在系統復位或電源復位時復位,也不會在器件從待機模式喚醒時復位。
3 RTC 初始化結構體
標准庫函數對每個外設都建立了一個初始化結構體,比如 RTC_InitTypeDef,結構體成員用於設置外設工作參數,並由外設初始化配置函數,比如 RTC_Init()調用,這些配置好的參數將會設置外設相應的寄存器,達到配置外設工作環境的目的。
初始化結構體和初始化庫函數配合使用是標准庫精髓所在,理解了初始化結構體每個成員意義基本上就可以對該外設運用自如。初始化結構體定義在 stm32f4xx_rtc.h 頭文件中,初始化庫函數定義在 stm32f4xx_rtc.c 文件中,編程時我們可以結合這兩個文件內注釋使用。
RTC初始化結構體用來設置 RTC 小時的格式和 RTC_CLK的分頻系數。
4 RTC 時間結構體
RTC時間初始化結構體用來設置初始時間,配置的是 RTC 時間寄存器 RTC_TR。
1) RTC_Hours:小時設置,12 小時制式時,取值范圍為 0~11,24 小時制式時,取值范圍為 0~23。
2) RTC_Minutes:分鍾設置,取值范圍為 0~59。
3) RTC_Seconds:秒鍾設置,取值范圍為 0~59。
4) RTC_H12 : AM/PM 設 置 , 可 取 值 RTC_H12_AM 和 RTC_H12_PM ,RTC_H12_AM時則是 24小時制,RTC_H12_PM 則是 12 小時制。
5 RTC 日期結構體
RTC日期初始化結構體用來設置初始日期,配置的是 RTC 日期寄存器 RTC_DR。
6 RTC 鬧鍾結構體
RTC 鬧鍾結構體主要用來設置鬧鍾時間,設置的格式為[星期/日期]-[時]-[分]-[秒],共四個字段,每個字段都可以設置為有效或者無效,即可 MASK。如果 MASK到[星期/日期]字段,則每天鬧鍾都會響。
1) RTC_AlarmTime:鬧鍾時間設置,配置的是 RTC時間初始化結構體,主要配置小時的制式,有 12小時或者是 24 小時,配套具體的時、分、秒。
2) RTC_AlarmMask:鬧鍾掩碼字段選擇,即選擇鬧鍾時間哪些字段無效,取值 可為:RTC_AlarmMask_None(全部有效)、RTC_AlarmMask_DateWeekDay(日期或者星期無
效)、RTC_AlarmMask_Hours(小時無效)、RTC_AlarmMask_Minutes(分鍾無效)、RTC_AlarmMask_Seconds(秒鍾無效)、RTC_AlarmMask_All(全部無效)。比如我
們選擇 RTC_AlarmMask_DateWeekDay,那么就是當 RTC 的時間的小時等於鬧鍾時間小時字段時,每天的這個小時都會產生鬧鍾中斷。
3) RTC_AlarmDateWeekDaySel : 鬧 鍾 日 期 或 者 星 期 選 擇 , 可 選 擇RTC_AlarmDateWeekDaySel_WeekDay 或者 RTC_AlarmDateWeekDaySel_Date。要想這個配置有效,則 RTC_AlarmMask 不能配置為 RTC_AlarmMask_DateWeekDay,否則會被 MASK掉。
4) RTC_AlarmDateWeekDay:具體的日期或者星期幾,當 RTC_AlarmDateWeekDaySel 設置成 RTC_AlarmDateWeekDaySel_WeekDay時,取值為 1~7,對應星期一~星期日,當設置成 RTC_AlarmMask_DateWeekDay時,取值為 1~31。