[研电赛技术支持] GD32F103ZE配置72MHz主频全解析

[复制链接]
132|0
Zhiniaocun 发表于 2025-11-6 18:41 | 显示全部楼层 |阅读模式
一、核心配置逻辑
GD32F103ZE的72MHz主频配置基于HSE(外部8MHz晶振)作为PLL输入源,通过PLL倍频9倍(8MHz×9=72MHz),并合理分配总线时钟:

系统时钟(SYSCLK)= 72MHz
AHB总线时钟(HCLK)= SYSCLK(不分频)= 72MHz
APB1总线时钟(PCLK1)= HCLK/2 = 36MHz(APB1外设最大支持36MHz)
APB2总线时钟(PCLK2)= HCLK(不分频)= 72MHz(APB2外设支持72MHz)
二、代码实现(基于GD32标准库)
#include "gd32f1x0.h"
#include "gd32f1x0_rcu.h"
#include "gd32f1x0_fmc.h"  // Flash控制器配置头文件

/**
* @brief  配置系统时钟为72MHz(HSE→PLL×9)
* @param  无
* @retval 无
*/
void system_clock_72mhz_config(void) {
    /* 步骤1:使能HSE并等待稳定 */
    rcu_osci_on(RCU_HSE);  // 使能外部高速时钟(HSE)
    // 等待HSE稳定(超时返回ERROR,可添加错误处理)
    while(rcu_osci_stab_wait(RCU_HSE) == ERROR);

    /* 步骤2:配置PLL(输入源为HSE,倍频系数9) */
    // 参数1:PLL输入源(HSE不分频:RCU_PLLSOURCE_HSE_DIV1)
    // 参数2:PLL倍频系数(×9:RCU_PLL_MUL9)
    rcu_pll_config(RCU_PLLSOURCE_HSE_DIV1, RCU_PLL_MUL9);

    /* 步骤3:使能PLL并等待稳定 */
    rcu_osci_on(RCU_PLL);  // 使能PLL锁相环
    while(rcu_osci_stab_wait(RCU_PLL) == ERROR);  // 等待PLL输出稳定

    /* 步骤4:配置Flash等待周期(关键!72MHz需2个等待周期) */
    // Flash读取速度需与CPU主频匹配,否则会导致指令读取错误
    fmc_wsc_config(FMC_WSC_WS_2);  // 配置等待周期为2(适用于48~72MHz)

    /* 步骤5:配置总线分频 */
    rcu_hclk_div_config(RCU_SYSCLK_DIV1);    // AHB分频:SYSCLK/1 → 72MHz
    rcu_ppre1_div_config(RCU_HCLK_DIV2);     // APB1分频:HCLK/2 → 36MHz(满足最大限制)
    rcu_ppre2_div_config(RCU_HCLK_DIV1);     // APB2分频:HCLK/1 → 72MHz

    /* 步骤6:切换系统时钟源为PLL(72MHz) */
    rcu_system_clock_source_config(RCU_CKSYSSOURCE_PLLCLK);

    /* 步骤7:验证时钟源切换成功(可选,增强可靠性) */
    while(rcu_system_clock_source_get() != RCU_CKSYSSOURCE_PLLCLK);
}

/**
* @brief  初始化系统时钟(在main函数中首先调用)
* @param  无
* @retval 无
*/
void system_init(void) {
    // 配置72MHz系统时钟
    system_clock_72mhz_config();

    // 使能外设时钟(根据需要添加,例如GPIOA、USART1等)
    // 示例:使能GPIOA时钟(APB2总线)
    rcu_periph_clock_enable(RCU_GPIOA);
    // 示例:使能USART1时钟(APB2总线)
    rcu_periph_clock_enable(RCU_USART1);
    // 示例:使能TIM1时钟(APB2总线)
    rcu_periph_clock_enable(RCU_TIM1);
}

/* main函数示例 */
int main(void) {
    // 初始化系统时钟
    system_init();

    // 后续业务逻辑(如GPIO输出、UART通信等)
    while(1) {
        // 代码逻辑
    }
}




三、关键配置说明
HSE使能与稳定等待

rcu_osci_on(RCU_HSE):开启外部8MHz晶振,需确保硬件上晶振(8MHz)和匹配电容(10~30pF)已正确焊接。
rcu_osci_stab_wait(RCU_HSE):等待HSE稳定(约几毫秒),返回SUCCESS表示稳定,若失败可切换到HSI(内部8MHz时钟)作为备用。
PLL配置细节

GD32F103的PLL输入源支持两种:
RCU_PLLSOURCE_HSE_DIV1:HSE不分频(8MHz直接输入PLL)
RCU_PLLSOURCE_HSE_DIV2:HSE分频2(4MHz输入PLL)
倍频系数RCU_PLL_MUL9:8MHz×9=72MHz,符合芯片最大主频规格。
Flash等待周期(WSC)

当系统主频超过48MHz时,必须配置Flash等待周期(通过fmc_wsc_config):
主频≤24MHz:FMC_WSC_WS_0(0个等待周期)
24MHz<主频≤48MHz:FMC_WSC_WS_1(1个等待周期)
48MHz<主频≤72MHz:FMC_WSC_WS_2(2个等待周期)
若不配置,CPU将无法正确读取Flash中的指令,导致程序运行异常(如死机、跑飞)。
总线分频限制

APB1总线连接低速外设(如I2C、UART2、TIM2~TIM7),最大支持36MHz,因此必须分频(RCU_HCLK_DIV2)。
APB2总线连接高速外设(如GPIO、UART1、SPI1、TIM1),支持最高72MHz,故不分频。
四、验证与调试
配置完成后,可通过以下函数验证时钟频率:

#include "gd32f1x0_rcu.h"

void clock_verify(void) {
    uint32_t sysclk = rcu_system_clock_freq_get();  // 系统时钟(应返回72000000)
    uint32_t hclk = rcu_ahb_freq_get();             // AHB时钟(72000000)
    uint32_t pclk1 = rcu_apb1_freq_get();           // APB1时钟(36000000)
    uint32_t pclk2 = rcu_apb2_freq_get();           // APB2时钟(72000000)
    // 可通过调试器观察变量值,或通过UART打印输出验证
}


五、注意事项
若硬件无外部晶振(HSE),可使用HSI(内部8MHz)配置72MHz:
rcu_osci_on(RCU_HSI);  // 使能内部高速时钟
while(rcu_osci_stab_wait(RCU_HSI) == ERROR);
// HSI默认8MHz,分频2后为4MHz,PLL×18得到72MHz
rcu_pll_config(RCU_PLLSOURCE_HSI_DIV2, RCU_PLL_MUL18);



外设初始化前必须先使能对应时钟(如rcu_periph_clock_enable(RCU_GPIOA)),否则外设无法工作。
确保固件库版本与芯片型号匹配(GD32F103ZE属于GD32F1x0系列,需使用对应库文件)。
通过以上配置,GD32F103ZE可稳定工作在72MHz主频,满足大多数外设的时钟需求(如UART波特率、SPI时钟、定时器频率等)。
————————————————
版权声明:本文为CSDN博主「Shylock_Mister」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Shylock_Mister/article/details/153481131

您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

307

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部