GD32 MCU內部提供了一個RTC(實時時鐘)模塊,通過RTC可以實現日歷時鐘、鬧鐘等功能。RTC也可以用于深度睡眠或待機模式的低功耗喚醒。不同系列的GD32 MCU在RTC設計和功能上有所區別,總體可以分為三大系列:
(1)F10x、F30x、E10x系列RTC功能基本相同,后文簡稱0x系列。
(2)F1x0、F3x0、E23x系列RTC功能基本相同,后文簡稱x0系列。
(3)F405、F407、F450系列RTC功能基本相同,后文簡稱4xx系列。后文會對0x系列、x0系列、4xx系列的RTC模塊分別進行介紹,簡單介紹RTC的工作原理、配置使用方法。
14.1.GD32 RTC 外設簡介
0x 系列 RTC
0x系列RTC整體架構相對精簡,主要依靠32位累加計數器配置分頻實現時鐘計數。日歷功能可通過軟件計算并寫入備份域中實現;同時具有鬧鐘功能可用于定時產生中斷和喚醒喚醒事件;RTC的核心計數部分在備份域中,可在VDD斷電時VBAT供電的情況保持RTC的計數,正常上電工作時通過APB總線接口可對RTC寄存器進行配置。
0x系列RTC主要特點:
? 32位可編程計數器,用于計數運行時間
– 可編程的預分頻器: 分頻系數最高可達220
? 獨立時鐘域:
– PCLK1時鐘域
– RTC時鐘域(該時鐘必須比PCLK1時鐘至少慢4倍)
? RTC時鐘源:
– HXTAL時鐘分頻
– LXTAL振蕩電路時鐘
– IRC40K振蕩電路時鐘
? 可屏蔽的中斷源:
– 鬧鐘中斷
– 秒中斷
– 溢出中斷
0x系列RTC框圖介紹:
RTC由兩個主要部分組成,如下圖0x系列RTC結構框圖所示,位于PCLK1時鐘域的APB接口和位于RTC時鐘域的RTC內核。

第一部分APB接口用來和APB1總線相連。此單元還包含一組16位寄存器,可通過APB1總線對其進行讀寫操作。對RTC模塊進行相關配置。
另一部分(RTC核心)由一組可編程計數器組成,分成兩個主要模塊。第一個模塊是RTC的預分頻模塊,RTC時鐘源輸入后經過預分頻模塊,可編程產生RTC時間基準SC_CLK。RTC的預分頻模塊包含了一個20位的可編程分頻器(RTC預分頻器);如果在RTC_INTEN寄存器中設置了相應的允許位,則在每個SC_CLK周期中RTC產生一個中斷(秒中斷)。
第二個模塊是一個32位的可編程計數器,可被初始化為當前的系統時間。系統時間按SC_CLK周期累加并與存儲在RTC_ALRM寄存器中的可編程時間相比較,如果RTC_INTEN控制寄存器中設置了相應允許位,比較匹配時將產生一個鬧鐘中斷。
x0 系列 RTC
0x系列RTC提供了一個包含日期(年/月/日)和時間(時/分/秒/亞秒)的日歷功能。除亞秒用二進制碼顯示外,時間和日期都以BCD碼的形式顯示。RTC可以進行夏令時補償。RTC可以工作在省電模式下,并通過軟件配置來智能喚醒。RTC支持外接更高精度的低頻時鐘,用以達到更高的日歷精度。
x0系列RTC主要特點:
? 通過軟件設置來實現夏令時補償。
? 參考時鐘檢測功能:通過外接更高精度的低頻率時鐘源(50Hz/60Hz)來提高日歷精度。
? 數字校準功能:通過調整最小時間單位(最大可調精度0.95ppm)來進行日歷校準。
? 通過移位功能進行亞秒級調整。
? 記錄事件時間的時間戳功能。
? 兩個模式可配置的獨立的侵入檢測。
? 可編程的日歷和一個位域可屏蔽的鬧鐘。
? 5個32位(共20字節)通用備份寄存器,能夠在省電模式下保存數據。當有外部事件侵入時,備份寄存器將會復位。
? 可屏蔽的中斷源:
– 鬧鐘0;
– 時間戳檢測;
– 侵入檢測;
x0系列RTC框圖介紹:
x0系列RTC工作在備份域,可在低功耗模式下保持工作,通過APB總線可對RTC寄存器進行讀取和配置。如下圖x0系列RTC結構框圖所示,RTC時鐘源可配置通過數字平滑校準或直接輸入到7位異步預分頻器輸出ck_apre時鐘用于RTC_SS亞秒寄存器自減計數,ck_apre時鐘又經過15位同步預分頻器后輸出1HZ的ck_spre時鐘提供日歷寄存器使用;基于日歷寄存器還實現了鬧鐘和時間戳功能;RTC還具有鬧鐘、時鐘輸出功能,對RTC_TS、RTC_TAMP0、RTC_TAMP1引腳的有效輸入可觸發時間戳和侵入事件并產生中斷。侵入事件會將備份域復位。

? 鬧鐘
RTC鬧鐘功能被劃分為多個位域并且每一個位域有一個該域的可屏蔽位。屏蔽某些位域后可固定周期產生鬧鐘事件。
? 侵入事件
RTC_TAMPx管腳可以作為侵入事件檢測功能輸入管腳,檢測模式有兩種可供用戶選擇:邊沿檢測模式或者是帶可配置濾波功能的電平檢測模式。侵入事件會將備份域復位,可產生一個中斷。
? 可選的RTC輸出功能:
512Hz( 默認預分頻值): RTC_OUT;
1Hz( 默認預分頻值): RTC_ OUT;
鬧鐘事件( 極性可配置): RTC_ OUT。
? 可選的RTC輸入功能:
時間戳事件檢測( RTC_TS);
侵入事件檢測 0( RTC_TAMP0);
侵入事件檢測 1( RTC_TAMP1);
參考時鐘輸入 RTC_REFIN( 50 或 60Hz)。
? RTC中斷
所有的RTC中斷(鬧鐘、時間戳、侵入事件)都被連接到EXTI控制器。
4xx 系列 RTC 4xx系列RTC在x0系列RTC的基礎上做了部分功能的升級。提供了一個包含日期(年/月/日)和時間(時/分/秒/亞秒)的日歷功能。除亞秒用二進制碼顯示外,時間和日期都以BCD碼的形式顯示。
RTC可以進行夏令時補償。RTC可以工作在省電模式下,并通過軟件配置來智能喚醒。RTC支持外接更高精度的低頻時鐘,用以達到更高的日歷精度。
- 4xx系列RTC主要特點:
? 通過軟件設置來實現夏令時補償。
? 參考時鐘檢測功能:通過外接更高精度的低頻率時鐘源(50Hz或60Hz)來提高日歷精度。
? 數字校準功能:通過調整最小時間單位(最大可調精度0.95ppm)來進行日歷校準。
? 通過移位功能進行亞秒級調整。
? 記錄事件時間的時間戳功能。
? 兩個模式可配置的獨立的侵入檢測。
? 可編程的日歷和一個位域可屏蔽的鬧鐘。
? 20個32位(共80字節)通用備份寄存器,能夠在省電模式下保存數據。當有外部事件侵入時,備份寄存器將會復位。
? 可屏蔽的中斷源:
– 鬧鐘0和鬧鐘1;
– 時間戳檢測;
– 自動喚醒事件;
– 侵入檢測;
? 可配置周期的自動喚醒定時器
4xx系列RTC框圖介紹:
4xx系列RTC工作在備份域,可在低功耗模式下保持工作,通過APB總線可對RTC寄存器進行讀取和配置。如下圖4xx系列RTC結構框圖所示,RTC時鐘源可配置通過數字平滑校準或直接輸入到7位異步預分頻器輸出ck_apre時鐘用于RTC_SS亞秒寄存器自減計數,ck_apre時鐘又可通過數字粗平滑校準或直接輸入15位同步預分頻器后輸出1HZ的ck_spre時鐘提供日歷寄存器使用;基于日歷寄存器還實現了鬧鐘和時間戳功能;RTC還具有鬧鐘、時鐘輸出功能,對RTC_TS、RTC_TAMP0、RTC_TAMP1引腳的有效輸入可觸發時間戳和侵入事件并產生中斷。侵入事件會將備份域復位。4xx系列RTC有一個獨立的自動重加載喚醒定時器可用于產生喚醒事件和中斷。

? 鬧鐘
RTC鬧鐘功能被劃分為多個位域并且每一個位域有一個該域的可屏蔽位。屏蔽某些位域后可固定周期產生鬧鐘事件。
? 侵入事件
RTC_TAMPx管腳可以作為侵入事件檢測功能輸入管腳,檢測模式有兩種可供用戶選擇:邊沿檢測模式或者是帶可配置濾波功能的電平檢測模式。侵入事件會將備份域復位,可產生一個中斷。
? 可選的RTC輸出功能:
512Hz(默認預分頻值):(RTC_OUT)PC13
1Hz(默認預分頻值):(RTC_OUT)PC13
鬧鐘事件(極性可配置):(RTC_OUT)PC13
自動喚醒事件(極性可配置):(RTC_OUT)PC13
? 可選的RTC輸入功能:
時間戳事件檢測(RTC_TS):RTC_AF0、RTC_AF1;
侵入事件檢測 0(RTC_TAMP0):RTC_AF0、RTC_AF1;
侵入事件檢測 1(RTC_TAMP1):RTC_AF1;
參考時鐘輸入 RTC_REFIN(50或60Hz)。
? RTC中斷
所有的RTC中斷(鬧鐘0、鬧鐘1、喚醒、時間戳、侵入0、侵入1)都被連接到EXTI控制器。
各系列 RTC 模塊功能對比
x0系列中的E23x系列均沒有VBAT引腳,不支持VDD掉電保持RTC工作。
0x系列備份域不同于x0、4xx系列,為單獨的一個外設模塊,所以使用RTC時,0x系列相比x0系列和4xx系列還需使能BKP的時鐘。
各系列 RTC 模塊功能對比

14.2.GD32 RTC 硬件設計
? Vbat電源設計
Vbat可以連接至外部電池,在Vdd掉電時可以保證備份域不掉電、RTC繼續運行。VBAT引腳需要對GND連接0.1uF電容,如果沒有外部電池需要將VBAT和一個0.1uF電容連接至Vdd電源上。

? RTC_TAMPx引腳
入侵事件會導致備份域復位,如使用該功能需注意檢測引腳的濾波,可在RTC_TAMPx引腳上并聯0.1uf電容。
14.3.GD32 RTC 軟件配置
GD32MCU_Example下的RTC_Example例程配置了日歷和鬧鐘功能,并開啟了鬧鐘中斷。本小節講解RTC_Example例程中RTC模塊的配置說明,主要包括時鐘及分頻配置、日歷配置、鬧鐘配置、主函數說明。本例程主要介紹GD32 MCU各系列RTC模塊的時間、鬧鐘配置,有關RTC其他功能例程可參考各系列固件庫例程。
時鐘及分頻配置
? 由于RTC工作在備份域,所以使用RTC時需要使能備份域寫功能,而控制備份域寫功能的寄存器位于PMU中,所以操作RTC還需要將PMU_CTL寄存中的BKPWEN置位,從而還需使能PMU的時鐘。而對于0x系列備份域為單獨的外設,還需額外使能BKP備份域時鐘。
? 為了實現準確的日歷功能,配置RTC前需要準備好需要的時鐘源,在選擇合適的時鐘源后RTC還需要進行預分頻的配置。
0x系列時鐘及分頻配置如代碼清單 RTC 0x系列時鐘及分頻配置所示,RTC使能后需要等待RTC寄存器和APB1時鐘同步,執行rtc_register_sync_wait()函數;此外0x系列RTC在RTC寄存器配 置時需要等待上一次配置結束才能繼續新的配置,所以在每個寄存器配置前需要執行rtc_lwoff_wait()函數,等待LWOFF置位。
代碼清單 RTC 0x 系列時鐘及分頻配置
void rtc_config(void) { uint32_t prescaler=0; /* enable PMU and BKPI clocks */ rcu_periph_clock_enable(RCU_BKPI); rcu_periph_clock_enable(RCU_PMU); /* allow access to BKP domain */ pmu_backup_write_enable(); #if RTC_CLOCK_SOURCE_IRC40K prescaler=40000; /* enable LXTAL */ rcu_osci_on(RCU_IRC40K); /* wait till LXTAL is ready */ rcu_osci_stab_wait(RCU_IRC40K); /* select RCU_LXTAL as RTC clock source */ rcu_rtc_clock_config(RCU_RTCSRC_IRC40K); #elif RTC_CLOCK_SOURCE_LXTAL prescaler=32767; /* enable LXTAL */ rcu_osci_on(RCU_LXTAL); /* wait till LXTAL is ready */ rcu_osci_stab_wait(RCU_LXTAL); /* select RCU_LXTAL as RTC clock source */ rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); #else #error RTC clock source should be defined. #endif /* RTC_CLOCK_SOURCE_IRC40K */ /* enable RTC Clock */ rcu_periph_clock_enable(RCU_RTC); /* wait for RTC registers synchronization */ rtc_register_sync_wait(); /* wait until last write operation on RTC registers has finished */ rtc_lwoff_wait(); /* set RTC prescaler: set RTC period to 1s */ rtc_prescaler_set(prescaler); rtc_lwoff_wait(); rtc_interrupt_enable(RTC_INT_ALARM); rtc_lwoff_wait(); }
x0系列時鐘及分頻配置如代碼清單 RTC x0系列時鐘及分頻配置所示,RTC使能后需要等待RTC寄存器和APB1時鐘同步,執行rtc_register_sync_wait()函數;和0x系列不同,后續配置過程x0和4xx系列均不需要執行rtc_lwoff_wait()函數。
代碼清單 RTC x0 系列時鐘及分頻配置
void rtc_config(void) { /* enable PMU clock */ rcu_periph_clock_enable(RCU_PMU); /* enable the access of the RTC registers */ pmu_backup_write_enable(); #if (RTC_CLOCK_SOURCE_IRC40K) rcu_osci_on(RCU_IRC40K); rcu_osci_stab_wait(RCU_IRC40K); rcu_rtc_clock_config(RCU_RTCSRC_IRC40K); prescaler_s = 0x18F; prescaler_a = 0x63; #elif (RTC_CLOCK_SOURCE_LXTAL) rcu_osci_on(RCU_LXTAL); rcu_osci_stab_wait(RCU_LXTAL); rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); prescaler_s = 0xFF; prescaler_a = 0x7F; #else #error RTC clock source should be defined. #endif /* RTC_CLOCK_SOURCE_IRC40K */ rcu_periph_clock_enable(RCU_RTC); rtc_register_sync_wait(); rtc_interrupt_enable(RTC_INT_ALARM); }
4xx系列時鐘及分頻配置如代碼清單 RTC 4xx系列時鐘及分頻配置所示,和x0系列基本相同,但由于4xx系列內部低速時鐘為32K,所以分頻系數和x0系列有所不同。
代碼清單 RTC 4xx 系列時鐘及分頻配置
void rtc_config(void) { /* enable PMU clock */ rcu_periph_clock_enable(RCU_PMU); /* enable the access of the RTC registers */ pmu_backup_write_enable(); #if (RTC_CLOCK_SOURCE_IRC32K) rcu_osci_on(RCU_IRC32K); rcu_osci_stab_wait(RCU_IRC32K); rcu_rtc_clock_config(RCU_RTCSRC_IRC32K); prescaler_s = 0x13F; prescaler_a = 0x63; #elif (RTC_CLOCK_SOURCE_LXTAL) rcu_osci_on(RCU_LXTAL); rcu_osci_stab_wait(RCU_LXTAL); rcu_rtc_clock_config(RCU_RTCSRC_LXTAL); prescaler_s = 0xFF; prescaler_a = 0x7F; #else #error RTC clock source should be defined. #endif /* RTC_CLOCK_SOURCE_IRC32K */ rcu_periph_clock_enable(RCU_RTC); rtc_register_sync_wait(); rtc_interrupt_enable(RTC_INT_ALARM0); }
日歷配置
0x系列由于沒有硬件日歷功能,所以需要讀取計數器通過軟件計算出日歷;而x0系列和4xx系列具有硬件日歷功能,日期信息均是BCD碼,所以在日歷配置的格式和方式均有差別。
0x系列RTC的日歷配置如代碼清單 RTC 0x系列日歷配置所示,該函數提供了日歷配置的入口參數,先將需要配置的日歷信息轉換成秒單位,再寫入RTC計數器即可。入口參數使用十進制寫入。
代碼清單 RTC 0x 系列日歷配置
uint32_t rtc_time_set(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) { uint16_t t; uint32_t seccount = 0; if(year < 1970 || year > 2099) return ERROR; for(t = 1970; t < year; t++){ if(is_leap_year(t)){ seccount += 31622400; }else{ seccount += 31536000; } } month -= 1; for(t=0; t < month; t++){ seccount += (uint32_t)month_table[t] * 86400; if(is_leap_year(year) && t==1){ seccount+=86400; } } seccount += (uint32_t)(day-1) * 86400; seccount += (uint32_t)hour * 3600; seccount += second; rtc_lwoff_wait(); rtc_counter_set(seccount); rtc_lwoff_wait(); return SUCCESS; }
x0系列RTC的日歷配置如代碼清單 RTC x0系列日歷配置所示,該函數提供了日歷配置的入口參數,參數為BCD碼格式,寫入后對RTC日歷結構體賦初值,日歷結構體還可以配置星期、時間格式等,這里默認配置了24小時制。函數入口參數使用16進制寫入。
代碼清單 RTC x0 系列日歷配置
uint32_t rtc_time_set(uint16_t year,uint8_t month,uint8_t day,uint32_t tmp_hh,uint32_t tmp_mm,uint32_t tmp_ss) { rtc_initpara.rtc_factor_asyn = prescaler_a; rtc_initpara.rtc_factor_syn = prescaler_s; rtc_initpara.rtc_year = year&0x00ff; rtc_initpara.rtc_day_of_week = RTC_SATURDAY; rtc_initpara.rtc_month = month; rtc_initpara.rtc_date = day; rtc_initpara.rtc_display_format = RTC_24HOUR; rtc_initpara.rtc_am_pm = RTC_AM; rtc_initpara.rtc_hour = tmp_hh; rtc_initpara.rtc_minute = tmp_mm; rtc_initpara.rtc_second = tmp_ss; if(ERROR == rtc_init(&rtc_initpara)){ return ERROR; } return SUCCESS; }
4xx系列RTC的日歷配置如代碼清單 0-52 RTC 4xx系列日歷配置所示,和x0系列基本相同, 唯一區別只是日歷結構體成員名字少了“RTC_”的前綴。
代碼清單 RTC 4xx 系列日歷配置
uint32_t rtc_time_set(uint16_t year,uint8_t month,uint8_t day,uint32_t tmp_hh,uint32_t tmp_mm,uint32_t tmp_ss) { rtc_initpara.factor_asyn = prescaler_a; rtc_initpara.factor_syn = prescaler_s; rtc_initpara.year = year&0x00ff; rtc_initpara.day_of_week = RTC_SATURDAY; rtc_initpara.month = month; rtc_initpara.date = day; rtc_initpara.display_format = RTC_24HOUR; rtc_initpara.am_pm = RTC_AM; rtc_initpara.hour = tmp_hh; rtc_initpara.minute = tmp_mm; rtc_initpara.second = tmp_ss; if(ERROR == rtc_init(&rtc_initpara)){ return ERROR; } return SUCCESS; }
鬧鐘配置
0x系列的RTC通過32位計數器運行時間,所以其鬧鐘也是32位數據,當計數器和鬧鐘值匹配時會產生鬧鐘事件或中斷,所需配置的鬧鐘值為鬧鐘剩余倒計時加上當前計數器值;而x0系列和4xx系列是硬件BCD日歷功能,所以其鬧鐘也是BDC格式,且具有位域屏蔽功能,根據需要直接配置具體的時間即可。
0x系列RTC的鬧鐘配置如代碼清單 RTC 0x系列鬧鐘配置所示,該函數提供了鬧鐘配置的入口參數,先將需要配置的時間信息轉換成秒單位,再加上當前計數器的值寫入鬧鐘寄存器即可。
0x系列配置的鬧鐘參數為鬧鐘中斷的倒計時時間,寫入參數為十進制。
代碼清單 RTC 0x 系列鬧鐘配置
void rtc_alarm_set(uint8_t hour, uint8_t minute, uint8_t second) { alarm_second = 3600 * hour + minute * 60 + second; rtc_lwoff_wait(); rtc_alarm_config(rtc_counter_get() + alarm_second); rtc_lwoff_wait(); } seccount += (uint32_t)(day-1) * 86400; seccount += (uint32_t)hour * 3600; seccount += (uint32_t)minute * 60; seccount += second; rtc_lwoff_wait(); rtc_counter_set(seccount); rtc_lwoff_wait(); return SUCCESS; }
x0系列RTC的鬧鐘配置如代碼清單 RTC x0系列鬧鐘配置所示,該函數提供了鬧鐘配置的入口參數,參數為BCD碼格式,寫入后對RTC鬧鐘結構體賦初值,鬧鐘結構體可以配置位域屏蔽、選擇配置日期或星期、時間格式等,這里默認配置了屏蔽天、小時、分鐘,所以配置最后實際生效的只有秒,所以配置后鬧鐘均是1分鐘產生一次。鬧鐘配置前需失能鬧鐘,配置后再使能,4xx系列配置的鬧鐘參數為鬧鐘產生的日期時間,因BCD格式寫入參數參數使用16進制。
代碼清單 RTC x0 系列鬧鐘配置
void rtc_alarm_set(uint32_t tmp_hh,uint32_t tmp_mm,uint32_t tmp_ss) { rtc_alarm_struct rtc_alarm; rtc_alarm_disable(); rtc_alarm.rtc_alarm_mask = RTC_ALARM_DATE_MASK|RTC_ALARM_HOUR_MASK|RTC_ALARM_MINUTE_MASK; rtc_alarm.rtc_weekday_or_date = RTC_ALARM_DATE_SELECTED; rtc_alarm.rtc_alarm_day = 0x31; rtc_alarm.rtc_am_pm = RTC_AM; rtc_alarm.rtc_alarm_hour = tmp_hh; rtc_alarm.rtc_alarm_minute = tmp_mm; rtc_alarm.rtc_alarm_second = tmp_ss; rtc_alarm_config(&rtc_alarm); rtc_alarm_enable(); }
4xx系列RTC的鬧鐘配置如代碼清單 0-55 RTC 4xx系列鬧鐘配置所示,和x0系列基本相同, 唯一區別只是鬧鐘結構體成員名字少了“RTC_”的前綴。
代碼清單 RTC 4xx 系列鬧鐘配置
uint32_t rtc_time_set(uint16_t year,uint8_t month,uint8_t day,uint32_t tmp_hh,uint32_t tmp_mm,uint32_t tmp_ss) { rtc_initpara.factor_asyn = prescaler_a; rtc_initpara.factor_syn = prescaler_s; rtc_initpara.year = year&0x00ff; rtc_initpara.day_of_week = RTC_SATURDAY; rtc_initpara.month = month; rtc_initpara.date = day; rtc_initpara.display_format = RTC_24HOUR; rtc_initpara.am_pm = RTC_AM; rtc_initpara.hour = tmp_hh; rtc_initpara.minute = tmp_mm; rtc_initpara.second = tmp_ss; if(ERROR == rtc_init(&rtc_initpara)){ return ERROR; } return SUCCESS; }
主函數說明 主函數如代碼清單 RTC_Example主函數所示,主要包含了中斷配置、RTC時鐘源和預分頻配置、日歷設置以及鬧鐘設置,成功設置好日歷和鬧鐘后在備份域數據寄存器寫入一個標志位,下次非備份域復位的情況就可以不再重復配置RTC。While1中循環調用rtc_current_time_get()函數獲取日歷信息。4xx系列和x0系列中固件庫底層已經提供了rtc_current_time_get()函數,直接更新至日歷結構體;而0x系列固件庫沒有此函數,額外編寫了相同接口的函數,通過讀取32位計數器軟件計算出日歷信息更新至自定義的日歷結構體中。通過仿真或串口打印可以看到結構體中的時間數據在更新。
代碼清單 RTC_Example 主函數
int main(void) { /* NVIC configure */ nvic_config(); rtc_config(); alarm_second=5; if (RTC_BKP0 != 0xA5A5){ /* backup data register value is not correct or not yet programmed (when the first time the program is executed) */ #if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X if(SUCCESS==rtc_time_set(2019, 10, 14, 12, 0, 0)){ rtc_alarm_set(12, 12, alarm_second); #elif defined GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X if(SUCCESS==rtc_time_set(0x2019, 0x10, 0x14, 0x12, 0, 0)){ rtc_alarm_set(0x12, 0x12, alarm_second); #endif RTC_BKP0=0xA5A5; } } while (1){ /* updata time in infinite loop */ rtc_current_time_get(&rtc_initpara); } }
代碼清單 0x 系列自定義 rtc_current_time_get()主函數
void rtc_current_time_get(rtc_parameter_struct* RTC_Calend) { static uint16_t daycnt = 0; uint32_t temp = 0,timevar=rtc_counter_get(); uint16_t temp1 = 0; temp = timevar / 86400; if(daycnt != temp) { daycnt = temp; temp1 = 1970; while(temp >= 365){ if(is_leap_year(temp1)){ if(temp >= 366) temp-=366; else break; }else temp -= 365; temp1++; } RTC_Calend->years = temp1; temp1=0; while(temp >= 28) { if(is_leap_year(RTC_Calend->years) && temp1 == 1){ if(temp >= 29) temp -= 29; else break; }else{ if(temp >= month_table[temp1]) temp -= month_table[temp1]; else break; } temp1++; } RTC_Calend->months = temp1 + 1; RTC_Calend->days = temp + 1; } temp = timevar % 86400; RTC_Calend->hours = temp / 3600; RTC_Calend->minutes = (temp % 3600) / 60; RTC_Calend->seconds = (temp % 3600) % 60; }
鬧鐘中斷說明
例程中開啟了鬧鐘中斷,初始化調用rtc_alarm_set(uint8_t hour, uint8_t minute, uint8_t second)函數分別配置了“0時0分5秒”的鬧鐘。
? 對0x系列來說這個配置是倒計時“0時0分5秒”后產生鬧鐘,進入鬧鐘中斷后再配置新的5s實現5s一次的鬧鐘周期;
? 對x0和4xx系列這個配置是時間在“0時0分5秒”時產生鬧鐘,但因為鬧鐘配置中已經屏蔽了鬧鐘的天、時、分位域,所以鬧鐘會在每分鐘的5秒產生,鬧鐘周期為一分鐘產生一次。
14.4.RTC 使用注意事項
1、 因為內部低速時鐘是在VDDA電源域,所以VDD斷電后VBAT供電情況下保持RTC運行需要使用外部低速時鐘;此外使用LXTAL在非備份域復位時可以不用在初始化階段配置,但使用內部低速時鐘需要每次復位都進行內部時鐘的初始化。
2、 內部低速時鐘精度相對較差,如必須使用內部且對精度有一定要求,4xx和0x系列可以使用TIMER4、x0系列可以使用TIMER13捕獲內部低速時鐘,計算出實際的頻率值來進行合適分頻。
3、 日歷信息意外被清零的話注意是否發生過備份域復位,是否有Vbat掉電或入侵事件發生。
4、 調試中如果修改了RTC代碼的配置,請先擦除全片Flash,然后斷電并上電后再下載新的代碼。
-
單片機
+關注
關注
6078文章
45542瀏覽量
672569 -
嵌入式
+關注
關注
5206文章
20563瀏覽量
336065 -
開發板
+關注
關注
26文章
6359瀏覽量
119870 -
RTC
+關注
關注
2文章
662瀏覽量
72084
發布評論請先 登錄
GD32 MCU 入門教程】GD32 MCU 常見外設介紹(12)FMC 模塊介紹
GD32 MCU移植
《GD32 MCU原理及固件庫開發指南》 + 初讀感悟
兆易創新GD32 MCU選型手冊,適用于GD32全系列MCU
【GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(1)使用Keil開發GD32
【GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(2)使用 IAR 開發 GD32
【GD32 MCU 入門教程】一、GD32 MCU 開發環境搭建(3)使用 Embedded Builder 開發 GD32
【GD32 MCU 入門教程】二、GD32 MCU 燒錄說明(1)ISP 燒錄
【GD32 MCU入門教程】GD32 MCU GPIO 結構與使用注意事項
【GD32 MCU 入門教程】GD32 MCU 常見外設介紹(14)RTC 模塊介紹
評論