RTC簡介
實時時鐘(Real Time Clock,RTC),本質是一個計數器,計數頻率常為秒,專門用來記錄時間。
普通定時器拿來作時鐘可行嗎?普通定時器無法掉電運行!
RTC特性:
1,能提供時間(秒鐘數) 2,能在MCU掉電后運行 3,低功耗
常用的RTC方案
對比因素 | 內部RTC | 外置RTC |
信息差異 | 提供秒/亞秒信號 | 提供秒信號和日歷 |
功耗 | 功耗高 | 功耗低 |
體積 | 不用占用額外體積 | 體積大 |
成本 | 成本低 | 成本高 |
1,一般都需要設計RTC外圍電路; 2,一般都可以給RTC設置獨立的電源; 3,多數RTC的寄存器采用BCD碼存儲時間信息;
BCD碼
時間戳
Unix 時間戳(Unix Timestamp)定義為從UTC/GMT的1970年1月1日0時0分0秒開始所經過的秒數,不考慮閏秒
時間戳存儲在一個秒計數器中,秒計數器為32位/64位的整型變量
世界上所有時區的秒計數器相同,不同時區通過添加偏移來得到當地時間
UTC/GMT
GMT(Greenwich Mean Time)格林尼治標準時間是一種以地球自轉為基礎的時間計量系統。它將地球自轉一周的時間間隔等分為24小時,以此確定計時標準
UTC(Universal Time Coordinated)協調世界時是一種以原子鐘為基礎的時間計量系統。它規定銫133原子基態的兩個超精細能級間在零磁場下躍遷輻射9,192,631,770周所持續的時間為1秒。當原子鐘計時一天的時間與地球自轉一周的時間相差超過0.9秒時,UTC會執行閏秒來保證其計時與地球自轉的協調一致
時間戳轉換
C語言的time.h模塊提供了時間獲取和時間戳轉換的相關函數,可以方便地進行秒計數器、日期時間和字符串之間的轉換
函數 | 作用 |
time_t?time(time_t*); | 獲取系統時鐘 |
struct?tm*?gmtime(const?time_t*); | 秒計數器轉換為日期時間(格林尼治時間) |
struct?tm*?localtime(const?time_t*); | 秒計數器轉換為日期時間(當地時間) |
time_t?mktime(struct?tm*); | 日期時間轉換為秒計數器(當地時間) |
char*?ctime(const?time_t*); | 秒計數器轉換為字符串(默認格式) |
char*?asctime(const?struct?tm*); | 日期時間轉換為字符串(默認格式) |
size_t?strftime(char*,?size_t,?const?char*,?const?struct?tm*); | 日期時間轉換為字符串(自定義格式) |
STM32 F1 RTC框圖介紹
1,RTC預分頻器
2,32位可編程計數器
3,待機喚醒
4,RTC控制寄存器與APB1接口
3個時鐘源(HSE / 128) ?? ??? ? ? (LSI 40kHz) ?? ??? ?(LSE 32.768kHz)
RTC工作在后備區域,VDD掉電仍正常
F1 RTC相關寄存器介紹
后備寄存器和RTC寄存器特性(F1)
部分寄存器寫保護:RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器不會被系統復位?
數據存儲功能:RTC和后備寄存器不會被系統或電源復位源復位;當從待機模式喚醒時,也不會被復位。 后備寄存器可用于保存掉電時的數據。
獨立工作:RTC和后備寄存器通過一個開關供電,在VDD有效時該開關選擇VDD供電,否則由VBAT引腳供電。在VBAT供電時仍可繼續工作。
2個獨立復位:APB1接口由系統復位;RTC核心只能由后備域復位;
RCC_APB1ENR寄存器
使能PWR && BKP時鐘
PWR_CR寄存器
使能后備域和RTC的訪問權限
RCC_BDCR寄存器
通過RCC_BDCR配置: 1,開啟RTC時鐘 2,開啟LSE時鐘; 3,選擇RTC計數時鐘源;
選擇LSE的原因,見F1參考手冊V10 59頁關于RTC時鐘的描述
RTC_CRL寄存器
RTC進入配置模式,關注的位
RTC_CRH寄存器
復位值為0,置1可開啟相關中斷
RTC_PRLH寄存器
使計數器每計數一次就是1秒,即需要32768分頻。
RTC_PRLL寄存器
與RTC_PRL相似的寄存器RTC_DIV可以在不停止分頻計數器的工作,獲得預分頻計數器的當前值。
RTC_CNTH寄存器
注意:進入配置模式才能對寄存器進行操作
RTC_CNTL寄存器
與RTC_CNT相似的寄存器還有RTC_ALR,這里就不做介紹。
RTC相關的HAL庫驅動介紹(F1)
驅動函數 | 關聯寄存器 | 功能描述 |
HAL_RTC_Init(...) | CRL/CRH/PRLH/PRLL | 初始化RTC |
HAL_RTC_MspInit(…) | 初始化回調 | 使能RTC時鐘 |
HAL_RCC_OscConfig(…) | RCC_CR/PWR_CR | 開啟LSE時鐘源 |
HAL_RCCEx_PeriphCLKConfig(...) | RCC_BDCR | 設置RTC時鐘源為LSE |
HAL_PWR_EnableBkUpAccess(...) | PWR_CR | 使能備份域的訪問權限 |
HAL_RTCEx_BKUPWrite/Read() | BKP_DRx | 讀/寫備份域數據寄存器 |
以下是需要開啟的時鐘源: __HAL_RCC_RTC_ENABLE()
__HAL_RCC_PWR_CLK_ENABLE()
__HAL_RCC_BKP_CLK_ENABLE()
RTC基本驅動步驟(F1)
時間設置和讀取
由于F1的RTC沒有日歷寄存器,使用時只存儲總秒數,不利于直接設置和顯示,所以我們還需要編寫函數把時間變成我們日常的日歷時間
驅動函數 | 功能描述 |
rtc_get_time(…) | 總秒數轉成日歷時間 |
rtc_is_leap_year(…) | 判斷是否閏年 |
uint8_t?rtc_get_week(…) | 計算公歷日歷對應的星期幾 |
static?long?rtc_date2sec(…) | 日歷時間轉成對應總秒數 |
全局的結構體變量calendar存儲時間信息