什么是RTC
RTC (Real Time Clock):實(shí)時(shí)時(shí)鐘
RTC是個(gè)獨(dú)立的定時(shí)器。RTC模塊擁有一個(gè)連續(xù)計(jì)數(shù)的計(jì)數(shù)器,在相應(yīng)的軟件配置下,可以提供時(shí)鐘日歷的功能。修改計(jì)數(shù)器的值可以重新設(shè)置當(dāng)前時(shí)間和日期 RTC還包含用于管理低功耗模式的自動喚醒單元。
在斷電情況下 RTC仍可以獨(dú)立運(yùn)行 只要芯片的備用電源一直供電,RTC上的時(shí)間會一直走。
RTC實(shí)質(zhì)是一個(gè)掉電后還繼續(xù)運(yùn)行的定時(shí)器,從定時(shí)器的角度來看,相對于通用定時(shí)器TIM外設(shè),它的功能十分簡單,只有計(jì)時(shí)功能(也可以觸發(fā)中斷)。但其高級指出也就在于掉電之后還可以正常運(yùn)行。
兩個(gè) 32 位寄存器包含二進(jìn)碼十進(jìn)數(shù)格式 (BCD) 的秒、分鐘、小時(shí)( 12 或 24 小時(shí)制)、星期幾、日期、月份和年份。此外,還可提供二進(jìn)制格式的亞秒值。系統(tǒng)可以自動將月份的天數(shù)補(bǔ)償為 28、29(閏年)、30 和 31 天。
上電復(fù)位后,所有RTC寄存器都會受到保護(hù),以防止可能的非正常寫訪問。
無論器件狀態(tài)如何(運(yùn)行模式、低功耗模式或處于復(fù)位狀態(tài)),只要電源電壓保持在工作范圍內(nèi),RTC使不會停止工作。
RCT特征:
可編程的預(yù)分頻系數(shù):分頻系數(shù)高為220。
32位的可編程計(jì)數(shù)器,可用于較長時(shí)間段的測量。
2個(gè)分離的時(shí)鐘:用于APB1接口的PCLK1和RTC時(shí)鐘(RTC時(shí)鐘的頻率必須小于PCLK1時(shí)鐘 頻率的四分之一以上)。
可以選擇以下三種RTC的時(shí)鐘源:
HSE時(shí)鐘除以128;
LSE振蕩器時(shí)鐘;
LSI振蕩器時(shí)鐘
2個(gè)獨(dú)立的復(fù)位類型:
APB1接口由系統(tǒng)復(fù)位;
RTC核心(預(yù)分頻器、鬧鐘、計(jì)數(shù)器和分頻器)只能由后備域復(fù)位
3個(gè)專門的可屏蔽中斷:
1.鬧鐘中斷,用來產(chǎn)生一個(gè)軟件可編程的鬧鐘中斷。
2.秒中斷,用來產(chǎn)生一個(gè)可編程的周期性中斷信號(長可達(dá)1秒)。
3.溢出中斷,指示內(nèi)部可編程計(jì)數(shù)器溢出并回轉(zhuǎn)為0的狀態(tài)。
RTC時(shí)鐘源:
三種不同的時(shí)鐘源可被用來驅(qū)動系統(tǒng)時(shí)鐘(SYSCLK):
HSI振蕩器時(shí)鐘
HSE振蕩器時(shí)鐘
PLL時(shí)鐘
這些設(shè)備有以下2種二級時(shí)鐘源:
40kHz低速內(nèi)部RC,可以用于驅(qū)動獨(dú)立看門狗和通過程序選擇驅(qū)動RTC。RTC用于從停機(jī)/待機(jī)模式下自動喚醒系統(tǒng)。
32.768kHz低速外部晶體也可用來通過程序選擇驅(qū)動RTC(RTCCLK)。
RTC原理框圖
RTC時(shí)鐘的框圖還是比較簡單的,這里我們把他分成 兩個(gè)部分:
APB1 接口:用來和 APB1 總線相連。此單元還包含一組 16 位寄存器,可通過 APB1 總線對其進(jìn)行讀寫操作。APB1 接口由 APB1 總 線時(shí)鐘驅(qū)動,用來與 APB1 總線連接。
通過APB1接口可以訪問RTC的相關(guān)寄存器(預(yù)分頻值,計(jì)數(shù)器值,鬧鐘值)。
RTC 核心接口:由一組可編程計(jì)數(shù)器組成,分成 兩個(gè)主要模塊 。
第一個(gè)模塊是 RTC 的 預(yù)分頻模塊,它可編程產(chǎn)生 1 秒的 RTC 時(shí)間基準(zhǔn) TR_CLK。RTC 的預(yù)分頻模塊包含了一個(gè) 20 位的可編程分頻器(RTC 預(yù)分頻器)。如果在 RTC_CR 寄存器中設(shè)置了相應(yīng)的允許位,則在每個(gè) TR_CLK 周期中 RTC 產(chǎn)生一個(gè)中斷(秒中斷)。
第二個(gè)模塊是一個(gè) 32 位的可編程計(jì)數(shù)器 (RTC_CNT),可被初始化為當(dāng)前的系統(tǒng)時(shí)間,一個(gè) 32 位的時(shí)鐘計(jì)數(shù)器,按秒鐘計(jì)算,可以記 錄 4294967296 秒,約合 136 年左右,作為一般應(yīng)用,這已經(jīng)是足夠了的。
RTC具體流程:
RTCCLK經(jīng)過RTC_DIV預(yù)分頻,RTC_PRL設(shè)置預(yù)分頻系數(shù),然后得到TR_CLK時(shí)鐘信號,我們一般設(shè)置其周期為1s,RTC_CNT計(jì)數(shù)器計(jì)數(shù),假如1970設(shè)置為時(shí)間起點(diǎn)為0s,通過當(dāng)前時(shí)間的秒數(shù)計(jì)算得到當(dāng)前的時(shí)間。RTC_ALR是設(shè)置鬧鐘時(shí)間,RTC_CNT計(jì)數(shù)到RTC_ALR就會產(chǎn)生計(jì)數(shù)中斷,
RTC_Second為秒中斷,用于刷新時(shí)間,
RTC_Overflow是溢出中斷。
RTC Alarm 控制開關(guān)機(jī)
RTC時(shí)鐘選擇
使用HSE分頻時(shí)鐘或者LSI的時(shí)候,在主電源VDD掉電的情況下,這兩個(gè)時(shí)鐘來源都會受到影響,因此沒法保證RTC正常工作。所以RTC一般都時(shí)鐘低速外部時(shí)鐘LSE,頻率為實(shí)時(shí)時(shí)鐘模塊中常用的32.768KHz,因?yàn)?2768 = 2^15,分頻容易實(shí)現(xiàn),所以被廣泛應(yīng)用到RTC模塊。(在主電源VDD有效的情況下(待機(jī)),RTC還可以配置鬧鐘事件使STM32退出待機(jī)模式)。
RTC復(fù)位過程
除了RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器外,所有的系統(tǒng)寄存器都由系統(tǒng)復(fù)位或電源復(fù)位進(jìn)行異步復(fù)位。
RTC_PRL、RTC_ALR、RTC_CNT和RTC_DIV寄存器僅能通過備份域復(fù)位信號復(fù)位。
系統(tǒng)復(fù)位后,禁止訪問后備寄存器和RCT,防止對后衛(wèi)區(qū)域(BKP)的意外寫操作
讀RTC寄存器
RTC內(nèi)核完全獨(dú)立于APB1接口,軟件通過APB1接口對RTC相關(guān)寄存器訪問。但是相關(guān)寄存器只在RTC APB1時(shí)鐘進(jìn)行重新同步的RTC時(shí)鐘的上升沿被更新。所以軟件必須先等待寄存器同步標(biāo)志位(RTC_CRL的RSF位)被硬件置1才讀。
配置RTC寄存器
必須設(shè)置RTC_CRL寄存器中的CNF位,使RTC進(jìn)入配置模式后,才能寫入RTC_PRL、
RTC_CNT、RTC_ALR寄存器。
另外,對RTC任何寄存器的寫操作,都必須在前一次寫操作結(jié)束后進(jìn)行。可以通過查詢
RTC_CR寄存器中的RTOFF狀態(tài)位,判斷RTC寄存器是否處于更新中。僅當(dāng)RTOFF狀態(tài)位是’1’
時(shí),才可以寫入RTC寄存器。
RTC時(shí)鐘源
RTC是一個(gè)獨(dú)立的時(shí)鐘源
RTC寄存器
RTC控制寄存器 (RTC_CRH, RTC_CRL)
RTC預(yù)分頻裝載寄存器 (RTC_PRLH, RTC_PRLL)
RTC預(yù)分頻余數(shù)寄存器 (RTC_DIVH, RTC_DIVL)
RTC計(jì)數(shù)器寄存器 (RTC_CNTH, RTC_CNTL)
RTC鬧鐘寄存器 (RTC_ALRH ,RTC_ALRL)
RTC控制寄存器高位——RTC_CRH 寄存器
作用:配置3個(gè)專門的可屏蔽中斷(溢出中斷、鬧鐘中斷、秒中斷)使能。
注意:系統(tǒng)復(fù)位后所有的中斷被屏蔽,因此可通過寫RTC寄存器來
確保在初始化后沒有掛起的中斷請求。當(dāng)外設(shè)正在完成前一次寫操作時(shí)(標(biāo)志位RTOFF=0),不
能對RTC_CRH寄存器進(jìn)行寫操作。
RTC控制寄存器低位——RTC_CRL 寄存器
一般用到該寄存器的 3,4,5位
第 3 位為寄存器同步標(biāo)志位,我們在修改控制寄存器 RTC_CRH/CRL 之前,必須先判斷該位,是否已經(jīng)同步了,如果沒有則等待同步
第 4 位為配置標(biāo)位,在軟件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的時(shí)候,必須先軟件置位該位,以允許進(jìn)入配置模式
第 5 位為 RTC 操作位,該位由硬件操作,軟件只讀。通過該位可以判斷上次對 RTC 寄存器的操作是否完成,如果沒有,我們必須等待上一次操作結(jié)束才能開始下一次,也就是判斷RTOFF位是否置位。
三個(gè)位總結(jié)如下:
① 修改CRH/CRL寄存器,必須先判斷RSF位,確定已經(jīng)同步。
② 修改CNT,ALR,PRL的時(shí)候,必須先配置CNF位進(jìn)入配置模式,修改完之后,設(shè)置CNF位為0退出配置模式
③ **同時(shí)在對RTC相關(guān)寄存器寫操作之前,必須判斷上一
RTC 預(yù)分頻裝載寄存器——(RTC_PRLH/RTC_PRLL) 寄存器
作用:配置 RTC 時(shí)鐘的分頻數(shù),
比如我們使用外部 32.768K 的晶振作為時(shí)鐘的輸入頻率,那么我們要設(shè)置這兩個(gè)寄存器的值為 7FFFh(32767),就可獲得周期為1秒鐘的信號。
RTC預(yù)分頻器余數(shù)寄存器(RTC_DIVH、RTC_DIVL)
作用:和他的名字一樣,獲得余數(shù),也就是獲取更精確的計(jì)時(shí),比如:0.1s ,0.01 s等
寄存器是只讀寄存器,其值在RTC_PRL或RTC_CNT寄存器中的值發(fā)生改變后,由硬件重新裝載。
RTC 計(jì)數(shù)器寄存器——RTC_CNTX 寄存器
作用:存放計(jì)數(shù)器內(nèi)的計(jì)數(shù)值。也就是用來記錄時(shí)鐘時(shí)間
該寄存器由 2 個(gè) 16 位的寄存器組成 RTC_CNTH 和 RTC_CNTL,總共 32 位,當(dāng)進(jìn)行讀操作時(shí),直接返回計(jì)數(shù)器內(nèi)的計(jì)數(shù)值(系統(tǒng)時(shí)間)
RTC 計(jì)數(shù)器寄存器——RTC 鬧鐘寄存器(RTC_ALRH、RTC_ALRL)
作用:RTC時(shí)鐘中斷控制寄存器
該寄存器也是由 2 個(gè) 16 位的寄存器組成 RTC_ALRH 和 RTC_ALRL,也就是32位,當(dāng)可編程計(jì)數(shù)器的值與RTC_ALR中的32位值相等時(shí),即觸發(fā)一個(gè)鬧鐘事件,并且產(chǎn)生RTC鬧鐘中斷。
BKP備份寄存器
備份寄存器是42個(gè)16位的寄存器。可用來存儲84個(gè)字節(jié)數(shù)據(jù)。
它們處在備份區(qū)域,當(dāng)VDD電源切斷,仍然由VBAT維持供電。
當(dāng)系統(tǒng)在待機(jī)模式下被喚醒,或者系統(tǒng)復(fù)位或者電源復(fù)位,它們也不會復(fù)位。
執(zhí)行以下操作將使能對后備寄存器和RTC訪問:
設(shè)置寄存器RCC_APB1ENR的PWREN和BKPEN位,使能電源和后備時(shí)鐘。
設(shè)置寄存器PWR_CR的DBP位,使能對RTC和后備寄存器的訪問
一般用 BKP 來存儲 RTC 的校驗(yàn)值或者記錄一些重要的數(shù)據(jù),
配置RTC寄存器:
1.查詢RTOFF位,知道RTOFF的值為1.
2.置CNF值為1,進(jìn)入配置模式。
3.對一個(gè)或者多個(gè)RTC寄存器進(jìn)行寫操作。
4.清除CNF標(biāo)志位,退出配置模式。
5.查詢RTOFF,直到RTOFF位變1,已確認(rèn)寫操作已經(jīng)完成。
僅當(dāng)CNF標(biāo)志位被清除時(shí),寫操作才能進(jìn)行,這個(gè)操作至少需要3個(gè)RTCCLK周期。
RTC相關(guān)庫函數(shù)
RTC時(shí)鐘源和時(shí)鐘操作函數(shù):
void RCC_RTCCLKConfig(uint32_t CLKSource);//時(shí)鐘源選擇
void RCC_RTCCLKCmd(FunctionalState NewState)//時(shí)鐘使能
RTC配置函數(shù)(預(yù)分頻,計(jì)數(shù)值):
void RTC_SetPrescaler(uint32_t PrescalerValue);//預(yù)分頻配置:PRLH/PRLL
void RTC_SetCounter(uint32_t CounterValue);//設(shè)置計(jì)數(shù)器值:CNTH/CNTL
void RTC_SetAlarm(uint32_t AlarmValue);//鬧鐘設(shè)置:ALRH/ALRL
RTC中斷設(shè)置函數(shù):
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//CRH
RTC配置函數(shù):
void RTC_EnterConfigMode(void);//允許RTC配置 :CRL位 CNF
void RTC_ExitConfigMode(void);//退出配置模式:CRL位 CNF
RTC同步函數(shù):
void RTC_WaitForLastTask(void);//等待上次操作完成:CRL位RTOFF
void RTC_WaitForSynchro(void);//等待時(shí)鐘同步:CRL位RSF
RTC相關(guān)狀態(tài)位獲取清除函數(shù):
FlagStatus RTC_GetFlagStatus(uint16_t RTC_FLAG);
void RTC_ClearFlag(uint16_t RTC_FLAG);
ITStatus RTC_GetITStatus(uint16_t RTC_IT);
void RTC_ClearITPendingBit(uint16_t RTC_IT);
其他相關(guān)函數(shù)(BKP等)
PWR_BackupAccessCmd();//BKP后備區(qū)域訪問使能
RCC_APB1PeriphClockCmd();//使能PWR和BKP時(shí)鐘
RCC_LSEConfig();//開啟LSE,RTC選擇LSE作為時(shí)鐘源
PWR_BackupAccessCmd();//BKP后備區(qū)域訪問使能
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//讀BKP寄存器
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//寫B(tài)KP
配置RTC步驟
①使能PWR和BKP時(shí)鐘:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
1
② 使能后備寄存器訪問:
PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后備寄存器訪問
1
③復(fù)位備份區(qū)域,開啟外部低速振蕩器。
BKP_DeInit();//復(fù)位備份區(qū)域
1
④ 配置RTC時(shí)鐘源,使能RTC時(shí)鐘:
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //選擇 LSE 作為 RTC 時(shí)鐘(RCC_RTCCLKSource_LSI 和 RCC_RTCCLKSource_HSE_Div128)
RCC_RTCCLKCmd(ENABLE); //使能 RTC 時(shí)鐘
⑤ 設(shè)置RTC預(yù)分頻系數(shù):RTC_SetPrescaler();
RTC_EnterConfigMode();/// 允許配置
RTC_SetPrescaler(32767); //設(shè)置RTC預(yù)分頻的值
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
⑥ 設(shè)置時(shí)間:RTC_SetCounter();
RTC_EnterConfigMode();/// 允許配置
void RTC_SetCounter(uint32_t CounterValue);
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
⑦開啟相關(guān)中斷(可選):
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中斷
⑧編寫中斷服務(wù)函數(shù):
RTC_IRQHandler();
⑨部分操作要等待寫操作完成和同步。
RTC_WaitForLastTask();//等待最近一次對RTC寄存器的寫操作完成
RTC_WaitForSynchro();//等待RTC寄存器同步
具體的代碼,庫函數(shù)寫的太多了,我會用CubeMx配置下,用HAL庫寫一個(gè)例程,幾十行就可以解決RTC。
審核編輯:湯梓紅
-
振蕩器
+關(guān)注
關(guān)注
28文章
3832瀏覽量
139032 -
實(shí)時(shí)時(shí)鐘
+關(guān)注
關(guān)注
4文章
245瀏覽量
65767 -
時(shí)鐘
+關(guān)注
關(guān)注
10文章
1733瀏覽量
131446 -
定時(shí)器
+關(guān)注
關(guān)注
23文章
3246瀏覽量
114715 -
RTC
+關(guān)注
關(guān)注
2文章
538瀏覽量
66460
原文標(biāo)題:一文看懂RTC
文章出處:【微信號:mcu168,微信公眾號:硬件攻城獅】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論