文章目录

  • GD32与STM32异同
    • 1. 相同点
    • 2. 外围硬件区别
    • 3. 内部结构差别
    • 4. 功耗区别(以128k以下容量的作为参考)
    • 5. 内部FLASH 区别
  • 使用STM32库开发
    • 时钟配置
      • 区别
        • 1. 晶振起振区别
          • 描述
          • 解决方法
        • 2. 部分客户使用有源晶振出现问题,在 GD32F103 小容量产品,发现会在 MCU 的复 位管脚一直把电平拉到0.89V,电平不能保持在高电平
          • 描述
          • 解决方法
        • 3. GD32 MCU 主频支持 108MHz 高性能,在代码移植方面需要注意事项
      • 1. 以72MHz运行
      • 2. 以108MHz运行(方法一)
        • 原因
          • 为什么要加这样的代码
          • 为什么是+=15
      • 3. 以108MHz运行(方法二)
        • 移植的代码
      • 参考
    • Flash配置
      • 1. 芯片设置读保护用法
        • 描述
        • 解决方法
      • 2. IAP在应用中编程
        • 描述
        • 解决方法
    • 其他
  • 参考

GD32与STM32异同

来自:https://blog.csdn.net/qq_15181569/article/details/105472881

1. 相同点

  1. 外围引脚定义:
    相同型号的管脚定义相同
  2. Cortex M3 内核:
    STM32F103 内核 R1P1 版本, STM32F205 内核 R2P1,GD32 内核 R2P1 版本,此内核修复了 R1P1 的一些 bug
  3. 芯片内部寄存器,外部 IP 寄存器地址 :
    逻辑地址相同,主要是根据STM32 的寄存器和物理地址,做的正向研发.
  4. 函数库文件:
    函数库相同,优化需要更改头文件
  5. 编译工具:
    完全相同 例如:keil MDK、IAR
  6. 型号命名方式:
    有一点点不一样
/*从上面的代码可以看出,GD32和STM32的命名有点不应样,去掉了低密度产品的选择并到了中密度产品中MD,增加了超大密度的产品选择XD。MD中包含的FLASH大小为:16,32,64,128,256HD中包含的FLASH大小为:384,512,768,1024XD中包含的FLASH大小为:2018,3072CL为互联型产品:包含107和105+网络接口型系列
*/
#define GD32F10X_MD   //GD32F103C8T6

2. 外围硬件区别

  1. 电压范围(ADC):
GD32F STM32F
外部电压 2.6-3.6V 2.0-3.6V
内核电压 1.2V 1.8V
  1. BOOT 0 管脚:
    Flash程序运行时,BOOT0在 STM32上可悬空,GD32 必须外部下拉(从 Flash 运行,BOOT0必须下拉地)

  2. ESD参数:
    STM32 人体模式 2KV,空气模式500V
    GD32 人体模式 4KV(内测5KV),空气模式 10KV(内测 15KV)

3. 内部结构差别

  1. 启动时间:
    GD32 启动时间相同,由于GD 运行稍快,需要延长上电时间配置(2ms)
  2. 主频时钟:
    GD32F10系列主频 108MHZ STM32F10 系列主频 72MHZ
  3. Flash擦除时间:
    GD32 是60ms/page,STM 30ms/page
  4. FLASH 容量:
    GD32 最大容量 3M Byte
  5. SRAM空间:
    GD32F103 系列、GD32F105\107大容量系列 SRAM 96K
  6. VB 外扩总线 FSMC:
    GD32 100PIN 配置总线输出,STM32 144PIN并且 256k 以上才配置总线输出

4. 功耗区别(以128k以下容量的作为参考)

GD32F STM32F10X
睡眠模式 Sleep 12.4mA 7.5mA
深度睡眠模式Deep Sleep 1.4mA 2.5uA
待机模式 Stand By 10.5uA 3.4uA
运行功耗 32.4mA/72M 52mA/72M

5. 内部FLASH 区别

  1. ISP:
    擦写时间同STM32 有差异,使用新版ISP 软件
  2. IAP:
    擦写时间相同,按字写入,按页擦除
  3. 存储寿命:
    10万次擦写,数据保存 20 年以上
  4. 加密特性:
    除了常规的禁止读出和96位 ID号码加密之外,GD32 数据写入Flash 时,具有存储逻辑地址连续,物理地址不连续的特性。

使用STM32库开发

下面都是以 GD32F103C8t6 为例

在查找了网上的相关资料后,接下来就是选择是用GD32固件库开发还是STM32的固件库开发了。

我个人是不喜欢再花时间去了解GD32的库了,而且看了一下,貌似还挺麻烦的,而且突然也想试试自己移植一下GD32,也就是用STM32的库(做部分修改和移植)去开发GD32。

GD32官方例程和模板下载地址:http://www.gd32mcu.com/cn/download/6?kw=GD32F1

GD32F10x 标准固件库:

GD32F103xx 数据手册:

用户手册和库函数使用指南:

时钟配置

首先肯定是系统时钟配置了,打开GD32官方的例程,打开 start_gd32f10x_cl.s ,然后找到系统初始化函数

沿着这条线一直找,最后找到 static void system_clock_108m_hxtal(void) 这个函数,看名字也知道是把系统时钟初始化到108MHz。

其中:

/* AHB = SYSCLK */
/* APB2 = AHB/1 */
/* APB1 = AHB/2 */
/* select HXTAL/2 as clock source */
/* CK_PLL = (CK_HXTAL/2) * 27 = 108 MHz */

区别

下面说下打开要改些什么东西

1. 晶振起振区别

描述

启动时间,GD32 与 STM32 启动时间都是 2ms,实际上 GD 的执行效率快,所以ST 的

HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)

是2ms,但是这个宏定义值在GD 上时间就更加短了,所以要加大这个值的设置

解决方法

将宏定义:

#define HSE_STARTUP_TIMEOUT ((uint16_t)0x0500)

修改为:

#define HSE_STARTUP_TIMEOUT ((uint16_t)0xFFFF)

备注:启动时间宏定义所在位置:

  1. 在V3.X 的库,其启动时间宏定义在 stm32f10x.h 头文件中
    (路径:…\Libraries\CMSIS\CM3)。(库版本的不同,所在目录也有所不同)
  2. 在 V3.0 以前的库,其启动时间宏定义在 stm32f10x_rcc.c 源文件中 (HSEStartUp_TimeOut)

其实通过看GD32的固件库代码也可以知道,在GD32中,这个数值也是 ((uint16_t)0xFFFF) 所以直接改就好了

2. 部分客户使用有源晶振出现问题,在 GD32F103 小容量产品,发现会在 MCU 的复 位管脚一直把电平拉到0.89V,电平不能保持在高电平

描述

是由于部分有源晶振起振时间太快,复位信号还没有完成导致的

解决方法

就是在有源晶振的输入端与地之前并上一个30pf 电容

3. GD32 MCU 主频支持 108MHz 高性能,在代码移植方面需要注意事项

GD32 通过芯片内部加大缓存,提高了相同工作频率下的代码执行速度,带来 了高性能的使用体验。

因此如果代码有用到for 循环或while 循环语句做精确定时的,定时时间会由 于代码执行速度加快而使循环的时间变短。使用Timer 定时器则没有影响。

1. 以72MHz运行

只需要修改上面提到的 HSE_STARTUP_TIMEOUT 把这个从 ((uint16_t)0x0500) 改为 ((uint16_t)0xFFFF)

2. 以108MHz运行(方法一)

  1. 首先肯定是把 system_stm32f10x.c 中的宏注释掉,然后手动添加新的108MHz的宏

  1. 因为改了宏,下面通过宏来给 SystemCoreClock 赋值也要修改

  1. 然后还要修改通过宏来选择的函数,就是用来初始化系统时钟配置的,最主要的函数(这个函数是本来没有的,自己设置的)

  1. 同理,这个也要修改

  1. 最后实现108MHz的函数,可以在文件最下面实现

代码如下:

#elif defined SYSCLK_FREQ_108MHz
/*** @brief  使用内部时钟倍频到108MHz * @note   This function should be used only after reset.* @param  None* @retval None*/
#define  RCC_CFGR_PLLMULL27                 ((uint32_t)0x08280000)
static void SetSysClockTo108(void)
{/* Enable Prefetch Buffer */FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;    /* HCLK = SYSCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;/* PCLK2 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;/* PCLK1 = HCLK */RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;/*  PLL configuration: PLLCLK = HSI * 27 = 108 MHz */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |RCC_CFGR_PLLMULL));RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLMULL27);/* Enable PLL */RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */while((RCC->CR & RCC_CR_PLLRDY) == 0){}/* Select PLL as system clock source */RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;    /* Wait till PLL is used as system clock source */while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}
}
#endif
  1. 还没结束,这样的话可以实现108MHz,但会有BUG,还需要修改
    void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
    这个函数

增加一段这样的代码就可以了

 /* 在读完 */if (RCC->CFGR & 0x08000000) //取27位{pllmull += 15;}

原因

为什么要加这样的代码

看cubemx的stm32f103c8t6的时钟配置,可以直观的看到整个系统时钟的结构

首先我们看STM32在正常情况下(也就是用72MHz,不修改时钟,并使用GD32开发板),RCC_CFGR 寄存器的数值

18~21bit 是PLL的倍频系数,数值是 0111 换成十进制加2就刚好是9,和上图cubemx中PLL的倍频系数对应,(+2也和stm32固件库里面的代码处理对应)

然后我们再看在使用直接使用GD32的固件库下(也就是用108MHz,修改时钟,使用GD32开发板),RCC_CFGR 寄存器的数值

下面放到一起对比一下

//  28   24   20   16   12    8    4    00000 0000 0001 1101 0000 0100 0000 1010   //STM320000 1000 0010 1011 0000 0100 0000 1010   //GD32
//不一样的
//第27bit  |  18~21bit  |  17bit  |
  • 27bit
    (下面会有解释,其实 “对应” 着29bit

    来自GD32F103xx用户手册

    来自STM32F10x中文参考手册

  • 18~21bit
    是PLL的倍频系数

    来自GD32F103xx用户手册

    来自STM32F10x中文参考手册

  • 17bit
    这里暂时没搞懂为什么17bit会不一样

    来自GD32F103xx用户手册

    来自STM32F10x中文参考手册

因为在stm32的参考手册里面,RCC_CFGR 寄存器的第27位是保留的,也就是不使用的,所以stm32标准库的代码里面直接没做27位处理,而这个函数(void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) )又是usart、spi等外设用来计算时钟频率的所以,必须得做一点处理,不然就会出现串口乱码等BUG

不做处理时数值是 10101010 换成十进制加2,就刚好是12,但12不对啊,我们要的是27(GD32的PLL倍频系数)

这时候我们加上一个判断,判断第27位置是否为1,为1的话就肯定是GD32了,因为STM32的27位是保留的,然后再加上15就刚好是27,也就和GD32固件库的PLL倍频系数对应:

⚠️ ⚠️ ⚠️ 这里大家应该都发现了个问题,,,明明数据手册上写的是29位共同构成倍频因子,但实际上29位却根本写不进去,实际上看GD32的固件库也确实是第27位不一样,那没办法了,我们只能相信手册错了。(手册是直接在官网下载的最新版本)

在这里卡了半天,最后终于发现了这篇文章。原来不止我一个人有这个问题。

参考:GD32F103单片机设置时钟到108MHz,串口波特率错误的问题?

为什么是+=15

如果27(其实应该是29)位为1的话,其实就是多了 0x1 0000 也就是,相当于加了 15(0x111)

最后,不出意外的话查看寄存器应该是正确的

3. 以108MHz运行(方法二)

上面(方法一)中,是直接移植了GD32的 void SystemInit(void) 函数,然后直接在主函数开开头添加或者直接修改启动文件

这里是把 SystemInit 改名改为 GD_SystemInit

但还是需要修改:

  • stm32f10x_rcc.c 中的 void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks) 函数

  • stm32f10x.h 中的 HSE_STARTUP_TIMEOUT

修改方式和上面一样

移植的代码

其实就是把GD32 GD_SystemInit 函数相关的代码全部复制过来STM32这里了,并稍微修改了一下,(可能算不上移植吧,这种方式并不优雅,但能力有限,也就只能这样了,,)

移植代码的下载连接:https://download.csdn.net/download/K_O_R_K/26541189

参考

  • GD32F103 108M配置串口乱码解决
  • GD32移植到STM32开发平台_喜欢做我自己的博客-程序员宅基地

Flash配置

1. 芯片设置读保护用法

描述

由于 GD 的 Flash 是自己的专利技术,STM 的 Flash 是第三方提供的,所以 GD 的 Flash 和STM 的Flash 有些许差异。GD 的擦除时间会长一点

解决方法

在写完KEY 序列以后,需要读该位,确认key 已生效。 所以,这里应该插入

While( ! (FLASH->CR & 0x200 ) );    // Wait OPTWRE     /或者/__NOP();__NOP();  //简单的插入两个 __NOP();

在 ST 库中,只有:

  • FLASH_Status FLASH_EraseOptionBytes(void)

  • FLASH_Status FLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data)

  • FLASH_Status FLASH_EnableWriteProtection(uint32_t FLASH_Pages)

  • FLASH_Status FLASH_ReadOutProtection(FunctionalState NewState)

    四个函数需要修改:

2. IAP在应用中编程

描述

GD32 由于自有flash 的0 访问时序,同 STM32 在 Flash 的 Erase 和 Program 上 存在差别,GD32 的 Erase 和 Program 时间比 STM32 的稍微长些,建议对 Erase 和Program 时间进行修改。

解决方法

将宏定义

//#define EraseTimeout          ((uint32_t)0x000B0000)
//#define ProgramTimeout        ((uint32_t)0x00002000)

修改为:

#define EraseTimeout          ((uint32_t)0x000FFFFF)
#define ProgramTimeout        ((uint32_t)0x0000FFFF)

备注 : Erase 和 Program 时间宏定义 在 stm32f10x_flash.c 源文件中

其他

目前只测试了 FLASH 、IAP、usart、时钟,其他的没用到,所以暂时没搞

参考

  • GD32移植到STM32开发平台_喜欢做我自己的博客-程序员宅基地
  • GD32F103单片机设置时钟到108MHz,串口波特率错误的问题?
  • GD32替代STM32全过程记录
  • GD32替换STM32注意事项!!!
  • GD32移植到STM32开发平台

使用STM32固件库开发GD32 汇总相关推荐

  1. 文末赠书《GD32 MCU原理及固件库开发指南》5本 | 国产MCU中GD32系列有望成为未来32位MCU的主流

    学习优秀博文([guo产MCU移植]手把手教你使用RT-Thread制作GD32系列BSP)有感 一篇优秀的博文是什么样的?它有什么规律可循吗?优秀的guo产32位单片机处理器是否真的能成功替换掉st ...

  2. STM32固件库移植(开发环境的搭建)

    STM32固件库移植(开发环境的搭建) 以下过程是手动移植,过程繁琐,不感兴趣的可以绕路学习CubeMX. 下文阐述两种基本开发环境的搭建方法,HAL库的添加将放在下期 1.基本开发环境的搭建 先创一 ...

  3. STM32 HAL库开发转固件库开发杂谈

    前言 本文使用代码工程 STM32HAL库开发转固件库开发杂谈-嵌入式文档类资源-CSDN文库 STM32 最早提供固件库开发,在当时也是一个很大的创新.导致大量攻城狮熟悉了固件库开发,后面STM32 ...

  4. 【致敬未来的攻城狮计划】第2期定向赠书《RT-Thread设备驱动开发指南》+ 《GD32 MCU原理及固件库开发指南》

    开启攻城狮的成长之旅!这是我参与的由 CSDN博客专家 架构师李肯(超链接:http://yyds.recan-li.cn)和 瑞萨MCU (超链接:瑞萨电子 (Renesas Electronics ...

  5. 【08】STM32·HAL库开发-HAL库介绍 | STM32Cube固件库介绍 | HAL库框架结构 | 如何使用HAL库及使用注意事项

    目录 1.初识HAL库(了解) 1.1CMSIS简介 1.2HAL库简介 2.STM32Cube固件包浅析(了解) 2.1如何获取STM32Cube固件包? 2.2STM32Cube固件包文件夹简介 ...

  6. 了解库开发,我们从STM32标准库开发学起

    摘要:从STM32新建工程.编译下载程序出发,让新手由浅入深,尽享STM32标准库开发的乐趣. 自从CubeMX等图像配置软件的出现,同学们往往点几下鼠标就解决了单片机的配置问题.对于追求开发速度的业 ...

  7. 第9章 初识STM32固件库—零死角玩转STM32-F429系列

    第9章     初识STM32固件库 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/fire ...

  8. STM32 固件库,CMSIS 标准,STM32Cube

    STM32 固件库与 CMSIS 标准讲解 STM32F4 固件库就是函数的集合,那么对这些函数有什么要求呢? 这里就涉及到一个 CMSIS 标准的基础知识.经常有人问到 STM32 和 ARM 以及 ...

  9. STM32固件库文件树及构成详解

    (想要pfd格式文件的可以留下邮箱) STM32固件库文件树及构成详解(库版本:STM32F10x_StdPeriph_Lib_V3.5.0) 库减压后所有文件夹构成如下: /

  10. STM32固件库文件分析

    STM32固件库文件分析 1.汇编编写的启动文件 startup/stm32f10x.hd.s:设置堆栈指针,设置pc指针,初始化中断向量,配置系统时钟,对用c库函数_main最后去c语言世界里. 2 ...

最新文章

  1. java获取随机值的方法
  2. php rdkafka实例,linux下php扩展kafka的实例分享
  3. MySQL(9)主从复制与读写分离
  4. python selenium p_python selenium 常见问题列表
  5. 【CSS3】-webkit-margin-before与margin-top
  6. 原型模式 —— Java的赋值、浅克隆和深度克隆的区别
  7. 领域驱动设计,让程序员心中有码(二)
  8. ASP.NET Core Docker部署
  9. LeetCode之Reverse Integer
  10. SpringBootAdmin
  11. 两个时间之间是多少小时_那是两个小时我不会回来
  12. 编码Java时的10个微妙的最佳实践
  13. 如何通过Graph+AI的方法打造高精度风控模型
  14. KafkaProducer介绍
  15. Oracle 9i和10g安装后的基本环境与服务
  16. HTTP协议详解(必看)
  17. 数字化是实现“跨界打劫”的超级武器
  18. android+x86+远程桌面,Chrome远程桌面和Android模拟器
  19. 动态gif图如何裁剪?一个小窍门教你在线裁剪动图
  20. 5.11 Go语言文本大数据处理(2):文件分割与入库

热门文章

  1. java音乐网站论文_基于Java web的音乐网站的设计与实现论文(含源文件).doc
  2. centos 7 sogou input
  3. 草根站长胖子讲述做站故事
  4. 计算机用户注册表修改,WindowsServer2012 注册表修改用户的连接数
  5. Leaflet加turf生成等值线图(或色斑图)并单击显示值
  6. c语言编程能力提高,C语言编程能力的培养
  7. 《21天学通Java(第6版)》—— 2.10 认证练习
  8. 计算机软件处理化学数据,化学中的常用计算机软件与资源程功臻武汉大学化学系计算机作为一.pdf...
  9. 计算机打印不了测试纸,XP打印机打印不了测试页如何解决|打印机打印不了测试页的原因...
  10. 数模美赛-层次分析模型方法(评价类问题)