打印

GD32_时钟配置解析

[复制链接]
1810|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GD32_时钟配置解析

本文以GD32F303型号为基础,依照标准库GD32F30x_Firmware_Library_V2.1.5为例,作为笔记简单记录个人对其时钟配置的理解,后续会持续更新本篇笔记内容。


前言

因为某些原因,国外半导体供应供应短缺,以STM32为例的系列芯片紧缺,价格跳水严重。技术群的部分码友们所在公司纷纷寻找替代产品,将头转向兆易创新的GD32,在将以前的STM32项目移植到国产GD32过程中,踩坑是在所难免,我也重新梳理了对GD32的理解。作为笔记加深理解。本篇主要是对时钟树的配置的一些理解和问题,欢迎各位码友指点!


使用特权

评论回复
沙发
范德萨发额|  楼主 | 2023-9-30 19:09 | 只看该作者
时钟源简介
时钟控制单元提供有五个时钟源,见时钟树标记,包括:
1:内部8M RC振荡器时钟(IRC8M):高速内部8MHz时钟,拥有8MHz的固定频率,设备上电后CPU默认选择的时钟源就是IRC8M时钟
2:内部48M RC 振荡器时钟(IRC48): 有一个固定的频率48MHz,可用作USB时钟或者PLL时钟源
3:外部高速晶体振荡器时钟(HXTAL:4到32MHz的外部振荡器,可为系统提供精确的主时钟。带有特定频率的晶体必须靠近两个HXTAL的引脚。和晶体连接的外部电阻和电容必须根据所选择的振荡器来调整
4:内部40K RC振荡器时钟(IRC40K):它的时钟频率大约40 kHz,为独立看门狗定时器和实时时钟电路提供时钟。
5:外部低速晶体振荡器时钟(LXTA):一个32.768kHz的低速外部晶体或陶瓷谐振器。它为实时时钟电路提供一个低功耗且精确的时钟源。
内部锁相环(PLL):对输入参考频率为4到32MHz时钟进行分频操作,输出一个8-120 MHz的时钟输出
剩下就是HXTAL时钟监视器、时钟预分频器、时钟多路复用器和时钟门控电路等。
AHB、 APB和Cortex®-M4时钟都源自系统时钟(CK_SYS),系统时钟的时钟源可以选择IRC8M、HXTAL或PLL。系统时钟的最大运行时钟频率可以达到120MHz。
严格来说锁相环不算时钟源,它是其他时钟源头配置而来

使用特权

评论回复
板凳
范德萨发额|  楼主 | 2023-9-30 19:09 | 只看该作者
时钟配置步骤
1.SystemInit (void)
此函数中主要操作为依内部8MHz时钟为时钟源,驱动时钟配置,线路为红色线路所示,步骤如下图:

使用特权

评论回复
地板
范德萨发额|  楼主 | 2023-9-30 19:09 | 只看该作者

使用特权

评论回复
5
范德萨发额|  楼主 | 2023-9-30 19:10 | 只看该作者

使用特权

评论回复
6
范德萨发额|  楼主 | 2023-9-30 19:10 | 只看该作者
代码如下(示例)、
void SystemInit (void)
{
  /* FPU settings */
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
#endif
    /* reset the RCU clock configuration to the default reset state */
    /* Set IRC8MEN bit */
    RCU_CTL |= RCU_CTL_IRC8MEN;                                                //打开内部8MHz RC振荡器
    while(0U == (RCU_CTL & RCU_CTL_IRC8MSTB)){          //等待内部8MHz RC振荡器稳定
    }
    RCU_MODIFY(0x50);                                                                //AHB时钟分频设置 先二分频再四分频
   
    RCU_CFG0 &= ~RCU_CFG0_SCS;                                                //00:选择 CK_IRC8M 时钟作为 CK_SYS 时钟源

#if (defined(GD32F30X_HD) || defined(GD32F30X_XD))
    /* reset HXTALEN, CKMEN and PLLEN bits */
        /*外部高速时钟使能位、HXTAL 时钟监视器使能位、PLL使能位 复位,方便后续操作*/
    RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
    /* disable all interrupts */
    /*关闭中断位*/
    RCU_INT = 0x009f0000U;
#elif defined(GD32F30X_CL)
    /* Reset HXTALEN, CKMEN, PLLEN, PLL1EN and PLL2EN bits */
    RCU_CTL &= ~(RCU_CTL_PLLEN |RCU_CTL_PLL1EN | RCU_CTL_PLL2EN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
    /* disable all interrupts */
    RCU_INT = 0x00ff0000U;
#endif

    /* reset HXTALBPS bit */
    RCU_CTL &= ~(RCU_CTL_HXTALBPS); //旁路模式位复位
   
    /* Reset CFG0 and CFG1 registers */
    RCU_CFG0 = 0x00000000U;
    RCU_CFG1 = 0x00000000U;
    /* configure the system clock source, PLL Multiplier, AHB/APBx prescalers and Flash settings */
    system_clock_config();
}

使用特权

评论回复
7
范德萨发额|  楼主 | 2023-9-30 19:10 | 只看该作者
system_clock_config();
根据宏定义,选择相关的时钟频率配置函数,我的是高速外部时钟源配置108MHz系统时钟
配置函数为;system_clock_108m_hxtal();
代码如下(示例):

使用特权

评论回复
8
范德萨发额|  楼主 | 2023-9-30 19:10 | 只看该作者
static void system_clock_config(void)
{
#ifdef __SYSTEM_CLOCK_IRC8M
    system_clock_8m_irc8m();
#elif defined (__SYSTEM_CLOCK_48M_PLL_IRC8M)
    system_clock_48m_irc8m();
#elif defined (__SYSTEM_CLOCK_72M_PLL_IRC8M)
    system_clock_72m_irc8m();
#elif defined (__SYSTEM_CLOCK_108M_PLL_IRC8M)
    system_clock_108m_irc8m();
#elif defined (__SYSTEM_CLOCK_120M_PLL_IRC8M)
    system_clock_120m_irc8m();
#elif defined (__SYSTEM_CLOCK_HXTAL)
    system_clock_hxtal();
#elif defined (__SYSTEM_CLOCK_48M_PLL_HXTAL)
    system_clock_48m_hxtal();
#elif defined (__SYSTEM_CLOCK_72M_PLL_HXTAL)
    system_clock_72m_hxtal();
#elif defined (__SYSTEM_CLOCK_108M_PLL_HXTAL)
    system_clock_108m_hxtal();
#elif defined (__SYSTEM_CLOCK_120M_PLL_HXTAL)
    system_clock_120m_hxtal();
#endif /* __SYSTEM_CLOCK_IRC8M */
}

使用特权

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

本版积分规则

52

主题

935

帖子

2

粉丝