打印
[研电赛技术支持]

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

[复制链接]
192|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言
        芯片: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);
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/LSL_Blogs/article/details/132866441

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

14

帖子

0

粉丝