GD32F10x外部晶振配置108MHz系统时钟

2023-05-16

嵌入式_GD32F10x外部晶振配置108MHz系统时钟


文章目录

  • 嵌入式_GD32F10x外部晶振配置108MHz系统时钟
  • 前言
  • 一、时钟树与配置思路
  • 二、时钟配置过程
  • 三、晶振故障排查
  • 总结


前言

由于公司更改硬件设计选择使用新的型号兆易创新国产芯片,需要把以前的软件进行移植,新板子要求新的板子使用的外部8兆晶振,系统时钟要求达到108兆,在配置过程中踩了别人的坑,在此简单记录一下。

注:本项目基于GD32F103CBT6硬件平台, 使用标准库GD32F10x_Firmware_Library_V1.0.0(提示:此库坑多、慎用!


一、时钟树与配置思路

GD32F10x使用M1内核时钟树如图所示,先根据构时钟树构想的配置思路如图上红线路径所示:

A:此处决定PREDV0的时钟源是外部时钟还是PLL1(CL型芯片才有PLL1和PLL2,时钟配置寄存器 1的第16位),我们是HD型芯片,所以配置不了该位,选择默认值0。
B:此处为PREDV0分频因子,时钟配置寄存器 0的第17位,我们选择为外部时钟2分频,得到4MHz时钟
C:此位决定PLL使用0(内部高速时钟)还是1(外部高速时钟),时钟配置寄存器 0的第16位,选择配置为1
D:PLL的倍频因子,时钟配置寄存器 0的第18到21位、29位,我们选择倍频27,4MHz*27 = 108MHz
E:系统时钟选择,决定系统用那一路时钟,时钟配置寄存器 0的第0位与第1位,我们配置为10即可

最终得到108兆系统时钟
在这里插入图片描述

二、时钟配置过程

● 1.在gd32f10x.h文件中修改HSE_VALUE宏的值为:8000000

#if !defined  HSE_VALUE    
#ifdef GD32F10X_CL   
#define HSE_VALUE    ((uint32_t)25000000) /*!< Value of the External oscillator in Hz */
#else 
#define HSE_VALUE    ((uint32_t)8000000) /* !< From 4M to 16M *!< Value of the External oscillator in Hz*/
#endif /* HSE_VALUE */
#endif

● 2.在system_gd32f10x.c文件中修改需要的系统时钟频率宏为:SYSCLK_FREQ_108MHz

代码如下(示例):

/* Uncomment the corresponding line to configure system clock that you need  */ 
/* The clock is from HSE oscillator clock  */
//#define SYSCLK_FREQ_HSE    HSE_VALUE
//#define SYSCLK_FREQ_24MHz  24000000
//#define SYSCLK_FREQ_36MHz  36000000
//#define SYSCLK_FREQ_48MHz  48000000
//#define SYSCLK_FREQ_56MHz  56000000 
//#define SYSCLK_FREQ_72MHz  72000000
//#define SYSCLK_FREQ_96MHz  96000000
#define SYSCLK_FREQ_108MHz  108000000

/* Uncomment the corresponding line to configure system clock that you need  */ 
//#define SYSCLK_FREQ_48MHz_HSI  48000000 
/* The clock is from HSI oscillator clock  */
//#define SYSCLK_FREQ_72MHz_HSI  72000000
//#define SYSCLK_FREQ_108MHz_HSI  108000000

然后在system_gd32f10x.c文件中你就可以看到108兆时钟配置函数

static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
  SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
  SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
  SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
  SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
  SetSysClockTo56();  
#elif defined SYSCLK_FREQ_72MHz
  SetSysClockTo72();
#elif defined SYSCLK_FREQ_96MHz
  SetSysClockTo96();
#elif defined SYSCLK_FREQ_108MHz				//根据宏自动选择该配置函数
  SetSysClockTo108();
#elif defined SYSCLK_FREQ_48MHz_HSI
  SetSysClockTo48HSI();
#elif defined SYSCLK_FREQ_72MHz_HSI
  SetSysClockTo72HSI();
#elif defined SYSCLK_FREQ_108MHz_HSI
  SetSysClockTo108HSI();
#endif
 
}

● 3.在system_gd32f10x.c 文件中修改SetSysClockTo108();
一般情况下是不用修改该函数的,但是我直接使用时踩了个坑,时钟频率不对,然后返回来检查寄存器时分析了这个函数,这里简单说一下作为个人笔记,大佬可以自动跳过。
最主要是这里:
RCC->GCFGR |= (uint32_t)( RCC_GCFGR_PLLPREDV_HSE_DIV2 | RCC_GCFGR_PLLSEL_HSE | RCC_GCFGR_PLLMF27);
RCC_GCFGR_PLLPREDV_HSE_DIV2:这里配置时钟树图的 B处
RCC_GCFGR_PLLSEL_HSE:这里配置时钟树图的 C处
RCC_GCFGR_PLLMF27:这里配置时钟树图的 D处
检查了一遍根据寄存器,显示的值都没问题,但调试到选择则PLL作为系统时钟这句就有问题:
RCC->GCFGR |= (uint32_t)RCC_GCFGR_SCS_PLL;
通过函数RCC_GetClocksFreq(&RCC_Clockstruct)抓出来的时钟频率全是乱的

代码如下(示例):

static void SetSysClockTo108(void)
{
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
  
  /* CK_SYS, AHB, APB2 and APB1 configuration ---------------------------*/    
  /* Enable HSE */    
  RCC->GCCR |= ((uint32_t)RCC_GCCR_HSEEN);
 
  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    HSEStatus = RCC->GCCR & RCC_GCCR_HSESTB;
    StartUpCounter++;  
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));

  if ((RCC->GCCR & RCC_GCCR_HSESTB) != RESET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }  

  if (HSEStatus == (uint32_t)0x01)
  {
    /* AHB = CK_SYS not divided */
    RCC->GCFGR |= (uint32_t)RCC_GCFGR_AHBPS_DIV1;
      
    /* APB2 = AHB not divided */
    RCC->GCFGR |= (uint32_t)RCC_GCFGR_APB2PS_DIV1;
    
    /* APB1 = AHB is divided 2 */
    RCC->GCFGR |= (uint32_t)RCC_GCFGR_APB1PS_DIV2;

#ifdef GD32F10X_CL
    /* Configure PLLs ------------------------------------------------------*/

    /* PLL configuration: PLLCLK = PREDIV1 * 9 = 108 MHz */ 
    RCC->GCFGR &= (uint32_t)~(RCC_GCFGR_PLLPREDV | RCC_GCFGR_PLLSEL | RCC_GCFGR_PLLMF);
    RCC->GCFGR |= (uint32_t)(RCC_GCFGR_PLLPREDV_PREDIV1 | RCC_GCFGR_PLLSEL_PREDIV1 | RCC_GCFGR_PLLMF9); 

    /* PLL2 configuration: PLL2CLK = (HSE / 5) * 12 = 60 MHz */
    /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 12 MHz */
        
    RCC->GCFGR2 &= (uint32_t)~(RCC_GCFGR2_PREDV2 | RCC_GCFGR2_PLL2MF |
                              RCC_GCFGR2_PREDV1 | RCC_GCFGR2_PREDV1SEL);
    RCC->GCFGR2 |= (uint32_t)( RCC_GCFGR2_PREDV2_DIV5 | RCC_GCFGR2_PLL2MF12 |
                             RCC_GCFGR2_PREDV1SEL_PLL2 | RCC_GCFGR2_PREDV1_DIV5);
  
    /* Enable PLL2 */
    RCC->GCCR |= RCC_GCCR_PLL2EN;
    /* Wait till PLL2 is ready */
    while((RCC->GCCR & RCC_GCCR_PLL2STB) == 0)
    {
    }

#else     
    /* PLL configuration: PLLCLK = (HSE/2) * 27 = 108 MHz */
    RCC->GCFGR &= (uint32_t)((uint32_t)~(RCC_GCFGR_PLLSEL | RCC_GCFGR_PLLPREDV | RCC_GCFGR_PLLMF));
    RCC->GCFGR |= (uint32_t)( RCC_GCFGR_PLLPREDV_HSE_DIV2 | RCC_GCFGR_PLLSEL_HSE | RCC_GCFGR_PLLMF27);

#endif /* GD32F10X_CL */

    /* Enable PLL */
    RCC->GCCR |= RCC_GCCR_PLLEN;

    /* Wait till PLL is ready */
    while((RCC->GCCR & RCC_GCCR_PLLSTB) == 0)
    {
    }

    /* Select PLL as system clock source */
    RCC->GCFGR &= (uint32_t)((uint32_t)~(RCC_GCFGR_SCS));
    RCC->GCFGR |= (uint32_t)RCC_GCFGR_SCS_PLL;    

    /* Wait till PLL is used as system clock source */
    while ((RCC->GCFGR & (uint32_t)RCC_GCFGR_SCSS) != (uint32_t)0x08)
    {
    }
  }
  else
  { 
  } 
}

三、晶振故障排查

软件排查基本没问题那就只能看硬件了,晶振使用的是晶科JX-S25A系列的一个8兆贴片晶振其原理图为:在这里插入图片描述
使用示波器打一下晶振并联电阻两端都没有波形,然后测了一下并联电阻阻值只有9.8千欧,原理图为1M欧,所以阻值太小了,多半是焊错了,然后把电阻挑了继续拿示波器打,波形一下就出来了,周期为125ns,也确实是8MHz
在这里插入图片描述
后面专门去查了原因,给晶振并联一个M级电阻是为了使本来为逻辑反相器的器件工作在线性区, 以获得增益, 在饱和区不存在增益, 而在没有增益的条件下晶振不起振。简而言之,并联1M电阻增加了电路中的负性阻抗(-R),即提升了增益,缩短了晶振起振时间,达到了晶振起振更容易之目的。但是因为晶振本身阻抗是很大的,所以也可以不焊接并联电阻,如果要焊并联电阻就必须足够大,刚刚的1千欧就太小了,等效电阻小于1千欧就没有波形。
也有给晶振串联K级别电阻用来预防晶振过驱,限制振荡幅度。


总结

如有错误,欢迎指正,原创不易,转载留名!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GD32F10x外部晶振配置108MHz系统时钟 的相关文章

  • 你知道几个中文编程语言,快来瞧瞧这些有趣的中文编程语言。

    提到编程语言 xff0c 我们所了解的也是比较广为人知的一些主流编程语言 xff0c 如Java C C 43 43 Python PHP等 那除了这些编程语言 xff0c 你有了解过中文编程语言吗 xff1f 如果没有 xff0c 那今天
  • Win10连接无线“需要执行操作”或无网络问题的解决方法。

    转载自品略图书馆 http www pinlue com article 2020 03 2800 3510060445349 html 最近这几天有用户反馈Win10系统连接网络出现异常的问题 xff0c 表现为连接到无线网络WIFI之后
  • Excel怎么比较两列文本是否相同?

    转载自品略图书馆 http www pinlue com article 2020 05 2215 1410586873210 html 这个问题很简单 xff0c 属于Excel基础操作技巧 xff0c 我就分享我最喜欢用的三招给你 xf
  • 为什么电脑唯独搜不到自己家wifi?

    转载自品略图书馆 http www pinlue com article 2020 05 2213 2410586244619 html 电脑唯独搜不到自己家wifi xff0c 别人家的都能搜到 xff0c 手机也可以搜到自己家的 xff
  • http://和www.前缀网站有什么具体区别?

    转载自品略图书馆 http www pinlue com article 2019 03 1813 598231572617 html 将http 和www 放一起比较 xff0c 是没有实际意义的 一 http协议二 域名一 http协议
  • 什么是三层交换机、网关、DNS、子网掩码、MAC地址?

    转载自品略图书馆 http www pinlue com article 2020 08 2313 2511146576256 html 一文讲懂什么是三层交换机 网关 DNS 子网掩码 MAC地址 很多朋友多次问到什么是网关 dns 子网
  • C++类对象共享数据的5种实现方法

    转自 xff1a http www pinlue com article 2020 09 2617 0611262487540 html
  • c语言free的用法

    转自 xff1a http www pinlue com article 2020 03 3100 4610073901713 html
  • Spring Boot 修改默认端口号

    修改配置文件 xff0c 加上参数 xff1a server port 61 8014 或者 xff1a server port 8014 启动后可发现tomcat运行在端口8014上了 实现原因可看以下链接 转载 SpringBoot修改
  • php调用类中的方法

    转自 xff1a http www pinlue com article 2020 06 1219 0410725563037 html
  • 人工智能 : 第三篇”脑机接口“

    本文作者Tim Urban xff1a Wait but Why的作者Tim Urban 是埃隆马斯克 xff08 特斯拉 SpaceX创始人 xff09 强烈推荐的科技博主 他写的AI文章是全世界转发量最高的 他的粉丝还包括 xff1a
  • 如何找回一台丢失的Win10电脑?

    今天说说如何找电脑 为什么小微想到了这个问题 还要从一次关于奇葩办公地点的讨论说起 看到大家的回答 xff0c 小微佩服得五体投地 办公经历还可以如此精jing彩xin绝dong伦po 作为结实靠谱的出行伙伴 ThinkPad陪伴大家出现在
  • 不必再狂按空格键了!Word 里文字对齐推荐这4种方法

    我们在用Word写论文 制作简历的时候 xff0c 通常会遇到把word中某些特定文字对齐的情况 那么问题来了 xff0c 你平时都是怎么对齐文字的 xff1f 傻傻的用空格来对齐吗 xff1f 在字符数不等的情况下 xff0c 加空格不仅
  • AMI主板BIOS菜单图文讲解设置!

    电脑硬件 xff0c 包括电脑中所有物理的零件 xff0c 以此来区分它所包括或执行的数据和为硬件提供指令以完成任务的软件 主要包含 机箱 xff0c 主板 xff0c 总线 xff0c 电源 xff0c 硬盘 xff0c 存储控制器 xf
  • luffy-02

    这里写目录标题 一 昨日回顾二 今日内容1 路飞前台配置 1 重构项目目录 2 文件修订 xff1a 目录中非配置文件的多余文件可以移除router的使用 3 前台配置 全局样式 配置文件 axios vue cookies element
  • luffy-03

    这里写目录标题 一 昨日回顾二 今日内容1 跨域问题1 1后端自己处理跨域简单请求非简单请求中间件处理 1 2前端处理跨域App vuevue config js 2 头部组件 尾部组件components Header vuecompon
  • luffy-04

    这里写目录标题 一 昨日回顾二 今日内容1 路飞项目使用xadmin2 首页轮播图接口 轮播图表 视图类 轮播图数量4 通过配置实现 前端对接 后续 接口缓存 3 git的使用3 1git的工作流程 4 git分支git提交代码出现冲突的2
  • luffy-05

    这里写目录标题 一 首页轮播图接口二 今日内容1 过滤文件2 从远端拉项目3 远程仓库3 1链接远程仓库的两种情况 4 冲突出现的原因及解决 一 首页轮播图接口 span class token number 1 span 首页轮播图接口
  • 手把手教你搭建鸿蒙hi3518开发和运行环境

    前言 学习 C 语言 xff0c C 43 43 语言 xff0c 数据结构和算法 xff0c 操作系统 xff0c 网络 xff0c 驱动 xff0c 设计模式等知识 用鸿蒙来强化就太对了 本文教你一步一步搭建鸿蒙的开发和运行环境 xff
  • luffy-06

    这里写目录标题 一 上节回顾二 今日内容1 ssh链接和https链接2 gitlab3 git远程分支合并4 git冲突出现原因及解决5 首页登录注册vue页面Header vueLogin vue 6 登录注册功能接口分析 一 上节回顾

随机推荐

  • luffy-07

    这里写目录标题 一 昨日回顾二 今日内容1 登录注册前端页面1 1Login vue1 2Register vue1 3Header vue 2 多方式登录接口3 手机号是否存在接口3 1路由层user urls py3 2user ser
  • luffy-08

    这里写目录标题 一 集成了腾讯短信 封装 luffyapi lib t sms settings pyluffyapi lib t sms sms py 二 短信验证码接口2 1路由 配置2 2视图 三 短信登录接口3 1视图3 2序列化类
  • luffy-09/redis

    这里写目录标题 一 昨日回顾二 今日内容1 redis介绍2 redis的Windows安装和配置3 普通链接和连接池3 1代码3 2redis pool py 4 redis之string操作5 redis之hash操作 一 昨日回顾 s
  • luffy-10/redis/celery简单介绍

    这里写目录标题 一 昨日回顾二 今日内容2 1redis之列表操作2 2 redis之其他操作2 3 redis之管道2 4 django中使用redis2 4 1通用方案redis pool pyviews py 2 4 2django提
  • luffy-11/celery

    这里写目录标题 一 昨日回顾二 今日内容1 celery基本使用2 celery多任务结构多任务结构小案例 3 高级使用之延时任务4 高级使用之定时任务5 django中使用celery6 首页轮播图定时更新6 1首页轮播图走redis缓存
  • luffy-12/课程页面前端,课程表数据录入,课程表分析,编写

    这里写目录标题 一 昨日回顾二 今日内容2 1课程页面前端2 2课程表分析 编写修改之前的一些数据 2 3课程表数据录入2 4课程分类接口 一 昨日回顾 span class token number 1 span celery span
  • luffy-13/课程接口,课程详情前台

    这里写目录标题 一 课程接口1 1 course serializer py1 2 course models py1 3course pagenation py1 4course SearchByName py1 5course view
  • luffy-14/课程详情,课程章节接口,课程详情前台,七牛云对象存储托管视频

    这里写目录标题 一 课程详情接口 课程章节接口1 1课程详情接口1 2课程章节接口1 3序列化类1 4路由 二 课程详情前台三 七牛云对象存储托管视频四 区间过滤 一 课程详情接口 课程章节接口 span class token numbe
  • luffy-15/区间过滤,搜索功能前端后端,支付宝

    这里写目录标题 一 区间过滤二 搜索功能2 1后端代码2 2前端搜索页面2 2 1views SearchCourse vue2 2 2router index js2 2 3components Header vue 三 支付宝3 0结构
  • QT工程:error: undefined reference to `QSerialPort::QSerialPort(

    问题 xff1a qt中使用QSerialPort时报错 error undefined reference to 96 QSerialPort QSerialPort 解决办法 xff1a 工程文件 pro里增加 xff1a QT 43
  • luffy-16/订单表设计,立即付款接口/前端,支付成功get回调用户展示,支付成功post回调修改订单状态

    这里写目录标题 一 昨日回顾二 今日内容1 订单表设计2 立即付款接口 一堆校验 登录后 2 1视图类2 2序列化类2 3自定义异常类2 4配置文件2 5路由 3 立即付款前端4 支付成功get回调用户展示4 1luffycity src
  • luffy-17/上线

    这里写目录标题 一 上节回顾二 今日内容1 购买阿里云服务器2 服务器配置 软件安装2 1更新系统软件包2 2安装mysql2 3安装redis2 4安装python3 62 5配置pip源 xff1a 阿里云不用配置 xff0c 默认配置
  • bs4遍历文档树,搜素文档树,find_all参数,selenium,模拟登陆百度

    这里写目录标题 一 昨日回顾二 今日内容1 bs4遍历文档树2 bs4的搜索文档树3 find all的其他参数4 css选择器5 selenium的介绍6 selenium的使用7 模拟登陆百度8 selenium的其他使用 一 昨日回顾
  • xpath的使用,selenium爬取京东商品信息,scrapy介绍,安装及使用

    这里写目录标题 一 xpath的使用二 selenium爬取京东商品信息三 scrapy的架构3 1scrapy的架构3 2目录介绍 四 scrapy的简单使用 一 xpath的使用 span class token number 1 sp
  • go语言值变量命名规范,定义变量,数据类型,常量,函数基础,函数高级

    这里写目录标题 一 昨日回顾二 今日内容1 变量命名规范2 变量代码演示 3 类型代码演示 4 常量5 函数基础6 函数高级 一 昨日回顾 span class token number 1 span redis高级 span class
  • 串口接收一帧数据及解析

    3 xff0e 下位机中的数据接收和协议解析 下位机接收数据也有两种方式 xff0c 一 等待接收 xff0c 处理器一直查询串口状态 xff0c 来判断是否接收到数据 二 中断接收 两种方法的优缺点在此前的一篇关于串口通信的文章中详细讨论
  • <string>库常用的函数

    include lt string h gt 库包含字符串处理函数 xff0c 常用的有strcpy strcat strcmp strchr等 1 strcpy是字符串赋值函数 char strcpy char target char s
  • APM(Ardupilot)——电机输出流程图

    电机类声明 xff1a system cpp void Copter allocate motors void switch AP Motors motor frame class g2 frame class get if FRAME C
  • C++中的三个特殊宏:__FILE__,__FUNCTION__和__LINE__

    C 43 43 中的三个特殊宏 xff1a FILE xff0c FUNCTION 和 LINE 1 FILE 宏 FILE 宏用于检查当前文件名 xff0c 例如 xff1a include lt cstdio gt using name
  • GD32F10x外部晶振配置108MHz系统时钟

    嵌入式 GD32F10x外部晶振配置108MHz系统时钟 文章目录 嵌入式 GD32F10x外部晶振配置108MHz系统时钟前言一 时钟树与配置思路二 时钟配置过程三 晶振故障排查总结 前言 由于公司更改硬件设计选择使用新的型号兆易创新国产