眾所周知,時(shí)鐘是MCU能正常運(yùn)行的基本條件,就好比心跳或脈搏,為所有的工作單元提供時(shí)間 基數(shù)。時(shí)鐘控制單元提供了一系列頻率的時(shí)鐘功能,包括多個(gè)內(nèi)部RC振蕩器時(shí)鐘(IRC)、一個(gè)外部 高速晶體振蕩器時(shí)鐘(HXTAL)、一個(gè)外部低速晶體振蕩器時(shí)鐘(LXTAL)、一個(gè)或多個(gè)鎖相環(huán)(PLL) 一個(gè)HXTAL時(shí)鐘和LXTAL時(shí)鐘監(jiān)視器、時(shí)鐘預(yù)分頻器、時(shí)鐘多路復(fù)用器和時(shí)鐘門控電路等。 本章,我們將通過一個(gè)“輸出HXTAL時(shí)鐘信號(hào)” 的實(shí)驗(yàn)來熟悉RCU的工作流程。
1.1RCU 配置
GD32系列MCU在啟動(dòng)后首先會(huì)執(zhí)行Reset Handler,緊接著就會(huì)執(zhí)行SystemInit()函數(shù),而時(shí)鐘的初始化,就是在這個(gè)函數(shù)中進(jìn)行,其主要的功能是配置系統(tǒng)時(shí)鐘CK_SYS(即主頻),AHB、APB1以及APB2時(shí)鐘。SystemInit()函數(shù)由GD32官方庫(kù)提供,不同系列的MCU有一些差別,但實(shí)現(xiàn)方式基本相同:首先將RCU關(guān)于CK_SYS,AHB、APB1以及APB2時(shí)鐘配置的一些寄存器恢復(fù)到默認(rèn)值,然后再執(zhí)行system_clock_config()函數(shù),用于具體的時(shí)鐘配置。
實(shí)際上用戶可以不用過于關(guān)心上述的實(shí)現(xiàn)方式,因?yàn)镚D32庫(kù)已經(jīng)為您提供了多種時(shí)鐘源及時(shí)鐘選擇,您只需按照以下步驟即可將時(shí)鐘設(shè)置為您期望的值(以GD32F30x為例,其他系列類似):
(1) 在system_gd32f30x.c中,用戶可通過選擇宏來進(jìn)行預(yù)設(shè)的時(shí)鐘配置,如下圖代碼清單時(shí)鐘配置選擇宏定義,選擇了HXTAL作為PLL時(shí)鐘源,且配置CK_SYS為120MHz。
/* system frequency define */ #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ /* select a system clock by uncommenting the following line */ /* use IRC8M */ //#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M) //#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000) //#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000) //#define __SYSTEM_CLOCK_120M_PLL_IRC8M (uint32_t)(120000000) /* use HXTAL(XD series CK_HXTAL = 8M, CL series CK_HXTAL = 25M) */ //#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) //#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) //#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000) #define __SYSTEM_CLOCK_120M_PLL_HXTAL (uint32_t)(120000000)
但這種情況下您使用的外部晶振需要是默認(rèn)值,此值由HXTAL_VALUE定義,如為8000000,那么您應(yīng)該選擇8MHz的外部晶振。
當(dāng)然,您可以使用其他規(guī)格的外部晶振,這種情況下就需要去修改RCU配置函數(shù)里面的一些參數(shù),主要是分頻和倍頻系數(shù),以達(dá)到期望的配置,具體如何修改,可以結(jié)合GD32的User manual中定義的RCU寄存器來對(duì)配置函數(shù)進(jìn)行分析。
(2) 設(shè)置HXTAL_VALUE的值。
此數(shù)值和RCU的初始化其實(shí)并沒有太大關(guān)系,但如果您使用的外部晶振不是默認(rèn)值,那么除了按照步驟(1)修改配置參數(shù)外,您還必須將此HXTAL_VALUE的值修改為實(shí)際的外部晶振頻率,這是因?yàn)樵谝恍?a target="_blank">通信外設(shè)配置時(shí),庫(kù)函數(shù)會(huì)調(diào)用HXTAL_VALUE值來設(shè)置波特率,如此值設(shè)置錯(cuò)誤,會(huì)導(dǎo)致通信異常。
1.2.非默認(rèn)外部晶振配置時(shí)鐘實(shí)例
GD32各系列固件庫(kù)都已提供配置系統(tǒng)時(shí)鐘的函數(shù)。需要注意的是,在使用外部晶振時(shí),固件庫(kù)中HXTAL_VALUE值規(guī)定了 外部晶振的默認(rèn)值,以 GD32F30x系列為例,如下圖代碼清單HXTAL_VALUE選擇宏定義所示,當(dāng)芯片為非互聯(lián)型(GD32F303)時(shí),默認(rèn)使用的外部晶振頻率為8MHz,當(dāng)芯片為互聯(lián)型(GD32F305/307)時(shí),默認(rèn)使用的外部晶振頻率為25MHz。
#ifdef GD32F30X_CL #define HXTAL_VALUE ((uint32_t)25000000) #else #define HXTAL_VALUE ((uint32_t)8000000)
那么,當(dāng)我們使用非默認(rèn)值的外部晶振時(shí),該如何修改時(shí)鐘配置函數(shù)呢?以GD32F303為例,首先我們先看下GD32F303的時(shí)鐘樹,如圖所示。

預(yù)分頻器可以配置AHB、APB2和APB1域的時(shí)鐘頻率。 AHB、APB2、APB1域的最高時(shí)鐘頻率分別為120MHz、120MHz、60MHz。RCU通過AHB時(shí)鐘(HCLK)8分頻后作為Cortex系統(tǒng)定時(shí)器(SysTick)的外部時(shí)鐘。通過對(duì)SysTick控制和狀態(tài)寄存器的設(shè)置,可選擇上述時(shí)鐘或AHB(HCLK)時(shí)鐘作為SysTick時(shí)鐘。
ADC時(shí)鐘由APB2時(shí)鐘經(jīng)2、4、6、8、12、16分頻或由AHB時(shí)鐘經(jīng)5、6、10、20分頻獲得,它們是通過設(shè)置RCU_CFG0和RCU_CFG1寄存器的ADCPSC位來選擇。
SDIO, EXMC的時(shí)鐘由CK_AHB提供。
TIMER時(shí)鐘由CK_APB1和CK_APB2時(shí)鐘分頻獲得,如果APBx(x=0,1)的分頻系數(shù)不為1,則TIMER時(shí)鐘為CK_APBx(x=0,1)的兩倍。
USBD的時(shí)鐘由CK48M時(shí)鐘提供。通過配置 RCU_ADDCTL寄存器的CK48MSEL及PLL48MSEL位可以選擇CK_PLL時(shí)鐘或IRC48M時(shí)鐘做為CK48M的時(shí)鐘源。
CTC時(shí)鐘由IRC48M時(shí)鐘提供,通過CTC單元,可以實(shí)現(xiàn)IRC48M時(shí)鐘精度的自動(dòng)調(diào)整。
I2S的時(shí)鐘由CK_SYS提供。
通過配置RCU_BDCTL寄存器的RTCSRC位, RTC時(shí)鐘可以選擇由LXTAL時(shí)鐘、IRC40K時(shí)鐘或HXTAL時(shí)鐘的128分頻提供。RTC時(shí)鐘選擇HXTAL時(shí)鐘的128分頻做為時(shí)鐘源后,當(dāng)1.2V內(nèi)核電壓域掉電時(shí),時(shí)鐘將停止。 RTC時(shí)鐘選擇IRC40K時(shí)鐘做為時(shí)鐘源后,當(dāng)VDD掉電時(shí),時(shí)鐘將停止。
RTC時(shí)鐘選擇LXTAL時(shí)鐘做為時(shí)鐘源后,當(dāng)VDD和VBAT都掉電時(shí),時(shí)鐘將停止。
當(dāng)FWDGT啟動(dòng)時(shí), FWDGT時(shí)鐘被強(qiáng)制選擇由IRC40K時(shí)鐘做為時(shí)鐘源。
現(xiàn)在,我們結(jié)合圖GD32F303系統(tǒng)時(shí)鐘樹對(duì)時(shí)鐘樹進(jìn)行分析:
(1) 標(biāo)注A為CK_SYS,即系統(tǒng)主時(shí)鐘,它一條線連接至CK_I2S,給I2S外設(shè)提供時(shí)鐘,另一條線經(jīng)過AHB分頻器,輸出到CK_AHB,即標(biāo)注B。
(2) CK_AHB為AHB總線時(shí)鐘,AHB總線時(shí)鐘或直連,或經(jīng)過APB1/APB2分頻,給標(biāo)注C位置的外設(shè)提供時(shí)鐘。
(3) 那么,CK_SYS從何而來呢,我們看標(biāo)注A的左邊,CK_SYS通過SCS位域選擇CK_IRC8M、CK_PLL、CK_HXTAL作為時(shí)鐘來源,其中CK_IRC8M來源于標(biāo)注D,即IRC8M(MCU內(nèi)部8M RC時(shí)鐘);CK_HXTAL來源于標(biāo)注F,即HXTAL(外部時(shí)鐘);CK_PLL的來源較復(fù)雜,我們單獨(dú)拿出來說。
(4) CK_PLL來源于鎖相環(huán)倍頻器輸出,倍頻系數(shù)通過PLLMF位域選擇,而PLLMF來源于兩個(gè)地方,一個(gè)為 IRC8M 的 2 分 頻 , 另 外 一 個(gè) 為 預(yù) 分 頻 器 PREDV0 , 而 PREDV0 來 源 于 標(biāo) 注 E, 即CK_IRC48M(內(nèi)部48M RC時(shí)鐘)和標(biāo)注F,即HXTAL(外部高速時(shí)鐘)。
(5) 通過以上分析可以得出結(jié)論,CK_PLL的時(shí)鐘源為D:IRC8M、E:IRC48M、F:HXTAL,用戶通過相關(guān)寄存器設(shè)置選擇時(shí)鐘線。
(6) 和前面分析相同,RTC的時(shí)鐘來自于F:HXTAL的128分頻、G:LXTAL(外部32.768K低速時(shí)鐘)、F:IRC40K(內(nèi)部40K RC時(shí)鐘);FWDGT的時(shí)鐘來源于F:IRC40K。
(7) 標(biāo)注I位置為時(shí)鐘輸出線,它的作用是將MCU內(nèi)部的一些時(shí)鐘信號(hào)線輸出到特定IO口上(大部分系列MCU的PA8口都可被設(shè)置為時(shí)鐘輸出口0,有些系列MCU含有兩組輸出IO,具體IO配置請(qǐng)參考各系列MCU Datasheet)用來給其他器件提供基準(zhǔn)時(shí)鐘。由圖中可看出通過設(shè)置位域CK_OUT0,輸出的時(shí)鐘包括CK_PLL、CK_IRC8M、CK_HXTAL、CK_PLL的2分頻。
結(jié)合以上分析,我們來看下GD32F30x固件庫(kù)時(shí)鐘配置函數(shù)(因篇幅有限,只貼出各分頻和倍頻配置部分),還是以GD32F303芯片為例,如下圖代碼清單時(shí)鐘配置部分代碼所示:
/* select HXTAL/2 as clock source */ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0); RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0); /* CK_PLL = (CK_HXTAL/2) * 30 = 120 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5); RCU_CFG0 |= RCU_PLL_MUL30;
可以看出,8MHz的HXTAL經(jīng)過預(yù)分頻器PREDV0分頻成4MHz,再通過鎖相環(huán)PLL倍頻30倍到了120MHz。
那么,當(dāng)您選擇其他規(guī)格的外部晶振,比如12MHz,則可以先通過預(yù)分頻器PREDV0分頻成6MHz,再通過鎖相環(huán)PLL倍頻20倍即可,如代碼清單 0-4. 使用12MHz外部晶振配置120M系統(tǒng)時(shí)鐘所示。
/* select HXTAL/2 as clock source */ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0); RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0); /* CK_PLL = (CK_HXTAL/2) * 20 = 120 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5); RCU_CFG0 |= RCU_PLL_MUL20;
當(dāng)然,在修改完配置函數(shù)后,別忘了將HXTAL_VALUE值改為12000000。
需要注意的是,在進(jìn)行時(shí)鐘配置時(shí),要嚴(yán)格按照Datasheet中規(guī)定的時(shí)鐘范圍進(jìn)行配置,如GD32F303的 HXTAL的選 擇范 圍是4~32MHz, PLL的輸 入范 圍是 1~25MHz,輸出范圍是16~120Mhz,所以當(dāng)使用32MHz的外部晶振時(shí),不進(jìn)行預(yù)分頻,而直接倍頻是不被允許的。
1.3.硬件連接說明
本章通過“輸出HXTAL時(shí)鐘信號(hào)”實(shí)驗(yàn)來熟悉RCU的工作流程。
通過前面內(nèi)容講解可知,本章實(shí)驗(yàn)為“輸出HXTAL時(shí)鐘信號(hào)”,即通過PA8口將HXTAL輸出,我們使用示波器,將探頭連接到PA8口,從示波器上讀取PA8口波形即可。
1.4.軟件配置說明
本小節(jié)講解RCU_Example例程中RCU的配置說明,主要包括外設(shè)時(shí)鐘配置、GPIO引腳配置、主函數(shù)介紹以及運(yùn)行結(jié)果。
軟件設(shè)計(jì)的流程如下:
(1)使能GPIOA時(shí)鐘
(2)初始化PA8,將此端口設(shè)置為備用功能模式(AFIO)
(3)通過調(diào)用庫(kù)函數(shù)選擇HXTAL作為PA8時(shí)鐘信號(hào)源
外設(shè)時(shí)鐘配置
void rcu_config(void) { /* enable the GPIOA clock */ rcu_periph_clock_enable(RCU_GPIOA); }
GPIO 引腳配置
代碼清單 0-6. RCU 例程引腳配置
void gpio_config(void) { /* configure PA8 port */ #if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); #elif GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X gpio_mode_set(GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8); gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_8); #endif }
GPIO的配置說明,請(qǐng)參考GPIO章節(jié)。
主函數(shù)說明
代碼清單 0-7 . RCU 例程主函數(shù)
int main(void) { rcu_config(); gpio_config(); #if defined GD32F10X_HD || GD32F30X_HD || GD32E10X rcu_ckout0_config(RCU_CKOUT0SRC_HXTAL); #elif defined GD32F20X_CL || GD32F4XX rcu_ckout0_config(RCU_CKOUT0SRC_HXTAL,RCU_CKOUT0_DIV1); #elif GD32F1X0 || GD32F3X0 || GD32E23X rcu_ckout_config(RCU_CKOUTSRC_HXTAL,RCU_CKOUT_DIV1); #endif while(1){ } }
如代碼清單RCU例程主函數(shù),該主函數(shù)主要分成四部分,RCU時(shí)鐘配置、GPIO配置、RCU輸出相關(guān)庫(kù)函數(shù)調(diào)用和while(1)主循環(huán),其中RCU輸出相關(guān)庫(kù)函數(shù)請(qǐng)讀者結(jié)合各系列MCU Datasheet、User Manual進(jìn)行RCU例程的分析。
注意:因?yàn)槭禽敵鯤XTAL,所以必須要使能HXTAL,否則PA8將無波形輸出。一個(gè)簡(jiǎn)單的辦法是將HXTAL作為CK_SYS時(shí)鐘源,請(qǐng)參考本章第一節(jié)內(nèi)容。
1.5.運(yùn)行結(jié)果
如圖所示 RCU 例程運(yùn)行結(jié)果為 RCU 例程運(yùn)行結(jié)果,可看出,PA8 口正確輸出了 HXTAL 波形。

本教程由GD32 MCU方案商聚沃科技原創(chuàng)發(fā)布,了解更多GD32 MCU教程,關(guān)注聚沃科技官網(wǎng)
-
單片機(jī)
+關(guān)注
關(guān)注
6067文章
44969瀏覽量
649198 -
mcu
+關(guān)注
關(guān)注
146文章
17933瀏覽量
363191 -
嵌入式
+關(guān)注
關(guān)注
5147文章
19616瀏覽量
316465 -
時(shí)鐘樹
+關(guān)注
關(guān)注
0文章
56瀏覽量
11025 -
rcu
+關(guān)注
關(guān)注
0文章
21瀏覽量
5608
發(fā)布評(píng)論請(qǐng)先 登錄
GD32 MCU 入門教程】GD32 MCU 常見外設(shè)介紹(12)FMC 模塊介紹

GD32的MCU介紹
《GD32 MCU原理及固件庫(kù)開發(fā)指南》 + 初讀感悟
《GD32 MCU原理及固件庫(kù)開發(fā)指南》+讀后感
兆易創(chuàng)新GD32 MCU選型手冊(cè),適用于GD32全系列MCU
不同型號(hào)的GD32 MCU如何區(qū)分?

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

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

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

【GD32 MCU 入門教程】二、GD32 MCU 燒錄說明(1)ISP 燒錄

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

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

評(píng)論