STM32 的 RTC 外設(shè)(Real Time Clock) ,實(shí)質(zhì)是一個掉電后還繼續(xù)運(yùn)行的定時器。STM32G4 的 RTC,是一個獨(dú)立的 BCD 定時器/計(jì)數(shù)器。 RTC 提供一個日歷時鐘(包含年月日時分秒信息)、兩個可編程鬧鐘(ALARM A 和 ALARM B)中斷,以及一個具有中斷功能的周期性可編程喚醒標(biāo)志。 RTC 還包含用于管理低功耗模 式的自動喚醒單元
從定時器的角度來說,相對于通用定時器 TIM 外設(shè),它十分簡單,只有很純粹的計(jì)時和觸發(fā)中斷的功能;但從掉電還繼續(xù)運(yùn)行的角度來說,它卻是 STM32 中唯一一個具有如此強(qiáng)大功能的外設(shè)。所以 RTC 外設(shè)的復(fù)雜之處并不在于它的定時功能,而在于它掉電還繼續(xù)運(yùn)行的特性
以上所說的掉電,是指主電源 VDD 斷開的情況,為了 RTC 外設(shè)掉電繼續(xù)運(yùn)行,必須接上鋰電池給 STM32 的 RTC、備份發(fā)卡通過 VBAT 引腳供電
當(dāng)主電源 VDD 有效時,由VDD給 RTC 外設(shè)供電; 而當(dāng) VDD掉電后,由 VBAT給 RTC 外設(shè)供電。但無論由什么電源供電,== RTC 中的數(shù)據(jù)都保存在屬于 RTC 的備份域中,若主電源 VDD和 VBAT都掉電,那么備份域中保存的所有數(shù)據(jù)將丟失==。
備份域除了 RTC 模塊的寄存器,還有 42 個 16 位的寄存器可以在 VDD 掉電的情況下保存用戶程序的數(shù)據(jù),系統(tǒng)復(fù)位或電源復(fù)位時,這些數(shù)據(jù)也不會被復(fù)位
從 RTC 的定時器特性來說,它是一個 32 位的計(jì)數(shù)器,只能向上計(jì)數(shù)。它使用的時鐘源有三種,分別為高速外部時鐘的, 低速內(nèi)部時鐘 LSI 以及低速外部時鐘 LSE
這里使用的高速外部時鐘HSE32分頻得到750khz,在主電源 VDD有效的情況下(待機(jī)), RTC 還可以配置鬧鐘事件使 STM32 退出待機(jī)模式
由于 RTC_CNT 是 32 位寄存器,可存儲的最大值為(232-1),即這樣計(jì)時的話,在 232秒后溢出,即它將在今后的 136 年時溢出:
N = 232/365/24/60/60 ≈136 年
時鐘分頻來自HSE32分頻得到750khz,然后經(jīng)過7位異步分頻(125)和15位同步分頻(6000),得到ck_spre(一般要使這個值為1hz), ck_spre 即可用于更新日歷時間等信息
日歷時間(RTC_TR)和日期(RTC_DR)寄存器兩個 32 位寄存器包含二進(jìn)碼/B十進(jìn)數(shù)格式 (BCD) 的秒、分鐘、小時(12 或24 小時制)、星期、日期、月份和年份。此外,還可提供二進(jìn)制格式的亞秒值
可以讀取 RTC_TR 和 RTC_DR 來得到當(dāng)前時間和日期信息,不過需要注意的是:時間和日期都是以 BCD 碼的格式存儲的,讀出來要轉(zhuǎn)換一下,才可以得到十進(jìn)制的數(shù)據(jù),在讀的時侯,以二進(jìn)制格式讀出來的數(shù)據(jù)可以直接使用。
STM32G4 提供兩個可編程鬧鐘:鬧鐘 A(ALARM_A)和鬧鐘 B(ALARM_B)。通過 RTC_CR寄存器的 ALRAE 和 ALRBE 位置 1 來使能可編程鬧鐘功能。當(dāng)日歷的亞秒、秒、分、小時、日期分別與鬧鐘寄存器 RTC_ALRMASSR/RTC_ALRMAR 和 RTC_ALRMBSSR/RTC_ALRMBR中的值匹配時,則可以產(chǎn)生鬧鐘(需要適當(dāng)配置)
小結(jié):
RTC配置一般步驟:
① 使能PWR和BKP時鐘
② 使能后備寄存器訪問
③ 配置RTC時鐘源,使能RTC時鐘:
如果使用LSE,要打開LSE:RCC_LSEConfig(RCC_LSE_ON);
④ 設(shè)置RTC預(yù)分頻系數(shù)
⑤ 設(shè)置時間
⑥開啟相關(guān)中斷(如果需要)
⑦編寫中斷服務(wù)函數(shù)
⑧部分操作要等待寫操作完成和同步。
(1)RTC使能時鐘源和日歷
注意,一定要選擇好兩次分頻的系數(shù),使經(jīng)過兩次分頻后的時鐘頻率為1hz
750 000 / 125 / 6000 = 1
RTC_TimeTypeDef H_S_M_Time; // 時間結(jié)構(gòu)體
RTC_DateTypeDef Y_M_D_Data; // 日期結(jié)構(gòu)體
// 獲取日期和時間必須同時使用,注意這里的編碼方式選擇二進(jìn)制,可以直接使用
// 若選擇BCD編碼,需要自己處理數(shù)據(jù)
HAL_RTC_GetTime(&hrtc, &H_S_M_Time,RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &Y_M_D_Data,RTC_FORMAT_BIN);
sprintf((char *)Lcd_Display_String,"TIME:%2d-%2d-%2d",H_S_M_Time.Hours,H_S_M_Time.Minutes,H_S_M_Time.Seconds);
LCD_DisplayStringLine(Line0, Lcd_Display_String);
提示:這里對文章進(jìn)行總結(jié):