GD32 介绍与 STM32 兼容性汇总

发新帖
发表于 2017-9-12 10:40:52 | 显示全部楼层 |阅读模式
分享:
查看: 1141|回复: 0
GD32 介绍与 STM32 兼容性汇总一、 GD32 与 STM32 异同1. 相同点1)外围引脚定义:相同型号的管脚定义相同2)Cortex M3 内核:STM32F103 内核 R1P1 版本, STM32F205 内核 R2P1,GD32 内核 R2P1 版本,此内核修复了 R1P1 的一些 bug3)芯片内部寄存器,外部 IP 寄存器地址 :逻辑地址相同,主要是根据 STM32 的寄存器和物理地址,做的正向研发.4)函数库文件:函数库相同,优化需要更改头文件5)编译工具:完全相同 例如:keil MDK、IAR6)型号命名方式:完全相同2. 外围硬件区别1) 电压范围(ADC): GD32F: 2.6-3.6V STM32F: 2.0-3.6V(外部电压) GD32F: 1.2V(内核电压)STM32F: 1.8V(内核电压)2) BOOT 0 管脚: Flash 程序运行时,BOOT0 在 STM32 上可悬空,GD32 必须外 部下拉(从 Flash 运行,BOOT0 必须下拉地)3) ESD 参数: STM32 人体模式 2KV,空气模式 500VGD32 人体模式 4KV(内测 5KV),空气模式 10KV(内测 15KV)3. 内部结构差别1)启动时间:GD32 启动时间相同,由于 GD 运行稍快,需要延长上电时间配置(2ms)2)主频时钟:GD32F10 系列主频 108MHZ STM32F10 系列主频 72MHZ3)Flash 擦除时间:GD32 是 60ms/page,STM 30ms/page4)FLASH 容量:GD32 最大容量 3M Byte5)SRAM 空间:GD32F103 系列、GD32F105\107 大容量系列 SRAM 96K6) VB 外扩总线 FSMC:GD32 100PIN 配置总线输出,STM32 144PIN 并且 256k 以上才配置总线输出4. 功耗区别(以 128k 以下容量的作为参考)1)睡眠模式 Sleep:GD32F:12.4mASTM32F10X:7.5mA2)深度睡眠模式 Deep Sleep:GD32F:1.4mASTM32F10X:24uA3)待机模式 Stand By:GD32F:10.5uASTM32F10X:3.4uA4)运行功耗:GD32F:32.4mA/72MSTM32F10X:52mA/72M5. 内部 FLASH 区别1)ISP:擦写时间同 STM32 有差异,使用新版 ISP 软件2)IAP:擦写时间相同,按字写入,按页擦除3)存储寿命:10 万次擦写,数据保存 20 年以上4)加密特性:除了常规的禁止读出和 96 位 ID 号码加密之外,GD32 数据写入Flash 时,具有存储逻辑地址连续,物理地址不连续的特性。二、 GD32 介绍与兼容性详析1. 系统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)(路径:\..\Libraries\STM32F10x_StdPeriph_Driver\src)。2) 部分客户使用有源晶振出现问题,在 GD32F103 小容量产品,发现会在 MCU 的复 位管脚一直把电平拉到 0.89V,电平不能保持在高电平描述是由于部分有源晶振起振时间太快,复位信号还没有完成导致的解决方法就是在有源晶振的输入端与地之前并上一个 30pf 电容3) GD32 MCU 主频支持 108MHz 高性能,在代码移植方面需要注意事项描述GD32 通过芯片内部加大缓存,提高了相同工作频率下的代码执行速度,带来 了高性能的使用体验。解决方法因此如果代码有用到 for 循环或 while 循环语句做精确定时的,定时时间会由于代码执行速度加快而使循环的时间变短。使用 Timer 定时器则没有影响。4) GD32F105/107 系列 MCU 配置为 108MHz 有何不同描述通 过 Clock configuration register (RCC_CFGR) 中 , 第 21 : 18 位 为PLLMUL[3:0],再结合第 29 位 PLLMUL[4]组成 5 位的位域来确定 PLL 倍频 系数,即通过软件配置来定义 PLL 的倍频系数,且 PLL 输出频率绝对不 得超过最高主频(108MHz)。2. 内部 Flash1) 芯片设置读保护用法描述由于 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)四个函数需要修改。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 源 文 件 中(路径:\..\Libraries\STM32F10x_StdPeriph_Driver\src)3) 用 IAR 下载配置解决方法在批量生产的时候首先会烧写一个 USB 的 boot,这个 boot 自动运行后在由上位机软件进行烧写应用程序。如果 boot 程序不能自动运行则需要重新插拔一 次电源。给生产造成一些麻烦。产生不能自动运行程序的原因是如果程序设置 读保护的话需要等待 FLASH_CR 的第 9[OPTWRE]位为 1.如果没有置位的话继续 执行就会出错。由于 ST 的执行速度慢,程序执行到读 FLASH_CR 寄存器的时候 该位已经置 1,GD 的执行速度比较快,程序运行到这的时候该位还没置 1,因 此需要在 FLASH_ReadOutProtection 函数里面添加一些轮询该位为 1 或者加一 些延时。3. ISP 烧写软件1) ISP 烧写,建议使用官方烧写软件描述GD32 芯片内部 flash 同 STM32 有区别解决方法建议到 www.mcuisp.com 下载最新版本的 MCUISP。另外 GD32 也有专门的烧写软件(GigaDevice MCU ISP Programmer)可以到 http://bbs.21ic.com/gd32 论坛下载。如果使用自制的 ISP 软件或脱机编程器,实现 ST 和 GD 完全兼容,建议修改以下参数。1、 页擦除等待超时时间增加至 300ms,整片擦除等待超时时间增加至 3s 左右。2、 字编程等待超时时间增加至 2ms,页编程等等超时时间增加至 300ms。I/O 口1) IO 口外部中断使用方法描述在关闭期间,如果外部引脚有电平的变化,在使用 IMR 打开中断后会马上进 入中断服务程序。理论是打开中断前,不管管脚是否有电平的变化,都不会影 响到打开后的中断响应。解决方法所以解决方法就是通过禁用上升沿或者下降沿检测寄存器来开关中断,不能使用 IMR 屏蔽寄存器。程序如下:EXTI->FTSR &= ~EXTI_Line3; //关闭沿检测,以达到关闭中断的 目的,下降沿使用 FTSR 寄存器,上升沿使用 RTSR 寄存器EXTI->PR = EXTI_Line3; EXTI->FTSR |= EXTI_Line3;2) 在待机模式,PA8 引脚特殊设置描述在使用低功耗的情况下,PA8 会被 MCU 在内部被设置为地PA8 复用为 MCU 内部频率输出,超低功耗设置时需要悬空解决方法在待机模式,PA8 悬空不用3) 低功耗下必须注意4) 当有脉冲群冲击管脚描述需要在在进入中断后关闭中断描述在使用低功耗情况下,把软件全部端口(A-F)时钟关掉,无论是否有该端口。4. 定时器1) 定时器输入捕获模式需要软件清中断描述STM 定时器输入捕获模式默认能硬件清中断,GD 为了更加严格要求配置,需要做软件清中断解决方法软件清除标志位2) 定时器向上脉冲计数模式设置描述定时器的用法差异解决方法脉冲计数模式下,装载值必须设置为比预期值大,否则不计数在 ST 上如果重载值不设置(初始为 0)的时候,CNT 可以正常计数。在 GD 上如果重载值不设置保持初始为 0 的时候,会因为重载值为零,即便是 来一个脉冲也会导致所有的寄存器复位从而不能正常计数。型号GD32F1 系列 MCU (Flash 256KB 及以上的型号)TIM、ADC模块描述Timer、ADC 模块的触发信号宽度要求解决方法由于内部有高速和低速两条外围总线,Timer、ADC 模块和其他外设共同使用这两个总线。GD32F103/101 系列 Flash 128KB 及以下的型号,Timer、ADC 等 模块识别触发信号的条件是触发信号宽度大于模块所在总线的时钟宽度。5.串口USART1 USART连续发送数据字节有空闲位描述字节间有空闲位解决方法对于一般的通讯来说,不会有影响,只对于一般在通讯上有特殊协议的,才会产生数据不准确的情况 所以,特定情况,修改程序6. I2C 总线1) 硬件 I2C 特殊配置描述GD 的 I2C 相对 STM 的来说要少一个标志位解 决 方法1、宏地址定义改变#define I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED((uint32_t)0x00060002)#define I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED7.ADC采样1) ADC采样设置描述ADC 启动解决方法分三个方面1. 当 ADON=0 时写入 1 后,需要等待一段时间 t_WAIT,如果用 ST 库的话 就在 ADC_CMD 后面加 20us 左右的延时。2. 如果采用中断获得采样数据后,需要软件清除中断。8. SDIO1) SDIO DAT 3 pin 的在 1 bit bus mode 和 4 bit bus mode 下的配置描述1、 SDIO 在 1 bit bus mode 下,DAT 3 pin 是低电平,这样会导致 SD Card 进入 SPI 模式。原因:初始化失败的原因主要是因为 GD32 的芯片 SDIO 的 DAT3 口存在BUG。2、 在 4 位模式下,通过上面的方法,程序能正常初始化,但不能正常读写 SD卡。原因:因为 DAT3 口在前面已经配置成推挽输出,所以在 4 位模式下,不 能正常读下。在调用 4 位模式前,把 DAT3 的端口配置成复用推挽输入即可解决问题。解决方法1、 1 bit bus mode 的解决方法:建议在 SDIO 使能之前,先把 SDIO DAT 3pin 配置成推挽输出,并且要置成高电平,使 SDIO DAT 3 pin 保持高电 平即可2、 4 bit bus mode 的解决方法:在调用 4 位模式前,把 DAT3 的端口配置成 复用输出即可解决问题。((uint32_t)0x00070002) 2、硬件 I2C 在会在向从机发送 7bits 地址完成后,从机还没来得及识别。(看客户 应用) 我们可以在发送完 7bits 后加个延时,让从机完全识别: I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); { int i = 0xfff;while(i --); }3、检测 ADDR 不能使用 I2C_CheckEvent 函数,因为他会清除 ADDR,可以使用 I2C_GetFlagStatus 函数。 就是把while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); 改为 while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR));4、还有个关于编程步骤的严谨性,跟STM 想比,我们是先 Clear_ACK,再 Clear_ARRD。2) 程序在刚烧完后能正常读写 SD 卡,断电再上电后,SD 卡初始化失败,需要手动 复位一次后才正常描述在某些 SD 卡中,GD32 断电再上电,会引起 SD 卡上的时钟信号不正常,导致SD 卡发送命令失败。解决方法在程序中,打开 SD 卡时钟后,增加一小段延时,以保证 SD 卡时钟信号稳定。这个延时添加的地方:在 sdcard.c(即 SDIO 的配置文件中),然后在 SD_ErrorSD_Init(void)这个函数中找到 SDIO_DeInit();就在这个后面加个延时。RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA2, ENABLE);SDIO_DeInit();{int i = 0xffff;while(i --);}9. USBA. USB_OTG1) 客户使用STM32 的DFU 原工程时需要注意几点解决方法1、在usb_istr.c 中,增加如下图红色字体语句 for (i=0;iHCCHAR, hcchar.d32);} pdev->host.HC_Status = HC_NAK;}而V2.1.0版本的 NAK 处理过程如下: else if (hcint.b.nak) { if(hcchar.b.eptype == EP_TYPE_INTR) { UNMASK_HOST_INT_CHH (num); USB_OTG_HC_Halt(pdev, num); } else if ((hcchar.b.eptype == EP_TYPE_CTRL)||(hcchar.b.eptype == EP_TYPE_BULK)) { /* re-activate the channel */hcchar.b.chen = 1; hcchar.b.chdis = 0; USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32); } pdev->host.HC_Status[num] = HC_NAK;CLEAR_HC_INT(hcreg , nak);}唯一的区别就是 CLEAR_HC_INT(hcreg , nak)的位置,在 V1.0.0 版本中对于 CTRL 和BULK 端点的 NAK 中断没有清除 NAK,我们的芯片会因此产生多次 IN 传输的请求,导 致数据传输错 误。改为 V2.1.1 的写法后传输正常。(注意 HC_Status 在 V2.1.0 是数 组,在 V1.0.0 是单个数据,直接拷贝的话要去掉后面的[num])B. USB 外设的工作频率有限制10. SPI1) 输入与输出配置要求(STM32 不需要如此要求)解决方法GD32 在使用 SPI 时,IO 的配置必须严格遵守主从模式下的输入与输出配置,而STM32 无此要求,相关代码如下:主机模式下 IO 配置(主机以 SPI 为例):GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7; GPIO_Init(GPIOA,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_Init(GPIOA,&GPIO_InitStructure);从机模式下 IO 配置(从机以 SPI2 为例):GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13|GPIO_Pin_15; GPIO_Init(GPIOB,&GPIO_InitStructure);GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;GPIO_Init(GPIOB,&GPIO_InitStructure);2) 在 GD32 的 SPI 的时钟信号,空闲状态需要配置成高电平,以保证数据的稳定性, 具体代码如下:红色字体代码描述有最低工作频率的要求,也就是 APB1 分频后的时钟必须大于 12MHz,比如HCLK 为 56MHz,APB1 的最大分频系数为 4,56/4 = 14MHz,可以正常工作。解 决方法SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;SPI_InitStructure.SPI_Mode = SPI_Mode_Master;3) 当作为从机时,在 GD32 中,时钟信号必须为 8 的整数倍。例如:红色字体代码解决方法SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; SPI_InitStructure.SPI_Mode = SPI_Mode_Master;SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;SPI_InitStructure.SPI_CRCPolynomial = 7; SPI_Init(SPI1, &SPI_InitStructure);4) 在GD32中,不能使用 SPI_I2S_FLAG_BSY该位来判断SPI总线数据是否接收或发送完成。11. 看门狗1) 进入STOP模式前打开看门狗,通过RTC的ALR唤醒后,程序会不断被复位的现像描述IWDG 内部有个 Reload 信号,KEY 寄存器写 AAAA 会使其拉高,过一段时间自动拉低。在拉底之前进入 STOP 状态会使 Reload 信号一直为高,等到退出 STOP 后也保持为高,之后再写 AAAA 没有办法让 Reload 产生上升沿,也就没办法更 新计数器了。解决方法进 STOP 之前不要 Reload,也可以调整下程序的顺序,把 IWDG 的配置放到 RTC配置之前,效果是一样的。SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge; SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; SPI_InitStructure.SPI_CRCPolynomial = 7;SPI_Init(SPI1, &SPI_InitStructure);
收藏 回复

使用道具 举报

返回列表
您需要登录后才可以回帖 登录 | 立即注册

快速回复 返回顶部 返回列表