GD32F450的时钟笔记

本文详细介绍了GD32F450单片机的时钟系统配置,包括外部和内部时钟源、主要时钟、PLL设置以及系统时钟的切换。通过代码示例展示了如何初始化时钟以达到240MHz的工作频率,并提供了厂家提供的预设时钟配置选项。此外,还强调了正确配置时钟对单片机性能的重要性。
摘要由CSDN通过智能技术生成

GD32F450 标称 200MHz,但是在手册中又说 它是 240MHz。本文以 手册中的 240MHz 进行举例,我保险起见,产品中使用还是在 200MHz 下使用。

时钟树

手册上的时钟树图如下
在这里插入图片描述

GD32F450的 外部时钟源 有2个

  • LXTAL 外部低速时钟源 32.768 kHz
  • HXTAL 外部高速时钟源 4~32 MHz

GD32F450的 内部时钟源 有3个

  • IRC32K 内部 32KHz 时钟源
  • IRC16M 内部 16MHz 时钟源
  • IRC48M 内部 48MHz 时钟源

重要时钟

对于 GD32F450 的使用,主要关注

  • CK_SYS 系统时钟
    _
  • HCLK ( AHB bus,Cortex-M4,SRAM,DMA,peripherals )
  • PCLK1 ( APB1 peripherals )
  • CKTIMERx ( TIMER1,2,3,4,5,6,11,12,13 )
  • PCLK2 ( APB2 peripherals )
  • CKTIMERx ( TIMER0,7,8,9,10 )
  • CK_ADCX ( ADC 0,1,2 )

主要的外设时钟还是下面这三个时钟,它们衍生出其它外设时钟。

  • AHB 最高时率为 240 MHz
  • APB2 最高时率为 120 MHz
  • APB1 最高时率为 60 MHz

对于单片机内核,仅需要关注 HCLK
上述的时钟 主要还是 通过 CK_SYS 时钟衍生出来的,因此需要先配置好它,才能对接下来的 外设时钟进行配置。

GD32F450的PLL

CK_SYS 有 3 个 时钟源,如下图所示:

在这里插入图片描述
即,

  • IRC16M 内部16MHz (默认)
  • HXTAL 外部高速时钟
  • PLLP 倍频时钟P

CK_SYS 要想达到240MHz,必须要通过 倍频时钟P 得到。

GD32F450有3个PLL,与CK_SYS有关的只有PLL,如下图所示

在这里插入图片描述

根据上图,可以明确倍频步骤了。

  1. 打开外部时钟源(HXTAL)
  2. 切换内核时钟为非PLL时钟(当前例程为选择内部16MHz时钟)
  3. 确定切换成功
  4. 关闭PLL
  5. 配置 PLLSEL 选择外部时钟源(鄙人的开发板外部晶振为8MHz)
  6. 配置输入分频系数,倍频系数N,输出P分频系数
  7. 使能 PLL
  8. 配置SCS切换时钟
  9. 确定切换成功

查看相关寄存器,即可进行配置了。

代码如下

uint8_t CLock_Init(void)
{
	uint16_t overTimeCnt;

	RCU_CTL |= RCU_CTL_HXTALEN;												// 高速晶体振荡器(HXTAL)使能
	overTimeCnt = 0x0fff;
	do
	{
		overTimeCnt--;
		if(!overTimeCnt)
			return FAILED;													// 等待超时
	} while (!(RCU_CTL & RCU_CTL_HXTALSTB));								// 等待 外部晶振HXTAL 稳定

	RCU_CFG0 = (RCU_CFG0 & ~RCU_CFG0_SCS) | RCU_CKSYSSRC_IRC16M;			// 系统时钟 选择内部16MHz
	overTimeCnt = 0x0fff;
	do
	{
		overTimeCnt--;
		if(!overTimeCnt)
			return FAILED;													// 等待超时
	} while ((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_IRC16M);				// 等待 系统时钟 选择内部16MHz


	RCU_CTL &= ~RCU_CTL_PLLEN;												// 关闭 PLL
	overTimeCnt = 0x0fff;
	do
	{
		overTimeCnt--;
		if(!overTimeCnt)
			return FAILED;													// 等待超时
	} while ((RCU_CTL & RCU_CTL_PLLEN));									// 等待 关闭 PLL

	RCU_PLL = 	( RCU_PLL & ~(RCU_PLL_PLLPSC | RCU_PLL_PLLN | RCU_PLL_PLLP | RCU_PLL_PLLSEL | RCU_PLL_PLLQ) ) | \
								( 8 << 0)    | ( 480 << 6)  | ( 0 << 16)   | RCU_PLL_PLLSEL | ( 10 << 24);
							// 输入8分频     | 倍频480倍    | PLLP 2分频   | 选择外部晶振   | PLLQ 10分频
							// 输入 1MHz     | VCO=480MHz   | PLLP=240MHz  |                | PLLQ=48MHz

	RCU_CTL |= RCU_CTL_PLLEN;												// 使能 PLL
	overTimeCnt = 0x0fff;
	do
	{
		overTimeCnt--;
		if(!overTimeCnt)
			return FAILED;													// 等待超时
	} while (!(RCU_CTL & RCU_CTL_PLLSTB));									// 等待 PLL 稳定

	RCU_CFG0 = (RCU_CFG0 & ~(RCU_CFG0_AHBPSC | RCU_CFG0_APB1PSC | RCU_CFG0_APB2PSC)) | \
								(0 << 4)     | (5 << 10)        | (4 << 13);
							// AHB不分频     | APB1 4分频       | APB2 2分频
							// 240MHz        | 60MHz            | 120MHz
	

	RCU_CFG0 = (RCU_CFG0 & ~RCU_CFG0_SCS) | RCU_CKSYSSRC_PLLP;				// 系统时钟 选择PLLP
	overTimeCnt = 0x0fff;
	do
	{
		overTimeCnt--;
		if(!overTimeCnt)
			return FAILED;													// 等待超时
	} while ((RCU_CFG0 & RCU_CFG0_SCSS) != RCU_SCSS_PLLP);					// 等待 系统时钟 选择PLLP

	return SUCCEED;
}

简单的方法

其实厂家已经帮我们初始化好了时钟,在 system_gd32f4xx.c 文件中 通过 选择宏定义就能 将单片机 配置成常用的时钟频率了。

AHB 不分频
APB1 四分频
APB2 二分频


/* select a system clock by uncommenting the following line */
//#define __SYSTEM_CLOCK_IRC16M                   (uint32_t)(__IRC16M)
//#define __SYSTEM_CLOCK_HXTAL                    (uint32_t)(__HXTAL)
//#define __SYSTEM_CLOCK_120M_PLL_IRC16M          (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_120M_PLL_8M_HXTAL        (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_120M_PLL_25M_HXTAL       (uint32_t)(120000000)
//#define __SYSTEM_CLOCK_168M_PLL_IRC16M          (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_168M_PLL_8M_HXTAL        (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_168M_PLL_25M_HXTAL       (uint32_t)(168000000)
//#define __SYSTEM_CLOCK_200M_PLL_IRC16M          (uint32_t)(200000000)
#define __SYSTEM_CLOCK_200M_PLL_8M_HXTAL        (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_200M_PLL_25M_HXTAL       (uint32_t)(200000000)
//#define __SYSTEM_CLOCK_240M_PLL_IRC16M          (uint32_t)(240000000)
// #define __SYSTEM_CLOCK_240M_PLL_8M_HXTAL        (uint32_t)(240000000)
//#define __SYSTEM_CLOCK_240M_PLL_25M_HXTAL       (uint32_t)(240000000)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值