GD32官方提供的固件库中使用的晶振配置一般为8M或25M,如果读者使用其他频率的晶振如何修改配置呢?本文为大家讲解如何修改。
 
以GD32F303为例,官方固件库中的晶振及时钟配置代码如下,改配置代码为使用外部8M晶振倍频到120M时钟。
 
| C/* 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)
 
 #if !defined  HXTAL_VALUE
 #ifdef GD32F30X_CL
 #define HXTAL_VALUE    ((uint32_t)25000000) /*!< value of the external oscillator in Hz */
 #else
 #define HXTAL_VALUE    ((uint32_t)8000000) /* !< from 4M to 32M *!< value of the external oscillator in Hz*/
 #endif /* HXTAL_VALUE */
 #endif /* high speed crystal oscillator value */
 
 static void system_clock_120m_hxtal(void)
 {
 uint32_t timeout = 0U;
 uint32_t stab_flag = 0U;
 
 /* enable HXTAL */
 RCU_CTL |= RCU_CTL_HXTALEN;
 
 /* wait until HXTAL is stable or the startup time is longer than HXTAL_STARTUP_TIMEOUT */
 do{
 timeout++;
 stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
 }while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
 
 /* if fail */
 if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
 while(1){
 }
 }
 
 RCU_APB1EN |= RCU_APB1EN_PMUEN;
 PMU_CTL |= PMU_CTL_LDOVS;
 
 /* HXTAL is stable */
 /* AHB = SYSCLK */
 RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
 /* APB2 = AHB/1 */
 RCU_CFG0 |= RCU_APB2_CKAHB_DIV1;
 /* APB1 = AHB/2 */
 RCU_CFG0 |= RCU_APB1_CKAHB_DIV2;
 
 #if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
 /* 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;
 
 #elif defined(GD32F30X_CL)
 /* CK_PLL = (CK_PREDIV0) * 30 = 120 MHz */
 RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);
 RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_PLL_MUL30);
 
 /* CK_PREDIV0 = (CK_HXTAL)/5 *8 /10 = 4 MHz */
 RCU_CFG1 &= ~(RCU_CFG1_PLLPRESEL | RCU_CFG1_PREDV0SEL | RCU_CFG1_PLL1MF | RCU_CFG1_PREDV1 | RCU_CFG1_PREDV0);
 RCU_CFG1 |= (RCU_PLLPRESRC_HXTAL | RCU_PREDV0SRC_CKPLL1 | RCU_PLL1_MUL8 | RCU_PREDV1_DIV5 | RCU_PREDV0_DIV10);
 
 /* enable PLL1 */
 RCU_CTL |= RCU_CTL_PLL1EN;
 /* wait till PLL1 is ready */
 while((RCU_CTL & RCU_CTL_PLL1STB) == 0U){
 }
 #endif /* GD32F30X_HD and GD32F30X_XD */
 
 /* enable PLL */
 RCU_CTL |= RCU_CTL_PLLEN;
 
 /* wait until PLL is stable */
 while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
 }
 
 /* enable the high-drive to extend the clock frequency to 120 MHz */
 PMU_CTL |= PMU_CTL_HDEN;
 while(0U == (PMU_CS & PMU_CS_HDRF)){
 }
 
 /* select the high-drive mode */
 PMU_CTL |= PMU_CTL_HDS;
 while(0U == (PMU_CS & PMU_CS_HDSRF)){
 }
 
 /* select PLL as system clock */
 RCU_CFG0 &= ~RCU_CFG0_SCS;
 RCU_CFG0 |= RCU_CKSYSSRC_PLL;
 
 /* wait until PLL is selected as system clock */
 while(0U == (RCU_CFG0 & RCU_SCSS_PLL)){
 }
 }
 | 
 
在此我们举例,若外部晶振使用16M该如何配置,主要修改以下两点:
 
1、修改HXTAL_VALUE为16M,如下红色底纹部分。
 
C
#if !defined  HXTAL_VALUE
#ifdef GD32F30X_CL
#define HXTAL_VALUE    ((uint32_t)25000000) /*!< value of the external oscillator in Hz */
#else
#define HXTAL_VALUE    ((uint32_t)16000000) /* !< from 4M to 32M *!< value of the external oscillator in Hz*/
#endif /* HXTAL_VALUE */
#endif /* high speed crystal oscillator value */
 
2、修改时钟倍频到120M.如下图红色底纹部分,配置15倍频,计算公式为16M/2*15=120M.
 
C/* 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) * 15 = 120 MHz */RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5);RCU_CFG0 |= RCU_PLL_MUL15;
 
 PS:GD固件库中修改使用内部时钟非常方便,只要打开内部时钟的宏定义就可以啦。
 
C
/* 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)
 
 GD32MCU技术交流群:859440462
 
更多GD32 MCU相关咨询:单片机开发板_国产mcu视频_GD32 - 苏州聚沃电子科技有限公司