** 簡(jiǎn)述**
STM32 的實(shí)時(shí)時(shí)鐘(RTC)是一個(gè)獨(dú)立的定時(shí)器。 STM32 的 RTC 模塊擁有一組連續(xù)計(jì)數(shù)的計(jì)數(shù)器,在相應(yīng)軟件配置下,可提供時(shí)鐘日歷的功能。修改計(jì)數(shù)器的值可以重新設(shè)置系統(tǒng)當(dāng)前的時(shí)間和日期。
RTC 模塊和時(shí)鐘配置系統(tǒng) (RCC_BDCR 寄存器)是在后備區(qū)域,即在系統(tǒng)復(fù)位或從待機(jī)模式喚醒后 RTC 的設(shè)置和時(shí)間維持不變。但是在系統(tǒng)復(fù)位后,會(huì)自動(dòng)禁止訪問(wèn)后備寄存器和 RTC,以防止對(duì)后備區(qū)域 (BKP) 的意外寫(xiě)操作。所以在要設(shè)置時(shí)間之前, 先要取消備份區(qū)域(BKP)寫(xiě)保護(hù)。
RTC 由兩個(gè)主要部分組成(參見(jiàn)上圖), 第一部分(APB1 接口)用來(lái)和 APB1 總線相連。此單元還包含一組 16 位寄存器,可通過(guò) APB1 總線對(duì)其進(jìn)行讀寫(xiě)操作。 APB1 接口由 APB1 總線時(shí)鐘驅(qū)動(dòng),用來(lái)與 APB1 總線連接。
另一部分 (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ù)器,可被初始化為當(dāng)前的系統(tǒng)時(shí)間,一個(gè) 32 位的時(shí)鐘計(jì)數(shù)器,按秒鐘計(jì)算,可以記錄 4294967296 秒,約合 136 年左右。
RTC 還有一個(gè)鬧鐘寄存器 RTC_ALR,用于產(chǎn)生鬧鐘。系統(tǒng)時(shí)間按 TR_CLK 周期累加并與存儲(chǔ)在 RTC_ALR 寄存器中的可編程時(shí)間相比較,如果 RTC_CR 控制寄存器中設(shè)置了相應(yīng)允許位,比較匹配時(shí)將產(chǎn)生一個(gè)鬧鐘中斷。RTC 內(nèi)核完全獨(dú)立于 RTC APB1 接口,而軟件是通過(guò) APB1 接口訪問(wèn) RTC 的預(yù)分頻值、計(jì)數(shù)器值和鬧鐘值的。但是相關(guān)可讀寄存器只在 RTC APB1 時(shí)鐘進(jìn)行重新同步的 RTC 時(shí)鐘的上升沿被更新, RTC 標(biāo)志也是如此。這就意味著,如果 APB1 接口剛剛被開(kāi)啟之后,在第一次的內(nèi)部寄存器更新之前,從 APB1 上讀取的 RTC 寄存器值可能被破壞了(通常讀到 0)。因此,若在讀取 RTC 寄存器曾經(jīng)被禁止的 RTC APB1 接口,軟件首先必須等待 RTC_CRL 寄存器的 RSF位(寄存器同步標(biāo)志位, bit3)被硬件置 1。
2. RTC 寄存器介紹
2.1 RTC 的控制寄存器——RTC_CRH 寄存器
該寄存器用來(lái)控制中斷的。
2.2 RTC 的控制寄存器——RTC_CRL 寄存器
RTC 用到的是該寄存器的 0、 3~5 這幾個(gè)位,第 0 位是秒鐘標(biāo)志位,我們?cè)谶M(jìn)入鬧鐘中斷的時(shí)候,通過(guò)判斷這位來(lái)決定是不是發(fā)生了秒鐘中斷。然后必須通過(guò)軟件將該位清零(寫(xiě) 0)。第 3 位為寄存器同步標(biāo)志位,我們?cè)谛薷目刂萍拇嫫?RTC_CRH/CRL 之前,必須先判斷該位,是否已經(jīng)同步了,如果沒(méi)有則等待同步,在沒(méi)同步的情況下修 RTC_CRH/CRL 的值是不行的。第 4 位為配置標(biāo)位,在軟件修改 RTC_CNT/RTC_ALR/RTC_PRL 的值的時(shí)候,必須先軟件置位該位,以允許進(jìn)入配置模式。第 5 位為 RTC 操作位,該位由硬件操作,軟件只讀。通過(guò)該位可以判斷上次對(duì) RTC 寄存器的操作是否完成,如果沒(méi)有,我們必須等待上一次操作結(jié)束才能開(kāi)始下一次操作。
2.3 RTC 預(yù)分頻裝載寄存器——RTC_PRLH 寄存器
這兩個(gè)寄存器用來(lái)配置 RTC 時(shí)鐘的分頻數(shù)的,比如我們使用外部 32.768K 的晶振作為時(shí)鐘的輸入頻率,那么我們要設(shè)置這兩個(gè)寄存器的值為 32767,以得到一秒鐘的計(jì)數(shù)頻率。
2.4 RTC 預(yù)分頻裝載寄存器——RTC_PRLL 寄存器
2.5 RTC 預(yù)分頻器余數(shù)寄存器——RTC_DIVH 寄存器
2.6 RTC 預(yù)分頻器余數(shù)寄存器——RTC_DIVH 寄存器
這兩個(gè)寄存器的作用就是用來(lái)獲得比秒鐘更為準(zhǔn)確的時(shí)鐘,比如可以得到 0.1 秒,或者 0.01 秒等。該寄存器的值自減的,用于保存還需要多少時(shí)鐘周期獲得一個(gè)秒信號(hào)。在一次秒鐘更新后,由硬件重新裝載。
2.7 RTC 計(jì)數(shù)器寄存器——RTC_CNT 寄存器
該寄存器由 2 個(gè) 16 位的寄存器組成 RTC_CNTH 和 RTC_CNTL,總共 32 位,用來(lái)記錄秒鐘值(一般情況下)。在修改這個(gè)寄存器的時(shí)候要先進(jìn)入配置模式。
2.8 RTC 計(jì)數(shù)器寄存器——RTC 鬧鐘寄存器
該寄存器也是由 2 個(gè) 16 位的寄存器組成 RTC_ALRH 和 RTC_ALRL??偣惨彩?32 位,用來(lái)標(biāo)記鬧鐘產(chǎn)生的時(shí)間(以秒為單位),如果 RTC_CNT 的值與 RTC_ALR 的值相等,并使能了中斷的話,會(huì)產(chǎn)生一個(gè)鬧鐘中斷。該寄存器的修改也要進(jìn)入配置模式才能進(jìn)行。
3. 備份寄存器介紹
備份寄存器是 42 個(gè) 16 位的寄存器(Mini 開(kāi)發(fā)板就是大容量的),可用來(lái)存儲(chǔ) 84 個(gè)字節(jié)的用戶應(yīng)用程序數(shù)據(jù)。他們處在備份域里,當(dāng) VDD 電源被切斷,他們?nèi)匀挥?VBAT 維持供電。即使系統(tǒng)在待機(jī)模式下被喚醒,或系統(tǒng)復(fù)位或電源復(fù)位時(shí),他們也不會(huì)被復(fù)位。
復(fù)位后,對(duì)備份寄存器和 RTC 的訪問(wèn)被禁止,并且備份域被保護(hù)以防止可能存在的意外的
寫(xiě)操作。執(zhí)行以下操作可以使能對(duì)備份寄存器和 RTC 的訪問(wèn):
(1)通過(guò)設(shè)置寄存器 RCC_APB1ENR 的 PWREN 和 BKPEN 位來(lái)打開(kāi)電源和后備接口的時(shí)鐘;
(2)電源控制寄存器 (PWR_CR) 的 DBP 位來(lái)使能對(duì)后備寄存器和 RTC 的訪問(wèn)。
一般用 BKP 來(lái)存儲(chǔ) RTC 的校驗(yàn)值或者記錄一些重要的數(shù)據(jù),相當(dāng)于一個(gè) EEPROM,不過(guò)這個(gè) EEPROM 并不是真正的 EEPROM,而是需要電池來(lái)維持它的數(shù)據(jù)。
RTC 的時(shí)鐘源選擇及使能設(shè)置都是通過(guò)這個(gè)寄存器來(lái)實(shí)現(xiàn)的,所以我們?cè)?RTC 操作之前先要通過(guò)這個(gè)寄存器選擇 RTC 的時(shí)鐘源,然后才能開(kāi)始其他的操作。
4. RTC 配置步驟
(1) 使能電源時(shí)鐘和備份區(qū)域時(shí)鐘
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
(2) 取消備份區(qū)寫(xiě)保護(hù)
PWR_BackupAccessCmd(ENABLE); //使能 RTC 和后備寄存器訪問(wèn)
(3) 復(fù)位備份區(qū)域,開(kāi)啟外部低速振蕩器。
BKP_DeInit();//復(fù)位備份區(qū)域
(4) 選擇 RTC 時(shí)鐘,并使能
RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE); //選擇 LSE 作為 RTC 時(shí)鐘(RCC_RTCCLKSource_LSI 和 RCC_RTCCLKSource_HSE_Div128)
RCC_RTCCLKCmd(ENABLE); //使能 RTC 時(shí)鐘
(5) 設(shè)置 RTC 的分頻,以及配置 RTC 時(shí)鐘
在開(kāi)啟了 RTC 時(shí)鐘之后,我們要做的是設(shè)置 RTC 時(shí)鐘的分頻數(shù),通過(guò) RTC_PRLH 和RTC_PRLL 來(lái)設(shè)置,然后等待 RTC 寄存器操作完成,并同步之后,設(shè)置秒鐘中斷。然后設(shè)置 RTC 的允許配置位(RTC_CRH 的 CNF 位),設(shè)置時(shí)間(其實(shí)就是設(shè)置RTC_CNTH 和 RTC_CNTL兩個(gè)寄存器)。
RTC_EnterConfigMode();/// 允許配置
RTC_ExitConfigMode();//退出配置模式,更新配置
void RTC_SetPrescaler(uint32_t PrescalerValue);
void RTC_ITConfig(uint16_t RTC_IT, FunctionalState NewState);//RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能 RTC 秒中斷
void RTC_SetCounter(uint32_t CounterValue)最后在配置完成之后
(6) 更新配置,設(shè)置 RTC 中斷分組
設(shè)置完時(shí)鐘之后,我們將配置更新同時(shí)退出配置模式,這里還是通過(guò) RTC_CRH 的 CNF 來(lái)實(shí)現(xiàn)。
RTC_ExitConfigMode();//退出配置模式,更新配置
在退出配置模式更新配置之后我們?cè)趥浞輩^(qū)域 BKP_DR1 中寫(xiě)入 0X5050 代表我們已經(jīng)初始化過(guò)時(shí)鐘了,下次開(kāi)機(jī)(或復(fù)位)的時(shí)候,先讀取 BKP_DR1 的值,然后判斷是否是 0X5050 來(lái)決定是不是要配置。接著我們配置 RTC 的秒鐘中斷,并進(jìn)行分組。
void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data);//往備份區(qū)域?qū)懹脩魯?shù)據(jù)
uint16_t BKP_ReadBackupRegister(uint16_t BKP_DR);//讀取備份區(qū)域指定寄存器
(7) 編寫(xiě)中斷服務(wù)函數(shù)
流程圖:
-
寄存器
+關(guān)注
關(guān)注
31文章
5336瀏覽量
120230 -
STM32
+關(guān)注
關(guān)注
2270文章
10895瀏覽量
355727 -
計(jì)數(shù)器
+關(guān)注
關(guān)注
32文章
2256瀏覽量
94476 -
時(shí)鐘
+關(guān)注
關(guān)注
10文章
1733瀏覽量
131446
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論