1.1實驗內容
通過本實驗主要學習以下內容:
- RCU時鐘原理及配置;
- RCU時鐘輸出驗證。
1.2實驗原理
1.2.1RCU時鐘樹原理
GD32F303系列MCU的時鐘樹如下圖所示,由該圖可知,GD32F303系列MCU的時鐘樹可大致分為三個部分:1、主系統時鐘以及外設時鐘配置,如下圖所示,GD32F303系列MCU最高主頻為120MHz(CK_SYS),該系統時鐘根據SCS[1:0]控制位進行選擇,可選擇來源于HSI8M、PLL或者HXTAL,PLL時鐘源可根據PLLSEL控制位選擇來自于HSI8M/2或者HXTAL以及HSI48M,之后經過2-63倍頻(PLLMF)得到PLL時鐘,PLL時鐘可以通過USB分頻輸出給USB模塊,系統時鐘會直接輸出給IIS外設使用,AHB時鐘可由系統時鐘分頻而來,AHB時鐘最高120M,AHB時鐘會輸出給內核以及外設使用;2、RTC以及獨立看門狗時鐘配置,如圖中2所示,RTC時鐘可選擇HXTAL/128分頻、LXTAL或者IRC40K,獨立看門狗僅可選擇IRC40K使用;3、時鐘輸出配置,如圖中3所示,內部系統時鐘、IRC8M、HXTAL以及PLL/2可通過CKOUT0SEL控制位控制輸出到CKOUT引腳。
1.2.2外部高速晶振原理
外部高速晶振可選擇4-32M時鐘,若系統應用中有異步通信以及高精度定時等應用建議選擇使用外部高速晶振,外部高速晶振具有更高的精度,在GD32F303應用系統中建議選擇8M/16M/24M晶振,因為外部晶振輸入給PLL的時鐘源僅可進行1分頻或者2分頻,選擇其他頻率的晶振難以配置到最高120M系統時鐘。
HXTAL具有時鐘監測的功能,置位CKMEN控制位將會使能該功能,使能后一旦監測到HXTAL失效,HXTAL將自動被禁止,中斷寄存器RCU_INT中的HXTAL時鐘阻塞中斷標志位CKMIF將被置‘1’,并產生NMI不可屏蔽中斷,使用者可在NMI中斷中切換到內部時鐘并重新進行時鐘配置,可用于HXTAL失效情況下的異常處理。 |
1.2.3內部高速時鐘原理
GD32F303系列MCU的內部高速時鐘有IRC8M和IRC48M,IRC8M較為常用,且具有更高的精度,另外需注意內部高速時鐘并非晶振,電路上為RC振蕩器,因而比較容易受外部環境的影響,如下圖所示,常溫下IRC8M的精度約為1%。
1.2.4內部低速時鐘原理
GD32F303系列MCU內部有IRC40K低速時鐘,該低速時鐘可以為RTC或FWDG使用,如下圖所示,據測試IRC40K精度較差,如果作為RTC時鐘源可能存在較大偏差的情況,如果使用者使用RTC建議可以選擇LXTAL外部低頻晶振,或者使用內部高速時鐘對IRC40K進行校準(校準方法為使用內部高速時鐘對IRC40K進行捕獲,然后調整IRC40K的trim值)。
1.2.5外部低速晶振原理
外部低速晶振一般選擇32.768KHZ的晶振,外部低速晶振可以選擇作為RTC時鐘,在這種情況下,RTC可以在VDD掉電以及VBAT不掉電的情況下工作。
1.2.6時鐘輸出功能
時鐘輸出功能可以輸出4-120MHz的時鐘,具體通過配置CKOUT0SEL控制位進行實現,另外需要將CKOUT引腳(一般為PA8引腳)配置為推挽輸出的模式,有關時鐘輸出選擇配置如下表所示。
1.3硬件設計
本節主要介紹開發板外掛高速晶振以及低速晶振電路。
1.3.1外部高速晶振電路設計
外部高速晶振電路如下圖所示,其中外部高速晶振選擇8MHZ,匹配電容選擇20pf,該匹配電容可以參考以下公式:C1=C2=2*(Cload-CS),其中Cload為晶體負載電容,Cs為PCB以及MCU引腳的雜散電容,典型值為10pf,因而可以選擇負載電容約為20pf的晶振,匹配電容即可選擇20pf,需要注意晶振盡量靠近MCU引腳擺放,且晶振引腳走線盡量等長,PCB區域盡量禁空,走線可以包地,另外若走線不等長,匹配電容可以適當選擇不同的匹配電容以適配不同的雜散電容。R28的1M歐姆為晶振引腳的反饋電阻,該反饋電阻的作用為減少晶振輸出波形的諧波分量,提高晶振穩定性,該電阻并非必須,MCU內部也有400K的反饋電阻,從筆者使用來看,并不影響晶振起振及使用,但建議電路上可以選擇保留。R29的100R電阻為晶振引腳串聯電阻,用于限流以及引腳保護。另外測量晶振引腳波形時可能存在OSC_IN腳波形為較好的正弦波,OSC_OUT引腳波形可能存在畸變,該現象為正?,F象,不影響使用,MCU內部使用的為OSC_IN引腳的波形,并通過內部整形方波供給MCU使用。
1.3.2外部低速晶振電路設計
外部低速晶振電路如下圖所示,外部低速晶振選擇32.768KHz,匹配電容選擇10pf,C1 = C2 = 2*(CLOAD - CS),其中CS為PCB和MCU引腳的雜散電容, 經驗值在2pF-7pF之間,建議以5pF為參考值計算。推薦選用外部晶體時,盡量選擇晶體負載電容在10pF左右的,這樣外部所接匹配電容C1和C2電容值為10pF即可,且PCB Layout時盡可能近地靠近晶振引腳。
1.4代碼解析
本節主要進行例程代碼解析,主要分成兩個部分:時鐘配置以及CKOUT時鐘輸出驗證。
1.4.1時鐘配置代碼解析
時鐘配置是一個MCU系統的基礎,讀者在開發MCU項目時需要首先明確當前系統所運行的主頻具體是多少,這樣才能夠準確的進行外設時鐘配置,定時器定時才會準確,ADC采樣率才會準確,通信的速率才會準確等等,系統超頻也會帶來不可預料的風險,因而建議開發者在開發初期就需要明確系統主頻配置,有條件的情況下可以通過定時或者時鐘輸出進行校驗。
本例程中時鐘配置函數代碼如以下所示,該代碼實現通過外部8M晶振進行PLL倍頻,實現120MHz主系統時鐘的功能。
C void rcu_system_clk_config_120M(void) { uint32_t timeout = 0U; uint32_t stab_flag = 0U; /* 使能外部8M晶振 */ RCU_CTL |= RCU_CTL_HXTALEN; /* 等待外部晶振ready,或者外部晶振未ready情況下超時退出 */ do{ timeout++; stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB); }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout)); /* 如果外部晶振未ready,程序卡死進入while(1),讀者若避免卡死可在此處切換到內部振蕩器使用 */ if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){ while(1){ } } RCU_APB1EN |= RCU_APB1EN_PMUEN; PMU_CTL |= PMU_CTL_LDOVS; /* AHB一分頻,系統時鐘等于AHB時鐘 */ RCU_CFG0 |= RCU_AHB_CKSYS_DIV1; /* APB2一分頻,APB2高速外設時鐘等于AHB時鐘 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; /* APB1 二分頻,APB1低速外設時鐘等于AHB時鐘/2 */ RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; /* 選擇HXTAL/2作為PLL時鐘源,開發板外部晶振為8M,即8/2=4M作為PLL時鐘源*/ 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_PLL_MUL30倍頻因子即可 */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5); RCU_CFG0 |= RCU_PLL_MUL30; /* 使能 PLL */ RCU_CTL |= RCU_CTL_PLLEN; /* 等待PLL Ready */ while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){ } /* 使能PLL高驅模式 */ PMU_CTL |= PMU_CTL_HDEN; while(0U == (PMU_CS & PMU_CS_HDRF)){ } /* 選擇PLL高驅模式 */ PMU_CTL |= PMU_CTL_HDS; while(0U == (PMU_CS & PMU_CS_HDSRF)){ } /* 選擇PLL作為系統時鐘 */ RCU_CFG0 &= ~RCU_CFG0_SCS; RCU_CFG0 |= RCU_CKSYSSRC_PLL; /* 等待PLL被選擇作為系統時鐘 */ while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){ } } |
如果讀者使用的是其他頻率的晶振,可以選擇修改PLL倍頻因子以及HXTAL的宏定義即可,比如若讀者選擇16MHz晶振,可以將歷程中RCU_PLL_MUL30的倍頻因子修改為RCU_PLL_MUL15,且將HXTAL_VALUE宏定義修改為16000000。 |
1.4.2CKOUT時鐘輸出代碼解析
CKOUT時鐘輸出配置代碼如下所示,該函數無形參輸入,首先將PA8配置為推挽輸出,然后將系統時鐘配置為CKOUT輸出。
C void ckout_config(void) { /* 以下兩句配置PA8作為推挽輸出,即作為CKOUT功能輸出 */ rcu_periph_clock_enable(RCU_GPIOA); gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_MAX,GPIO_PIN_8); /* 以下語句為配置系統時鐘輸出到CKOUT引腳,若希望輸出其他時鐘可以修改該函數形參, 在GD32F303上僅可以輸出以下時鐘:RCU_CKOUT0SRC_CKSYS,RCU_CKOUT0SRC_IRC8M,RCU_CKOUT0SRC_HXTAL,RCU_CKOUT0SRC_CKPLL_DIV2*/ rcu_ckout0_config(RCU_CKOUT0SRC_CKSYS); } |
1.4.3主函數代碼解析
本例程主函數如下所示,首先使用外部8M晶振倍頻配置系統時鐘為120MHZ,然后通過PA8將系統時鐘輸出。
C int main(void) { bsp_uart_init(&BOARD_UART); /* 板載UART初始化 */ printf("Example ofClock configuration and output.\r\n"); rcu_system_clk_config_120M(); /*使用外部8M晶振進行倍頻,將系統時鐘配置為120M*/ ckout_config(); /*通過PA8(CKOUT)將系統時鐘輸出*/ while (1) {} } |
1.5實驗結果
首先將PA8外接示波器,然后將本例程編譯通過后,燒錄到紅楓派開發板中,通過示波器可以觀察到系統時鐘輸出,如下圖所示,本例程中系統時鐘輸出為120MHz。
-
單片機
+關注
關注
6032文章
44525瀏覽量
633249 -
開發板
+關注
關注
25文章
4959瀏覽量
97214 -
GD32F3
+關注
關注
0文章
11瀏覽量
3842 -
rcu
+關注
關注
0文章
21瀏覽量
5440
發布評論請先 登錄
相關推薦
評論