0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

【GD32 MCU 入門(mén)教程】GD32 MCU 常見(jiàn)外設(shè)介紹(14)RTC 模塊介紹

聚沃科技 ? 2024-08-23 09:18 ? 次閱讀

GD32 MCU內(nèi)部提供了一個(gè)RTC(實(shí)時(shí)時(shí)鐘)模塊,通過(guò)RTC可以實(shí)現(xiàn)日歷時(shí)鐘、鬧鐘等功能。RTC也可以用于深度睡眠或待機(jī)模式的低功耗喚醒。不同系列的GD32 MCU在RTC設(shè)計(jì)和功能上有所區(qū)別,總體可以分為三大系列:

(1)F10x、F30x、E10x系列RTC功能基本相同,后文簡(jiǎn)稱0x系列。

(2)F1x0、F3x0、E23x系列RTC功能基本相同,后文簡(jiǎn)稱x0系列。

(3)F405、F407、F450系列RTC功能基本相同,后文簡(jiǎn)稱4xx系列。后文會(huì)對(duì)0x系列、x0系列、4xx系列的RTC模塊分別進(jìn)行介紹,簡(jiǎn)單介紹RTC的工作原理、配置使用方法。

14.1.GD32 RTC 外設(shè)簡(jiǎn)介

0x 系列 RTC

0x系列RTC整體架構(gòu)相對(duì)精簡(jiǎn),主要依靠32位累加計(jì)數(shù)器配置分頻實(shí)現(xiàn)時(shí)鐘計(jì)數(shù)。日歷功能可通過(guò)軟件計(jì)算并寫(xiě)入備份域中實(shí)現(xiàn);同時(shí)具有鬧鐘功能可用于定時(shí)產(chǎn)生中斷和喚醒喚醒事件;RTC的核心計(jì)數(shù)部分在備份域中,可在VDD斷電時(shí)VBAT供電的情況保持RTC的計(jì)數(shù),正常上電工作時(shí)通過(guò)APB總線接口可對(duì)RTC寄存器進(jìn)行配置。

0x系列RTC主要特點(diǎn):

? 32位可編程計(jì)數(shù)器,用于計(jì)數(shù)運(yùn)行時(shí)間

– 可編程的預(yù)分頻器: 分頻系數(shù)最高可達(dá)220

? 獨(dú)立時(shí)鐘域:

– PCLK1時(shí)鐘域

– RTC時(shí)鐘域(該時(shí)鐘必須比PCLK1時(shí)鐘至少慢4倍)

? RTC時(shí)鐘源:

– HXTAL時(shí)鐘分頻

– LXTAL振蕩電路時(shí)鐘

– IRC40K振蕩電路時(shí)鐘

? 可屏蔽的中斷源:

– 鬧鐘中斷

– 秒中斷

– 溢出中斷

0x系列RTC框圖介紹:

RTC由兩個(gè)主要部分組成,如下圖0x系列RTC結(jié)構(gòu)框圖所示,位于PCLK1時(shí)鐘域的APB接口和位于RTC時(shí)鐘域的RTC內(nèi)核。

輸入圖片說(shuō)明

第一部分APB接口用來(lái)和APB1總線相連。此單元還包含一組16位寄存器,可通過(guò)APB1總線對(duì)其進(jìn)行讀寫(xiě)操作。對(duì)RTC模塊進(jìn)行相關(guān)配置。

另一部分(RTC核心)由一組可編程計(jì)數(shù)器組成,分成兩個(gè)主要模塊。第一個(gè)模塊是RTC的預(yù)分頻模塊,RTC時(shí)鐘源輸入后經(jīng)過(guò)預(yù)分頻模塊,可編程產(chǎn)生RTC時(shí)間基準(zhǔn)SC_CLK。RTC的預(yù)分頻模塊包含了一個(gè)20位的可編程分頻器(RTC預(yù)分頻器);如果在RTC_INTEN寄存器中設(shè)置了相應(yīng)的允許位,則在每個(gè)SC_CLK周期中RTC產(chǎn)生一個(gè)中斷(秒中斷)。

第二個(gè)模塊是一個(gè)32位的可編程計(jì)數(shù)器,可被初始化為當(dāng)前的系統(tǒng)時(shí)間。系統(tǒng)時(shí)間按SC_CLK周期累加并與存儲(chǔ)在RTC_ALRM寄存器中的可編程時(shí)間相比較,如果RTC_INTEN控制寄存器中設(shè)置了相應(yīng)允許位,比較匹配時(shí)將產(chǎn)生一個(gè)鬧鐘中斷。

x0 系列 RTC

0x系列RTC提供了一個(gè)包含日期(年/月/日)和時(shí)間(時(shí)/分/秒/亞秒)的日歷功能。除亞秒用二進(jìn)制碼顯示外,時(shí)間和日期都以BCD碼的形式顯示。RTC可以進(jìn)行夏令時(shí)補(bǔ)償。RTC可以工作在省電模式下,并通過(guò)軟件配置來(lái)智能喚醒。RTC支持外接更高精度的低頻時(shí)鐘,用以達(dá)到更高的日歷精度。

x0系列RTC主要特點(diǎn):

? 通過(guò)軟件設(shè)置來(lái)實(shí)現(xiàn)夏令時(shí)補(bǔ)償。

? 參考時(shí)鐘檢測(cè)功能:通過(guò)外接更高精度的低頻率時(shí)鐘源(50Hz/60Hz)來(lái)提高日歷精度。

? 數(shù)字校準(zhǔn)功能:通過(guò)調(diào)整最小時(shí)間單位(最大可調(diào)精度0.95ppm)來(lái)進(jìn)行日歷校準(zhǔn)。

? 通過(guò)移位功能進(jìn)行亞秒級(jí)調(diào)整。

? 記錄事件時(shí)間的時(shí)間戳功能。

? 兩個(gè)模式可配置的獨(dú)立的侵入檢測(cè)。

? 可編程的日歷和一個(gè)位域可屏蔽的鬧鐘。

? 5個(gè)32位(共20字節(jié))通用備份寄存器,能夠在省電模式下保存數(shù)據(jù)。當(dāng)有外部事件侵入時(shí),備份寄存器將會(huì)復(fù)位。

? 可屏蔽的中斷源:

– 鬧鐘0;

– 時(shí)間戳檢測(cè);

– 侵入檢測(cè);

x0系列RTC框圖介紹:

x0系列RTC工作在備份域,可在低功耗模式下保持工作,通過(guò)APB總線可對(duì)RTC寄存器進(jìn)行讀取和配置。如下圖x0系列RTC結(jié)構(gòu)框圖所示,RTC時(shí)鐘源可配置通過(guò)數(shù)字平滑校準(zhǔn)或直接輸入到7位異步預(yù)分頻器輸出ck_apre時(shí)鐘用于RTC_SS亞秒寄存器自減計(jì)數(shù),ck_apre時(shí)鐘又經(jīng)過(guò)15位同步預(yù)分頻器后輸出1HZ的ck_spre時(shí)鐘提供日歷寄存器使用;基于日歷寄存器還實(shí)現(xiàn)了鬧鐘和時(shí)間戳功能;RTC還具有鬧鐘、時(shí)鐘輸出功能,對(duì)RTC_TS、RTC_TAMP0、RTC_TAMP1引腳的有效輸入可觸發(fā)時(shí)間戳和侵入事件并產(chǎn)生中斷。侵入事件會(huì)將備份域復(fù)位。

輸入圖片說(shuō)明

? 鬧鐘

RTC鬧鐘功能被劃分為多個(gè)位域并且每一個(gè)位域有一個(gè)該域的可屏蔽位。屏蔽某些位域后可固定周期產(chǎn)生鬧鐘事件。

? 侵入事件

RTC_TAMPx管腳可以作為侵入事件檢測(cè)功能輸入管腳,檢測(cè)模式有兩種可供用戶選擇:邊沿檢測(cè)模式或者是帶可配置濾波功能的電平檢測(cè)模式。侵入事件會(huì)將備份域復(fù)位,可產(chǎn)生一個(gè)中斷。

? 可選的RTC輸出功能:

512Hz( 默認(rèn)預(yù)分頻值): RTC_OUT;

1Hz( 默認(rèn)預(yù)分頻值): RTC_ OUT;

鬧鐘事件( 極性可配置): RTC_ OUT。

? 可選的RTC輸入功能:

時(shí)間戳事件檢測(cè)( RTC_TS);

侵入事件檢測(cè) 0( RTC_TAMP0);

侵入事件檢測(cè) 1( RTC_TAMP1);

參考時(shí)鐘輸入 RTC_REFIN( 50 或 60Hz)。

? RTC中斷

所有的RTC中斷(鬧鐘、時(shí)間戳、侵入事件)都被連接到EXTI控制器。

4xx 系列 RTC 4xx系列RTC在x0系列RTC的基礎(chǔ)上做了部分功能的升級(jí)。提供了一個(gè)包含日期(年/月/日)和時(shí)間(時(shí)/分/秒/亞秒)的日歷功能。除亞秒用二進(jìn)制碼顯示外,時(shí)間和日期都以BCD碼的形式顯示。

RTC可以進(jìn)行夏令時(shí)補(bǔ)償。RTC可以工作在省電模式下,并通過(guò)軟件配置來(lái)智能喚醒。RTC支持外接更高精度的低頻時(shí)鐘,用以達(dá)到更高的日歷精度。

  1. 4xx系列RTC主要特點(diǎn):

? 通過(guò)軟件設(shè)置來(lái)實(shí)現(xiàn)夏令時(shí)補(bǔ)償。

? 參考時(shí)鐘檢測(cè)功能:通過(guò)外接更高精度的低頻率時(shí)鐘源(50Hz或60Hz)來(lái)提高日歷精度。

? 數(shù)字校準(zhǔn)功能:通過(guò)調(diào)整最小時(shí)間單位(最大可調(diào)精度0.95ppm)來(lái)進(jìn)行日歷校準(zhǔn)。

? 通過(guò)移位功能進(jìn)行亞秒級(jí)調(diào)整。

? 記錄事件時(shí)間的時(shí)間戳功能。

? 兩個(gè)模式可配置的獨(dú)立的侵入檢測(cè)。

? 可編程的日歷和一個(gè)位域可屏蔽的鬧鐘。

? 20個(gè)32位(共80字節(jié))通用備份寄存器,能夠在省電模式下保存數(shù)據(jù)。當(dāng)有外部事件侵入時(shí),備份寄存器將會(huì)復(fù)位。

? 可屏蔽的中斷源:

– 鬧鐘0和鬧鐘1;

– 時(shí)間戳檢測(cè);

– 自動(dòng)喚醒事件;

– 侵入檢測(cè);

? 可配置周期的自動(dòng)喚醒定時(shí)器

4xx系列RTC框圖介紹:

4xx系列RTC工作在備份域,可在低功耗模式下保持工作,通過(guò)APB總線可對(duì)RTC寄存器進(jìn)行讀取和配置。如下圖4xx系列RTC結(jié)構(gòu)框圖所示,RTC時(shí)鐘源可配置通過(guò)數(shù)字平滑校準(zhǔn)或直接輸入到7位異步預(yù)分頻器輸出ck_apre時(shí)鐘用于RTC_SS亞秒寄存器自減計(jì)數(shù),ck_apre時(shí)鐘又可通過(guò)數(shù)字粗平滑校準(zhǔn)或直接輸入15位同步預(yù)分頻器后輸出1HZ的ck_spre時(shí)鐘提供日歷寄存器使用;基于日歷寄存器還實(shí)現(xiàn)了鬧鐘和時(shí)間戳功能;RTC還具有鬧鐘、時(shí)鐘輸出功能,對(duì)RTC_TS、RTC_TAMP0、RTC_TAMP1引腳的有效輸入可觸發(fā)時(shí)間戳和侵入事件并產(chǎn)生中斷。侵入事件會(huì)將備份域復(fù)位。4xx系列RTC有一個(gè)獨(dú)立的自動(dòng)重加載喚醒定時(shí)器可用于產(chǎn)生喚醒事件和中斷。

輸入圖片說(shuō)明

? 鬧鐘

RTC鬧鐘功能被劃分為多個(gè)位域并且每一個(gè)位域有一個(gè)該域的可屏蔽位。屏蔽某些位域后可固定周期產(chǎn)生鬧鐘事件。

? 侵入事件

RTC_TAMPx管腳可以作為侵入事件檢測(cè)功能輸入管腳,檢測(cè)模式有兩種可供用戶選擇:邊沿檢測(cè)模式或者是帶可配置濾波功能的電平檢測(cè)模式。侵入事件會(huì)將備份域復(fù)位,可產(chǎn)生一個(gè)中斷。

? 可選的RTC輸出功能:

512Hz(默認(rèn)預(yù)分頻值):(RTC_OUT)PC13

1Hz(默認(rèn)預(yù)分頻值):(RTC_OUT)PC13

鬧鐘事件(極性可配置):(RTC_OUT)PC13

自動(dòng)喚醒事件(極性可配置):(RTC_OUT)PC13

? 可選的RTC輸入功能:

時(shí)間戳事件檢測(cè)(RTC_TS):RTC_AF0、RTC_AF1;

侵入事件檢測(cè) 0(RTC_TAMP0):RTC_AF0、RTC_AF1;

侵入事件檢測(cè) 1(RTC_TAMP1):RTC_AF1;

參考時(shí)鐘輸入 RTC_REFIN(50或60Hz)。

? RTC中斷

所有的RTC中斷(鬧鐘0、鬧鐘1、喚醒、時(shí)間戳、侵入0、侵入1)都被連接到EXTI控制器。

各系列 RTC 模塊功能對(duì)比

x0系列中的E23x系列均沒(méi)有VBAT引腳,不支持VDD掉電保持RTC工作。

0x系列備份域不同于x0、4xx系列,為單獨(dú)的一個(gè)外設(shè)模塊,所以使用RTC時(shí),0x系列相比x0系列和4xx系列還需使能BKP的時(shí)鐘。

各系列 RTC 模塊功能對(duì)比

輸入圖片說(shuō)明

14.2.GD32 RTC 硬件設(shè)計(jì)

? Vbat電源設(shè)計(jì)

Vbat可以連接至外部電池,在Vdd掉電時(shí)可以保證備份域不掉電、RTC繼續(xù)運(yùn)行。VBAT引腳需要對(duì)GND連接0.1uF電容,如果沒(méi)有外部電池需要將VBAT和一個(gè)0.1uF電容連接至Vdd電源上。

輸入圖片說(shuō)明

? RTC_TAMPx引腳

入侵事件會(huì)導(dǎo)致備份域復(fù)位,如使用該功能需注意檢測(cè)引腳的濾波,可在RTC_TAMPx引腳上并聯(lián)0.1uf電容。

14.3.GD32 RTC 軟件配置

GD32MCU_Example下的RTC_Example例程配置了日歷和鬧鐘功能,并開(kāi)啟了鬧鐘中斷。本小節(jié)講解RTC_Example例程中RTC模塊的配置說(shuō)明,主要包括時(shí)鐘及分頻配置、日歷配置、鬧鐘配置、主函數(shù)說(shuō)明。本例程主要介紹GD32 MCU各系列RTC模塊的時(shí)間、鬧鐘配置,有關(guān)RTC其他功能例程可參考各系列固件庫(kù)例程。

時(shí)鐘及分頻配置

? 由于RTC工作在備份域,所以使用RTC時(shí)需要使能備份域?qū)懝δ?,而控制備份域?qū)懝δ艿募拇嫫魑挥赑MU中,所以操作RTC還需要將PMU_CTL寄存中的BKPWEN置位,從而還需使能PMU的時(shí)鐘。而對(duì)于0x系列備份域?yàn)閱为?dú)的外設(shè),還需額外使能BKP備份域時(shí)鐘。

? 為了實(shí)現(xiàn)準(zhǔn)確的日歷功能,配置RTC前需要準(zhǔn)備好需要的時(shí)鐘源,在選擇合適的時(shí)鐘源后RTC還需要進(jìn)行預(yù)分頻的配置。

0x系列時(shí)鐘及分頻配置如代碼清單 RTC 0x系列時(shí)鐘及分頻配置所示,RTC使能后需要等待RTC寄存器和APB1時(shí)鐘同步,執(zhí)行rtc_register_sync_wait()函數(shù);此外0x系列RTC在RTC寄存器配 置時(shí)需要等待上一次配置結(jié)束才能繼續(xù)新的配置,所以在每個(gè)寄存器配置前需要執(zhí)行rtc_lwoff_wait()函數(shù),等待LWOFF置位。

代碼清單 RTC 0x 系列時(shí)鐘及分頻配置

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系列時(shí)鐘及分頻配置如代碼清單 RTC x0系列時(shí)鐘及分頻配置所示,RTC使能后需要等待RTC寄存器和APB1時(shí)鐘同步,執(zhí)行rtc_register_sync_wait()函數(shù);和0x系列不同,后續(xù)配置過(guò)程x0和4xx系列均不需要執(zhí)行rtc_lwoff_wait()函數(shù)。

代碼清單 RTC x0 系列時(shí)鐘及分頻配置

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系列時(shí)鐘及分頻配置如代碼清單 RTC 4xx系列時(shí)鐘及分頻配置所示,和x0系列基本相同,但由于4xx系列內(nèi)部低速時(shí)鐘為32K,所以分頻系數(shù)和x0系列有所不同。

代碼清單 RTC 4xx 系列時(shí)鐘及分頻配置

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系列由于沒(méi)有硬件日歷功能,所以需要讀取計(jì)數(shù)器通過(guò)軟件計(jì)算出日歷;而x0系列和4xx系列具有硬件日歷功能,日期信息均是BCD碼,所以在日歷配置的格式和方式均有差別。

0x系列RTC的日歷配置如代碼清單 RTC 0x系列日歷配置所示,該函數(shù)提供了日歷配置的入口參數(shù),先將需要配置的日歷信息轉(zhuǎn)換成秒單位,再寫(xiě)入RTC計(jì)數(shù)器即可。入口參數(shù)使用十進(jìn)制寫(xiě)入。

代碼清單 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系列日歷配置所示,該函數(shù)提供了日歷配置的入口參數(shù),參數(shù)為BCD碼格式,寫(xiě)入后對(duì)RTC日歷結(jié)構(gòu)體賦初值,日歷結(jié)構(gòu)體還可以配置星期、時(shí)間格式等,這里默認(rèn)配置了24小時(shí)制。函數(shù)入口參數(shù)使用16進(jìn)制寫(xiě)入。

代碼清單 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系列基本相同, 唯一區(qū)別只是日歷結(jié)構(gòu)體成員名字少了“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通過(guò)32位計(jì)數(shù)器運(yùn)行時(shí)間,所以其鬧鐘也是32位數(shù)據(jù),當(dāng)計(jì)數(shù)器和鬧鐘值匹配時(shí)會(huì)產(chǎn)生鬧鐘事件或中斷,所需配置的鬧鐘值為鬧鐘剩余倒計(jì)時(shí)加上當(dāng)前計(jì)數(shù)器值;而x0系列和4xx系列是硬件BCD日歷功能,所以其鬧鐘也是BDC格式,且具有位域屏蔽功能,根據(jù)需要直接配置具體的時(shí)間即可。

0x系列RTC的鬧鐘配置如代碼清單 RTC 0x系列鬧鐘配置所示,該函數(shù)提供了鬧鐘配置的入口參數(shù),先將需要配置的時(shí)間信息轉(zhuǎn)換成秒單位,再加上當(dāng)前計(jì)數(shù)器的值寫(xiě)入鬧鐘寄存器即可。

0x系列配置的鬧鐘參數(shù)為鬧鐘中斷的倒計(jì)時(shí)時(shí)間,寫(xiě)入?yún)?shù)為十進(jìn)制。

代碼清單 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系列鬧鐘配置所示,該函數(shù)提供了鬧鐘配置的入口參數(shù),參數(shù)為BCD碼格式,寫(xiě)入后對(duì)RTC鬧鐘結(jié)構(gòu)體賦初值,鬧鐘結(jié)構(gòu)體可以配置位域屏蔽、選擇配置日期或星期、時(shí)間格式等,這里默認(rèn)配置了屏蔽天、小時(shí)、分鐘,所以配置最后實(shí)際生效的只有秒,所以配置后鬧鐘均是1分鐘產(chǎn)生一次。鬧鐘配置前需失能鬧鐘,配置后再使能,4xx系列配置的鬧鐘參數(shù)為鬧鐘產(chǎn)生的日期時(shí)間,因BCD格式寫(xiě)入?yún)?shù)參數(shù)使用16進(jìn)制。

代碼清單 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系列基本相同, 唯一區(qū)別只是鬧鐘結(jié)構(gòu)體成員名字少了“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; }

主函數(shù)說(shuō)明 主函數(shù)如代碼清單 RTC_Example主函數(shù)所示,主要包含了中斷配置、RTC時(shí)鐘源和預(yù)分頻配置、日歷設(shè)置以及鬧鐘設(shè)置,成功設(shè)置好日歷和鬧鐘后在備份域數(shù)據(jù)寄存器寫(xiě)入一個(gè)標(biāo)志位,下次非備份域復(fù)位的情況就可以不再重復(fù)配置RTC。While1中循環(huán)調(diào)用rtc_current_time_get()函數(shù)獲取日歷信息。4xx系列和x0系列中固件庫(kù)底層已經(jīng)提供了rtc_current_time_get()函數(shù),直接更新至日歷結(jié)構(gòu)體;而0x系列固件庫(kù)沒(méi)有此函數(shù),額外編寫(xiě)了相同接口的函數(shù),通過(guò)讀取32位計(jì)數(shù)器軟件計(jì)算出日歷信息更新至自定義的日歷結(jié)構(gòu)體中。通過(guò)仿真或串口打印可以看到結(jié)構(gòu)體中的時(shí)間數(shù)據(jù)在更新。

代碼清單 RTC_Example 主函數(shù)

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()主函數(shù)

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; }

鬧鐘中斷說(shuō)明

例程中開(kāi)啟了鬧鐘中斷,初始化調(diào)用rtc_alarm_set(uint8_t hour, uint8_t minute, uint8_t second)函數(shù)分別配置了“0時(shí)0分5秒”的鬧鐘。

? 對(duì)0x系列來(lái)說(shuō)這個(gè)配置是倒計(jì)時(shí)“0時(shí)0分5秒”后產(chǎn)生鬧鐘,進(jìn)入鬧鐘中斷后再配置新的5s實(shí)現(xiàn)5s一次的鬧鐘周期;

? 對(duì)x0和4xx系列這個(gè)配置是時(shí)間在“0時(shí)0分5秒”時(shí)產(chǎn)生鬧鐘,但因?yàn)轸[鐘配置中已經(jīng)屏蔽了鬧鐘的天、時(shí)、分位域,所以鬧鐘會(huì)在每分鐘的5秒產(chǎn)生,鬧鐘周期為一分鐘產(chǎn)生一次。

14.4.RTC 使用注意事項(xiàng)

1、 因?yàn)閮?nèi)部低速時(shí)鐘是在VDDA電源域,所以VDD斷電后VBAT供電情況下保持RTC運(yùn)行需要使用外部低速時(shí)鐘;此外使用LXTAL在非備份域復(fù)位時(shí)可以不用在初始化階段配置,但使用內(nèi)部低速時(shí)鐘需要每次復(fù)位都進(jìn)行內(nèi)部時(shí)鐘的初始化。

2、 內(nèi)部低速時(shí)鐘精度相對(duì)較差,如必須使用內(nèi)部且對(duì)精度有一定要求,4xx和0x系列可以使用TIMER4、x0系列可以使用TIMER13捕獲內(nèi)部低速時(shí)鐘,計(jì)算出實(shí)際的頻率值來(lái)進(jìn)行合適分頻。

3、 日歷信息意外被清零的話注意是否發(fā)生過(guò)備份域復(fù)位,是否有Vbat掉電或入侵事件發(fā)生。

4、 調(diào)試中如果修改了RTC代碼的配置,請(qǐng)先擦除全片F(xiàn)lash,然后斷電并上電后再下載新的代碼。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 單片機(jī)
    +關(guān)注

    關(guān)注

    6037

    文章

    44558

    瀏覽量

    635284
  • 嵌入式
    +關(guān)注

    關(guān)注

    5082

    文章

    19126

    瀏覽量

    305184
  • 開(kāi)發(fā)板
    +關(guān)注

    關(guān)注

    25

    文章

    5050

    瀏覽量

    97468
  • RTC
    RTC
    +關(guān)注

    關(guān)注

    2

    文章

    538

    瀏覽量

    66527
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    GD32 MCU 入門(mén)教程GD32 MCU 常見(jiàn)外設(shè)介紹(12)FMC 模塊介紹

    閃存控制器(FMC),提供了片上閃存需要的所有功能。FMC 也提供了頁(yè)擦除,整片擦除,以及32 位整字或 16 位半字編程閃存等操作。 GD32 MCU 支持不同類型編程的具體說(shuō)明如下表 GD32
    的頭像 發(fā)表于 08-21 09:56 ?1126次閱讀
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>常見(jiàn)外設(shè)</b><b class='flag-5'>介紹</b>(12)FMC <b class='flag-5'>模塊</b><b class='flag-5'>介紹</b>

    GD32 MCU移植

    gd32是一款國(guó)產(chǎn)單片機(jī)。該芯片在很多方面和STM32有異曲同工之處。資料不是很多! GD32外設(shè)方面、和STM32沒(méi)有多大區(qū)別。 只是需要注意資源的引腳分配。雖然和STM32使用方式一樣、但是也存在
    發(fā)表于 03-23 13:40

    GD32MCU介紹

    其實(shí)兆芯的MCU為了兼容ST,外設(shè)的寄存器設(shè)計(jì)與ST保持一致了。比如GD32VF103或者GD32E103系列的USBFS這個(gè)外設(shè),基本等同
    發(fā)表于 11-01 06:03

    GD32 MCU原理及固件庫(kù)開(kāi)發(fā)指南》 + 初讀感悟

    GD32 MCU原理固件庫(kù)開(kāi)發(fā)指南這本書(shū)內(nèi)容豐富,囊括了GD32中的所有外設(shè),書(shū)中首先介紹了如何使用MDK或IAR軟件搭建
    發(fā)表于 03-31 22:11

    GD32 MCU原理及固件庫(kù)開(kāi)發(fā)指南》+讀后感

    GD32 MCU的電源管理系統(tǒng)及復(fù)位、時(shí)鐘系統(tǒng)。 第5章介紹GD32 MCU的基礎(chǔ)外設(shè),包括GP
    發(fā)表于 06-06 21:52

    兆易創(chuàng)新GD32 MCU選型手冊(cè),適用于GD32全系列MCU

    兆易創(chuàng)新GD32MCU選型手冊(cè),適用于GD32全系列MCUGD32MCU選型手冊(cè),適用于GD32全系列MCU
    發(fā)表于 10-19 17:26 ?49次下載

    你了解GD32 MCU的命名規(guī)則嗎

    下面為大家介紹GD32 MCU的通用命名規(guī)則,以GD32F303ZGT6為例,其中,GD32代表GD32
    的頭像 發(fā)表于 01-13 09:38 ?3648次閱讀
    你了解<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的命名規(guī)則嗎

    GD32 MCU的選項(xiàng)字節(jié)是什么?

    GD32 MCU的選項(xiàng)字節(jié)是什么,有什么功能呢?選項(xiàng)字節(jié)被誤篡改如何回復(fù)?
    的頭像 發(fā)表于 01-17 09:42 ?1384次閱讀
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的選項(xiàng)字節(jié)是什么?

    不同型號(hào)的GD32 MCU如何區(qū)分?

    大家是否碰到過(guò)以下應(yīng)用場(chǎng)景:同一套軟件代碼希望跑在不同型號(hào)的GD32 MCU中,但有些地方需要根據(jù)MCU型號(hào)進(jìn)行調(diào)整?或者上位機(jī)或其他MCUGD3
    的頭像 發(fā)表于 01-27 09:32 ?1003次閱讀
    不同型號(hào)的<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>如何區(qū)分?

    GD32 MCU 入門(mén)教程】一、GD32 MCU 開(kāi)發(fā)環(huán)境搭建(1)使用Keil開(kāi)發(fā)GD32

    GD32系列為通用型MCU,所以開(kāi)發(fā)環(huán)境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據(jù)個(gè)人喜好來(lái)選擇相應(yīng)的開(kāi)發(fā)環(huán)境。
    的頭像 發(fā)表于 08-08 15:01 ?1196次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開(kāi)發(fā)環(huán)境搭建(1)使用Keil開(kāi)發(fā)<b class='flag-5'>GD32</b>

    GD32 MCU 入門(mén)教程】一、GD32 MCU 開(kāi)發(fā)環(huán)境搭建(2)使用 IAR 開(kāi)發(fā) GD32

    GD32系列為通用型MCU,所以開(kāi)發(fā)環(huán)境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據(jù)個(gè)人喜好來(lái)選擇相應(yīng)的開(kāi)發(fā)環(huán)境。
    的頭像 發(fā)表于 08-08 15:40 ?700次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開(kāi)發(fā)環(huán)境搭建(2)使用 IAR 開(kāi)發(fā) <b class='flag-5'>GD32</b>

    GD32 MCU 入門(mén)教程】一、GD32 MCU 開(kāi)發(fā)環(huán)境搭建(3)使用 Embedded Builder 開(kāi)發(fā) GD32

    GD32系列為通用型MCU,所以開(kāi)發(fā)環(huán)境也可以使用通用型的IDE,目前使用較多的是KEIL、IAR、 GCC和Embedded Builder,客戶可以根據(jù)個(gè)人喜好來(lái)選擇相應(yīng)的開(kāi)發(fā)環(huán)境。
    的頭像 發(fā)表于 08-08 16:03 ?974次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 開(kāi)發(fā)環(huán)境搭建(3)使用 Embedded Builder 開(kāi)發(fā) <b class='flag-5'>GD32</b>

    GD32 MCU 入門(mén)教程】二、GD32 MCU 燒錄說(shuō)明(1)ISP 燒錄

    ISP:In System Programing,在系統(tǒng)編程,通過(guò)MCU片內(nèi)的引導(dǎo)程序進(jìn)行Flash編程。 GD32片內(nèi)有一個(gè)只讀信息塊,用于存放引導(dǎo)裝載程序,引導(dǎo)程序在MCU出廠前就會(huì)提前燒錄好
    的頭像 發(fā)表于 08-08 16:20 ?936次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】二、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 燒錄說(shuō)明(1)ISP 燒錄

    GD32 MCU 入門(mén)教程GD32 MCU FPU 使用方法

    GD32 MCU FPU 使用方法
    的頭像 發(fā)表于 08-25 09:24 ?600次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入門(mén)教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> FPU 使用方法

    GD32 MCU入門(mén)教程GD32 MCU GPIO 結(jié)構(gòu)與使用注意事項(xiàng)

    本文是專門(mén)為基于GD32 MCU開(kāi)發(fā)的工程設(shè)計(jì)人員提供,主要介紹了GPIO的功能配置、內(nèi)部結(jié)構(gòu)以及在不同場(chǎng)景使用時(shí)的注意事項(xiàng),旨在幫助GD32 MC
    的頭像 發(fā)表于 09-07 10:34 ?738次閱讀
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b><b class='flag-5'>入門(mén)教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> GPIO 結(jié)構(gòu)與使用注意事項(xiàng)