文章目录
前言
准备
1、GD32F系列开发版,我使用的事F427R-START开发版
2、安装有Keil的电脑,当前keil版本为v5.31.0.0
一、时钟树
二、配置步骤
1、时钟初始化配置过程,主要先配置和初始化RCU_CTL和RCU_CFG0两个寄存器
寄存器内容如下,具体介绍请查看芯片数据手册
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 */
/* 开始先使能内部16M时钟 */
RCU_CTL |= RCU_CTL_IRC16MEN;
/*CK_AHB分频(CK_AHB = CK_SYS/4,但是不懂为什么先2分频再4分配)*/
RCU_MODIFY
/* 选择 CK_IRC16M 时钟作为 CK_SYS 时钟源 */
RCU_CFG0 &= ~RCU_CFG0_SCS;
/* 锁相环PLL关闭, 禁止高速时钟(HXTAL)时钟监视器 、关闭外部高速时钟HXTAL */
RCU_CTL &= ~(RCU_CTL_PLLEN | RCU_CTL_CKMEN | RCU_CTL_HXTALEN);
/* 禁止HXTAL旁路模式 */
RCU_CTL &= ~(RCU_CTL_HXTALBPS);
/* 复位RCU_CFG0寄存器(即内部16M作为时钟源,AHB、APB1、APB2等不分频) */
RCU_CFG0 = 0x00000000U;
/* 等待内部高速时钟 IRC16M 作为系统时钟*/
while(0 != (RCU_CFG0 & RCU_SCSS_IRC16M)){
}
/* 复位PLL寄存器(0x24003010U) */
RCU_PLL = 0x24003010U;
/* 禁用中断 */
RCU_INT = 0x00000000U;
/* 配置系统时钟源, PLL 倍频器 和分频因子,AHB/APBx 预分频器 、flsh设置*/
system_clock_config();
}
总的来说就是SystemInit就是先初始化好内部高速时钟作为时钟源,然后再根据需求配置输出对应时钟
system_clock_200m_25m_hxtal()函数把外部25M高速时钟配置成200MCK_SYS时钟输出
static void system_clock_200m_25m_hxtal(void)
{
uint32_t timeout = 0U;
uint32_t stab_flag = 0U;
/* 使能 HXTAL */
RCU_CTL |= RCU_CTL_HXTALEN;
/* 等待外部高速时钟稳定,超时退出或者判断时钟稳定则退出等待 */
do{
timeout++;
stab_flag = (RCU_CTL & RCU_CTL_HXTALSTB);
}while((0U == stab_flag) && (HXTAL_STARTUP_TIMEOUT != timeout));
/* 如果时钟还没有稳定说明时钟异常,则在这里死循环 */
if(0U == (RCU_CTL & RCU_CTL_HXTALSTB)){
while(1){
}
}
/* 电源管理单元时钟使能 */
RCU_APB1EN |= RCU_APB1EN_PMUEN;
/* LDO电压选择, 输出高电压模式 */
PMU_CTL |= PMU_CTL_LDOVS;
/* 不分频,AHB = SYSCLK,CK_SYS = CK_AHB (这里最大200M,不同的型号不一样) */
RCU_CFG0 |= RCU_AHB_CKSYS_DIV1;
/* APB2 = AHB/2 则这里最大 100M*/
RCU_CFG0 |= RCU_APB2_CKAHB_DIV2;
/* APB1 = AHB/4 则这里最大 50M*/
RCU_CFG0 |= RCU_APB1_CKAHB_DIV4;
/* Configure the main PLL, PSC = 25, PLL_N = 400, PLL_P = 2, PLL_Q = 9 */
/* 配置PLLSEL选择HXTAL外部高速时钟作为PLL时钟源、
配置 预分频器 PSC 分频系数为25,作为PLL VCO的输入时钟,如果外部晶振是8或12M晶振的话需改
配置倍频因子 PLL_N = 400,输出频率分频系数PLL_P = 2, 输出频率的分频系数 PLL_Q = 9
根据公式 CK_PLLP = 25/25*400/2 = 200 */
RCU_PLL = (25U | (400U << 6U) | (((2U >> 1U) - 1U) << 16U) |
(RCU_PLLSRC_HXTAL) | (9U << 24U));
/* 使能PLL */
RCU_CTL |= RCU_CTL_PLLEN;
/* 等待PLL稳定 */
while(0U == (RCU_CTL & RCU_CTL_PLLSTB)){
}
/*在高频状态下,电源管理单元使能高驱动模式 */
PMU_CTL |= PMU_CTL_HDEN;
while(0U == (PMU_CS & PMU_CS_HDRF)){
}
/* 将LDO切换到高驱动模式 */
PMU_CTL |= PMU_CTL_HDS;
while(0U == (PMU_CS & PMU_CS_HDSRF)){
}
/* 清空SCS寄存器,再配置SCS寄存器把CK_PLLP 作为系统时钟CK_SYS的时钟源 */
RCU_CFG0 &= ~RCU_CFG0_SCS;
RCU_CFG0 |= RCU_CKSYSSRC_PLLP;
/* 等待选择 CK_PLLP 时钟作为 CK_SYS 时钟源 的状态切换完成 */
while(0U == (RCU_CFG0 & RCU_SCSS_PLLP)){
}
}
注意,这个函数是以25M晶振配置,如果外部高速晶振接的不是25M有没有对应的配置函数,需要自己修改PSC的系数,如 外部晶振如果接的是 12M,则PSC改为12