超全面GD32F4XX 系统时钟与AHB/APB1/APB2时钟配置

文章详细介绍了GD32F450ZGT6芯片的时钟配置过程,包括CK_SYS时钟源选择(IRC16M、HXTAL或PLL)、HXTAL频率配置、PLL倍频、AHB/APB1/APB2分频设置,以及如何测试配置效果。
摘要由CSDN通过智能技术生成

目录

 前言

时钟配置

CK_SYS时钟配置

时钟源选择方式

时钟源选择标准

HXTAL配置

配置流程

AHB/APB1/APB2分频设置

测试时钟配置情况


 前言

        芯片:GD32F450ZGT6

        系统时钟:最大200MHZ

        HXTAL:25MHZ

时钟配置

       本文以GD32F450为例,ST的芯片思路基本一致。

       本文介绍从时钟源到CK_SYS以及CK_AHB/APB1/APB2的配置。

CK_SYS时钟配置

手册里说:系统时钟的时钟源可以选择 IRC16M、HXTAL或PLL。

时钟源选择方式

通过在system_gd32f4xx.c中修改宏定义实现。

时钟源选择标准
  • 准确度

         手册里说:工厂会校准IRC16M时钟频率的精度,但是它的精度仍然比HXTAL时钟要差。4到32MHz的外部高速晶体振荡器可为系统时钟提供更为精确时钟源。

        所以一般选择HXTAL作为系统时钟源。不过IRC16M时钟启动更快,上电和睡眠唤醒时默认是IRC16M时钟,后续会根据配置设置HXTAL作为系统时钟源。

  • 频率选择

        只使用HXTAL的频率有限,PLL(锁相环)的主要作用之一是倍频,我用的芯片最大支持频率200MHZ,具体多少频率根据自己的需求选择就行,而具体是4-32MHZHXTAL的哪一个宏定义,根据自己使用芯片的实际HXTAL而定。

        至于 都使用PLL倍频的HXTAL时钟时,倍频到相同频率,8M与25M有什么区别,具体区别可以问硬件工程师,这些是他们负责选型,对于软件来说,时钟频率一样就是一样(应该会存在一定的稳定性和准确度的差别,但是影响不大)。 

HXTAL配置

        1.在system_gd32f4xx.c中 打开上文图片的宏定义 

#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL       (uint32_t)(200000000)

       2.在gd32f4xx.h中修改HXTAL_VALUE的具体数值

/* define value of high speed crystal oscillator (HXTAL) in Hz */
#if !defined  (HXTAL_VALUE)
#define HXTAL_VALUE    ((uint32_t)25000000)
#endif /* high speed crystal oscillator value */

      3.这里说明一下,不需要修改

        在system_gd32f4xx.c中,有一个宏定义,它其实并没有在任何地方使用,只是起到注释说明系统默认时钟是__IRC16M

#define __SYS_OSC_CLK   (__IRC16M)    /* main oscillator frequency */
配置流程
  • 打开时钟的宏定义后,具体数值会复制给SystemCoreClock,便于其他地方使用。
  • 系统复位时会调用SystemInit()->system_clock_config()->system_clock_200m_25m_hxtal()

25MHZ的HXTAL的配置函数,官方的固件程序中已经写好了,不需要我们自己改写,如果使用了官方没有的HXTAL频率,需要自己改写函数,主要时设置PLL的倍频,它有相应的计算公式,需要的话可以搜索相关资料。

AHB/APB1/APB2分频设置

在函数system_clock_200m_25m_hxtal()中,有设置他们分频系数的语句,在这里修改即可。

这么默认的时AHB不分频,就是AHN等于系统时钟,APB2是AHB的2分频,APB1是AHB的4分频

    /* AHB = SYSCLK */
    RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
    /* APB2 = AHB/2 */
    RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
    /* APB1 = AHB/4 */
    RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;

测试时钟配置情况

gd32中,使用uint32_t rcu_clock_freq_get(rcu_clock_freq_enum clock)函数返回时钟频率

#include "gd32f4xx_rcu.h"

//.....
uint32_t temp_CK_SYS = 0;
uint32_t temp_CK_AHB = 0;
uint32_t temp_CK_APB1 = 0;
uint32_t temp_CK_APB2 = 0;

temp_CK_SYS = rcu_clock_freq_get(CK_SYS);
temp_CK_AHB = rcu_clock_freq_get(CK_AHB);
temp_CK_APB1 = rcu_clock_freq_get(CK_APB1);
temp_CK_APB2 = rcu_clock_freq_get(CK_APB2);

  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值