0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【GD32 MCU 入门教程】GD32 MCU 常见外设介绍(1)RCU 时钟介绍

聚沃科技 2024-08-09 09:46 次阅读

众所周知,时钟MCU能正常运行的基本条件,就好比心跳或脉搏,为所有的工作单元提供时间 基数。时钟控制单元提供了一系列频率的时钟功能,包括多个内部RC振荡器时钟(IRC)、一个外部 高速晶体振荡器时钟(HXTAL)、一个外部低速晶体振荡器时钟(LXTAL)、一个或多个锁相环(PLL) 一个HXTAL时钟和LXTAL时钟监视器、时钟预分频器、时钟多路复用器和时钟门控电路等。 本章,我们将通过一个“输出HXTAL时钟信号” 的实验来熟悉RCU的工作流程。

1.1RCU 配置

GD32系列MCU在启动后首先会执行Reset Handler,紧接着就会执行SystemInit()函数,而时钟的初始化,就是在这个函数中进行,其主要的功能是配置系统时钟CK_SYS(即主频),AHB、APB1以及APB2时钟。SystemInit()函数由GD32官方库提供,不同系列的MCU有一些差别,但实现方式基本相同:首先将RCU关于CK_SYS,AHB、APB1以及APB2时钟配置的一些寄存器恢复到默认值,然后再执行system_clock_config()函数,用于具体的时钟配置。

实际上用户可以不用过于关心上述的实现方式,因为GD32库已经为您提供了多种时钟源及时钟选择,您只需按照以下步骤即可将时钟设置为您期望的值(以GD32F30x为例,其他系列类似):

(1) 在system_gd32f30x.c中,用户可通过选择宏来进行预设的时钟配置,如下图代码清单时钟配置选择宏定义,选择了HXTAL作为PLL时钟源,且配置CK_SYS为120MHz。

/* system frequency define */ #define __IRC8M (IRC8M_VALUE) /* internal 8 MHz RC oscillator frequency */ #define __HXTAL (HXTAL_VALUE) /* high speed crystal oscillator frequency */ #define __SYS_OSC_CLK (__IRC8M) /* main oscillator frequency */ /* select a system clock by uncommenting the following line */ /* use IRC8M */ //#define __SYSTEM_CLOCK_IRC8M (uint32_t)(__IRC8M) //#define __SYSTEM_CLOCK_48M_PLL_IRC8M (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_IRC8M (uint32_t)(72000000) //#define __SYSTEM_CLOCK_108M_PLL_IRC8M (uint32_t)(108000000) //#define __SYSTEM_CLOCK_120M_PLL_IRC8M (uint32_t)(120000000) /* use HXTAL(XD series CK_HXTAL = 8M, CL series CK_HXTAL = 25M) */ //#define __SYSTEM_CLOCK_HXTAL (uint32_t)(__HXTAL) //#define __SYSTEM_CLOCK_48M_PLL_HXTAL (uint32_t)(48000000) //#define __SYSTEM_CLOCK_72M_PLL_HXTAL (uint32_t)(72000000) //#define __SYSTEM_CLOCK_108M_PLL_HXTAL (uint32_t)(108000000) #define __SYSTEM_CLOCK_120M_PLL_HXTAL (uint32_t)(120000000)

但这种情况下您使用的外部晶振需要是默认值,此值由HXTAL_VALUE定义,如为8000000,那么您应该选择8MHz的外部晶振。

当然,您可以使用其他规格的外部晶振,这种情况下就需要去修改RCU配置函数里面的一些参数,主要是分频和倍频系数,以达到期望的配置,具体如何修改,可以结合GD32的User manual中定义的RCU寄存器来对配置函数进行分析。

(2) 设置HXTAL_VALUE的值。

此数值和RCU的初始化其实并没有太大关系,但如果您使用的外部晶振不是默认值,那么除了按照步骤(1)修改配置参数外,您还必须将此HXTAL_VALUE的值修改为实际的外部晶振频率,这是因为在一些通信外设配置时,库函数会调用HXTAL_VALUE值来设置波特率,如此值设置错误,会导致通信异常。

1.2.非默认外部晶振配置时钟实例

GD32各系列固件库都已提供配置系统时钟的函数。需要注意的是,在使用外部晶振时,固件库中HXTAL_VALUE值规定了 外部晶振的默认值,以 GD32F30x系列为例,如下图代码清单HXTAL_VALUE选择宏定义所示,当芯片为非互联型(GD32F303)时,默认使用的外部晶振频率为8MHz,当芯片为互联型(GD32F305/307)时,默认使用的外部晶振频率为25MHz。

#ifdef GD32F30X_CL #define HXTAL_VALUE ((uint32_t)25000000) #else #define HXTAL_VALUE ((uint32_t)8000000)

那么,当我们使用非默认值的外部晶振时,该如何修改时钟配置函数呢?以GD32F303为例,首先我们先看下GD32F303的时钟树,如图所示。

输入图片说明

预分频器可以配置AHB、APB2和APB1域的时钟频率。 AHB、APB2、APB1域的最高时钟频率分别为120MHz、120MHz、60MHz。RCU通过AHB时钟(HCLK)8分频后作为Cortex系统定时器(SysTick)的外部时钟。通过对SysTick控制和状态寄存器的设置,可选择上述时钟或AHB(HCLK)时钟作为SysTick时钟。

ADC时钟由APB2时钟经2、4、6、8、12、16分频或由AHB时钟经5、6、10、20分频获得,它们是通过设置RCU_CFG0和RCU_CFG1寄存器的ADCPSC位来选择。

SDIO, EXMC的时钟由CK_AHB提供。

TIMER时钟由CK_APB1和CK_APB2时钟分频获得,如果APBx(x=0,1)的分频系数不为1,则TIMER时钟为CK_APBx(x=0,1)的两倍。

USBD的时钟由CK48M时钟提供。通过配置 RCU_ADDCTL寄存器的CK48MSEL及PLL48MSEL位可以选择CK_PLL时钟或IRC48M时钟做为CK48M的时钟源。

CTC时钟由IRC48M时钟提供,通过CTC单元,可以实现IRC48M时钟精度的自动调整。

I2S的时钟由CK_SYS提供。

通过配置RCU_BDCTL寄存器的RTCSRC位, RTC时钟可以选择由LXTAL时钟、IRC40K时钟或HXTAL时钟的128分频提供。RTC时钟选择HXTAL时钟的128分频做为时钟源后,当1.2V内核电压域掉电时,时钟将停止。 RTC时钟选择IRC40K时钟做为时钟源后,当VDD掉电时,时钟将停止。

RTC时钟选择LXTAL时钟做为时钟源后,当VDD和VBAT都掉电时,时钟将停止。

当FWDGT启动时, FWDGT时钟被强制选择由IRC40K时钟做为时钟源。

现在,我们结合图GD32F303系统时钟树对时钟树进行分析:

(1) 标注A为CK_SYS,即系统主时钟,它一条线连接至CK_I2S,给I2S外设提供时钟,另一条线经过AHB分频器,输出到CK_AHB,即标注B。

(2) CK_AHB为AHB总线时钟,AHB总线时钟或直连,或经过APB1/APB2分频,给标注C位置的外设提供时钟。

(3) 那么,CK_SYS从何而来呢,我们看标注A的左边,CK_SYS通过SCS位域选择CK_IRC8M、CK_PLL、CK_HXTAL作为时钟来源,其中CK_IRC8M来源于标注D,即IRC8M(MCU内部8M RC时钟);CK_HXTAL来源于标注F,即HXTAL(外部时钟);CK_PLL的来源较复杂,我们单独拿出来说。

(4) CK_PLL来源于锁相环倍频器输出,倍频系数通过PLLMF位域选择,而PLLMF来源于两个地方,一个为 IRC8M 的 2 分 频 , 另 外 一 个 为 预 分 频 器 PREDV0 , 而 PREDV0 来 源 于 标 注 E, 即CK_IRC48M(内部48M RC时钟)和标注F,即HXTAL(外部高速时钟)。

(5) 通过以上分析可以得出结论,CK_PLL的时钟源为D:IRC8M、E:IRC48M、F:HXTAL,用户通过相关寄存器设置选择时钟线。

(6) 和前面分析相同,RTC的时钟来自于F:HXTAL的128分频、G:LXTAL(外部32.768K低速时钟)、F:IRC40K(内部40K RC时钟);FWDGT的时钟来源于F:IRC40K。

(7) 标注I位置为时钟输出线,它的作用是将MCU内部的一些时钟信号线输出到特定IO口上(大部分系列MCU的PA8口都可被设置为时钟输出口0,有些系列MCU含有两组输出IO,具体IO配置请参考各系列MCU Datasheet)用来给其他器件提供基准时钟。由图中可看出通过设置位域CK_OUT0,输出的时钟包括CK_PLL、CK_IRC8M、CK_HXTAL、CK_PLL的2分频。

结合以上分析,我们来看下GD32F30x固件库时钟配置函数(因篇幅有限,只贴出各分频和倍频配置部分),还是以GD32F303芯片为例,如下图代码清单时钟配置部分代码所示:

/* select HXTAL/2 as clock source */ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0); RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0); /* CK_PLL = (CK_HXTAL/2) * 30 = 120 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5); RCU_CFG0 |= RCU_PLL_MUL30;

可以看出,8MHz的HXTAL经过预分频器PREDV0分频成4MHz,再通过锁相环PLL倍频30倍到了120MHz。

那么,当您选择其他规格的外部晶振,比如12MHz,则可以先通过预分频器PREDV0分频成6MHz,再通过锁相环PLL倍频20倍即可,如代码清单 0-4. 使用12MHz外部晶振配置120M系统时钟所示。

/* select HXTAL/2 as clock source */ RCU_CFG0 &= ~(RCU_CFG0_PLLSEL | RCU_CFG0_PREDV0); RCU_CFG0 |= (RCU_PLLSRC_HXTAL_IRC48M | RCU_CFG0_PREDV0); /* CK_PLL = (CK_HXTAL/2) * 20 = 120 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4 | RCU_CFG0_PLLMF_5); RCU_CFG0 |= RCU_PLL_MUL20;

当然,在修改完配置函数后,别忘了将HXTAL_VALUE值改为12000000。

需要注意的是,在进行时钟配置时,要严格按照Datasheet中规定的时钟范围进行配置,如GD32F303的 HXTAL的选 择范 围是4~32MHz, PLL的输 入范 围是 1~25MHz,输出范围是16~120Mhz,所以当使用32MHz的外部晶振时,不进行预分频,而直接倍频是不被允许的。

1.3.硬件连接说明

本章通过“输出HXTAL时钟信号”实验来熟悉RCU的工作流程。

通过前面内容讲解可知,本章实验为“输出HXTAL时钟信号”,即通过PA8口将HXTAL输出,我们使用示波器,将探头连接到PA8口,从示波器上读取PA8口波形即可。

1.4.软件配置说明

本小节讲解RCU_Example例程中RCU的配置说明,主要包括外设时钟配置、GPIO引脚配置、主函数介绍以及运行结果。

软件设计的流程如下:

(1)使能GPIOA时钟

(2)初始化PA8,将此端口设置为备用功能模式(AFIO)

(3)通过调用库函数选择HXTAL作为PA8时钟信号源

外设时钟配置

void rcu_config(void) { /* enable the GPIOA clock */ rcu_periph_clock_enable(RCU_GPIOA); }

GPIO 引脚配置

代码清单 0-6. RCU 例程引脚配置

void gpio_config(void) { /* configure PA8 port */ #if defined GD32F10X_HD || GD32F30X_HD || GD32F20X_CL || GD32E10X gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8); #elif GD32F1X0 || GD32F4XX || GD32F3X0 || GD32E23X gpio_mode_set(GPIOA,GPIO_MODE_AF,GPIO_PUPD_NONE,GPIO_PIN_8); gpio_af_set(GPIOA,GPIO_AF_0,GPIO_PIN_8); #endif }

GPIO的配置说明,请参考GPIO章节。

主函数说明

代码清单 0-7 . RCU 例程主函数

int main(void) { rcu_config(); gpio_config(); #if defined GD32F10X_HD || GD32F30X_HD || GD32E10X rcu_ckout0_config(RCU_CKOUT0SRC_HXTAL); #elif defined GD32F20X_CL || GD32F4XX rcu_ckout0_config(RCU_CKOUT0SRC_HXTAL,RCU_CKOUT0_DIV1); #elif GD32F1X0 || GD32F3X0 || GD32E23X rcu_ckout_config(RCU_CKOUTSRC_HXTAL,RCU_CKOUT_DIV1); #endif while(1){ } }

如代码清单RCU例程主函数,该主函数主要分成四部分,RCU时钟配置、GPIO配置、RCU输出相关库函数调用和while(1)主循环,其中RCU输出相关库函数请读者结合各系列MCU Datasheet、User Manual进行RCU例程的分析。

注意:因为是输出HXTAL,所以必须要使能HXTAL,否则PA8将无波形输出。一个简单的办法是将HXTAL作为CK_SYS时钟源,请参考本章第一节内容。

1.5.运行结果

如图所示 RCU 例程运行结果为 RCU 例程运行结果,可看出,PA8 口正确输出了 HXTAL 波形。

输入图片说明

教程GD32 MCU方案商聚沃科技原创发布,了解更多GD32 MCU教程,关注聚沃科技官网

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6035

    文章

    44554

    浏览量

    634651
  • mcu
    mcu
    +关注

    关注

    146

    文章

    17123

    浏览量

    350992
  • 嵌入式
    +关注

    关注

    5082

    文章

    19104

    浏览量

    304815
  • 时钟树
    +关注

    关注

    0

    文章

    54

    浏览量

    10741
  • rcu
    rcu
    +关注

    关注

    0

    文章

    21

    浏览量

    5446
收藏 人收藏

    评论

    相关推荐

    GD32 MCU 入门教程GD32 MCU 常见外设介绍(12)FMC 模块介绍

    闪存控制器(FMC),提供了片上闪存需要的所有功能。FMC 也提供了页擦除,整片擦除,以及32 位整字或 16 位半字编程闪存等操作。 GD32 MCU 支持不同类型编程的具体说明如下表 GD32
    的头像 发表于 08-21 09:56 1097次阅读
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>常见外设</b><b class='flag-5'>介绍</b>(12)FMC 模块<b class='flag-5'>介绍</b>

    GD32MCU介绍

    其实兆芯的MCU为了兼容ST,外设的寄存器设计与ST保持一致了。比如GD32VF103或者GD32E103系列的USBFS这个外设,基本等同
    发表于 11-01 06:03

    GD32 MCU原理及固件库开发指南》 + 初读感悟

    GD32 MCU原理固件库开发指南这本书内容丰富,囊括了GD32中的所有外设,书中首先介绍了如何使用MDK或IAR软件搭建
    发表于 03-31 22:11

    GD32 MCU原理及固件库开发指南》+读后感

    运行,做到通俗易懂,降低了用户入门门槛,让学习者快速的应用到项目。 本书共分为8章: 第1章对GD32 MCU进行概述,包括对兆易创新公司进行概述,
    发表于 06-06 21:52

    兆易创新GD32 MCU选型手册,适用于GD32全系列MCU

    兆易创新GD32MCU选型手册,适用于GD32全系列MCUGD32MCU选型手册,适用于GD32全系列MCU
    发表于 10-19 17:26 49次下载

    你了解GD32 MCU的命名规则吗

    下面为大家介绍GD32 MCU的通用命名规则,以GD32F303ZGT6为例,其中,GD32代表GD32
    的头像 发表于 01-13 09:38 3627次阅读
    你了解<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的命名规则吗

    GD32 MCU的选项字节是什么?

    GD32 MCU的选项字节是什么,有什么功能呢?选项字节被误篡改如何回复?
    的头像 发表于 01-17 09:42 1358次阅读
    <b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>的选项字节是什么?

    不同型号的GD32 MCU如何区分?

    大家是否碰到过以下应用场景:同一套软件代码希望跑在不同型号的GD32 MCU中,但有些地方需要根据MCU型号进行调整?或者上位机或其他MCUGD3
    的头像 发表于 01-27 09:32 991次阅读
    不同型号的<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b>如何区分?

    GD32 MCU 入门教程】一、GD32 MCU 开发环境搭建(1)使用Keil开发GD32

    GD32系列为通用型MCU,所以开发环境也可以使用通用型的IDE,目前使用较多的是KEIL、IAR、 GCC和Embedded Builder,客户可以根据个人喜好来选择相应的开发环境。
    的头像 发表于 08-08 15:01 1168次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 开发环境搭建(<b class='flag-5'>1</b>)使用Keil开发<b class='flag-5'>GD32</b>

    GD32 MCU 入门教程】一、GD32 MCU 开发环境搭建(2)使用 IAR 开发 GD32

    GD32系列为通用型MCU,所以开发环境也可以使用通用型的IDE,目前使用较多的是KEIL、IAR、 GCC和Embedded Builder,客户可以根据个人喜好来选择相应的开发环境。
    的头像 发表于 08-08 15:40 681次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 开发环境搭建(2)使用 IAR 开发 <b class='flag-5'>GD32</b>

    GD32 MCU 入门教程】一、GD32 MCU 开发环境搭建(3)使用 Embedded Builder 开发 GD32

    GD32系列为通用型MCU,所以开发环境也可以使用通用型的IDE,目前使用较多的是KEIL、IAR、 GCC和Embedded Builder,客户可以根据个人喜好来选择相应的开发环境。
    的头像 发表于 08-08 16:03 950次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】一、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 开发环境搭建(3)使用 Embedded Builder 开发 <b class='flag-5'>GD32</b>

    GD32 MCU 入门教程】二、GD32 MCU 烧录说明(1)ISP 烧录

    ISP:In System Programing,在系统编程,通过MCU片内的引导程序进行Flash编程。 GD32片内有一个只读信息块,用于存放引导装载程序,引导程序在MCU出厂前就会提前烧录好
    的头像 发表于 08-08 16:20 883次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】二、<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> 烧录说明(<b class='flag-5'>1</b>)ISP 烧录

    GD32 MCU 入门教程GD32 MCU 常见外设介绍(14)RTC 模块介绍

    GD32 MCU内部提供了一个RTC(实时时钟)模块,通过RTC可以实现日历时钟、闹钟等功能。RTC也可以用于深度睡眠或待机模式的低功耗唤醒。不同系列的
    的头像 发表于 08-23 09:18 455次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>常见外设</b><b class='flag-5'>介绍</b>(14)RTC 模块<b class='flag-5'>介绍</b>

    GD32 MCU 入门教程GD32 MCU FPU 使用方法

    GD32 MCU FPU 使用方法
    的头像 发表于 08-25 09:24 573次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> <b class='flag-5'>入门教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> FPU 使用方法

    GD32 MCU入门教程GD32 MCU GPIO 结构与使用注意事项

    本文是专门为基于GD32 MCU开发的工程设计人员提供,主要介绍了GPIO的功能配置、内部结构以及在不同场景使用时的注意事项,旨在帮助GD32 MC
    的头像 发表于 09-07 10:34 722次阅读
    【<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b><b class='flag-5'>入门教程</b>】<b class='flag-5'>GD32</b> <b class='flag-5'>MCU</b> GPIO 结构与使用注意事项