【GD32 MCU 移植教程】10、从STM32F030系列移植到GD32E230系列
2024-11-11 来源:elecfans
1. 前言
GD32E230 对比 STM32F030 有着很好的兼容性和更高的性价比,内核和外设都有所增强。本人曾做过产品的 MCU 替换,将基于 STM32F0xx 1.5.0 固件库的应用程序移植到 GD32E230 上,大体上来说工作量不大,移植后的效果也不错,GD32E230 相比 STM32F030 有不少功能的升级,主频也更高,能感觉到国产 MCU 一直在进步。本人将此前的移植经验进行了整理,可帮助有需要的朋友快速将应用程序从 STM32F030 移植到GD32E230 上(基于STM32F0xx 标准库 V3.5.0 和 STM32F10x 标准库 V3.5.0)。本移植工作除基于STM32F0xx 1.5.0固件库的工程外还需准备STM32F10x 1.5.0固件库。GD32E230系列采用 Cortex-M23 内核,该内核向下兼容 Cortex-M0/M0+。由于 KEIL5.25/IAR8.23及以上版本才提供了对 M23 内核的支持,因此常规情况下,必须在 KEIL5.26/IAR8.23 及以上开发环境下才可以正常使用该芯片。调试仿真器如果使用 Jlink 的话需要 JlinkV9,也可以用 GD 官方的 GDlink 调试,但 GDlink 在 IAR 下的支持相对差一些。据了解也有在低版本开发环境下开发 E230的方法,可询问供应商或原厂。本文的介绍开发环境使用 Keil5.26 版本。
GD32E230 较 STM32F030 主要有以下优点:
1、更高的主频(72MHz VS 48MHz)
2、更高版本的内核(Cortex M23 VS M0)
3、支持更多指令集(单周期乘法、17 周期除法)
4、ADC 时钟更高(28MHz VS 14MHz)
5、运行功耗更低
2. 引脚兼容性
STM32F030 与 GD32E230 在相同封装下是 Pin To Pin 兼容的。外设上 GD32E230 功能覆盖STM32F030,大部分外设完全兼容,后文我会具体介绍。需要注意:相关手册中 STM32F030 外设编号从 1 开始,GD32E230 外设编号从 0 开始,且命名有差异。
3. 资源兼容性
(1)下表给出了 STM32F030 与 GD32E230 的资源对比总览(以 STM32F030C8 和 GD32E230C8对比为例):
表 1 STM32F030 系列和 GD32E230 系列内部资源对比总览
(2)在外设逻辑地址上 GD32E230C8 和 STM32F030C8 也是相同的,如下表 2。
表 2 STM32F030C8 系列和 GD32E230C8 系列外设基地址对比
(1) STM32F030 规格书上没有 TIM2,但实际是有的,如果使用到这个隐藏资源需使用 GD32E230 的其他定时器替代。
4. 环境配置
本文基于Keil5.25版本进行移植,需提前准备GD32E230 IDE芯片插件,插件可到GD32MCU资料网站 gd32mcu.com 或他们的网盘 https://pan.baidu.com/s/1mhQsNpu 进行下载。
(1) 安装 GigaDevice.GD32E230_DFP.pack 后更改为 GD32E230 的对应型号,如图 1
(2) 选择好型号后先点击 OK 然后再打开工程选项,切换至 C/C++选项卡。将 Warnings设置项选择 AC5-like Warnings;Language C 设置为 C99;Language C++设置为 C++11;Misc Controls 如果添加了内容将其删除。修改后如图 2 红框内容所示。
(3) 在 Debug 选项卡选择对应的仿真器并在 Settings 里添加 GD32E230 的 Flash 下载算法。Utilities 选项卡中采用同样设置。
5. 程序移植
对比上文内容可知 GD32E230C8 和 STM32F030C8 大部分外设功能、配置以及逻辑地址都是兼容的。所以如果仅只是从 STM32F030C8 上把代码移植到 GD32E230C8 上,需改动的底层文件有 ADC 和 Flash、I2C,另外有细节设计差异需要调整 PWR 中进入 standby 的函数。下面详细介绍一下如何对这两部分进行修改。
5.1 ADC 外设库修改
GD32E230C8 和 STM32F030C8 的 ADC 设计不同,实际和 STM32F103 配置相同。对此需要修改底层的 ADC 配置文件。虽然 ADC 设计上不相同,但其外设基地址还是相同的,也就是说只需要修改对应的外设配置函数,寄存器定义即可。对此有一个便捷的方法:可将 STM32F0xx标准库中的stm32f0xx_adc.h 和 stm32f0xx_adc.c 文件内代码替换为 STM32F10x 标准库中stm32f10x_adc.h 和 stm32f10x_adc.c 里的代码,修改 stm32f0xx.h 中的 ADC 寄存器结构体即可。
具体步骤如下:
(1) 将 stm32f10x_adc.c 中的代码复制到 stm32f0xx_adc.c 中替换原始内容,将两个头文件声明改回 0xx 的头文件声明,如图 3。
(2) 将替换后的 stm32f0xx_adc.c 中 void ADC_DeInit(ADC_TypeDef* ADCx)函数内除 ADC1外的代码删除。如图 4。
(3) 将 stm32f10x_adc.h 中的代码复制到 stm32f0xx_adc.h 中替换原始内容,头文件声明改回 0xx 的头文件声明,如图 5。
(4) 将 stm32f10x.h 中的 ADC 寄存器结构体 ADC_TypeDef 复制到 stm32f0xx.h 中替换原有的 ADC_TypeDef,如图 6。
至此 ADC 外设的底层文件就移植完成,配置方法可参考 GD32E230 用户手册或者也可以直接参考 STM32F103 的 ADC 配置例程,功能上更加灵活。
E230 的 ADC 设计相比 STM32F072 更加灵活,在 F072 上 adc 通道只能配置成一个组且转换顺序只能按通道号顺序来进行,在 E103 上 adc 通道可以分为两个组且顺序排号可以自由定义,以下举例在移植后的程序中如何配置 adc 通道 14 进行连续转换:
5.2 I2C 外设库修改
GD32E230C8 和 STM32F030C8 的 I2C 设计不同,实际和 STM32F103 配置相同,所以移植方式也是和 ADC 一样,将 STM32F0xx 标准库中的 stm32f0xx_i2c.h 和 stm32f0xx_i2c.c 文件内代码替换为 STM32F10x 标准库中 stm32f10x_i2c.h 和 stm32f10x_i2c.c 里的代码,修改 stm32f0xx.h 中
的 ADC 寄存器结构体即可。具体步骤如下:
(1) 将 stm32f10x_i2c.c 中的代码复制到 stm32f0xx_i2c.c 中替换原始内容,将两个头文件声明改回 0xx 的头文件声明。
(2) 将 stm32f10x_i2c.h 中的代码复制到 stm32f0xx_i2c.h 中替换原始内容,头文件声明改回 0xx 的头文件声明
(3) 将 stm32f10x.h 中的 I2C 寄存器结构体 I2C_TypeDef 复制到 stm32f0xx.h 中替换原有的 I2C_TypeDef至此 ADC 外设的底层文件就移植完成,配置方法可参考 GD32E230 用户手册或者也可以直接参考 STM32F103 的 I2C 配置例程。
5.3 Flash 外设库修改
STM32F030 系列的 Flash 和选项字节编程是按照 16 位编程的,E230 仅支持 32 位和 64 位编程,所以 Flash 文件中所有操作选项字节的函数和 Flash 操作都需要调整,修改成 32 位操作。此外选项字节字节中无读保护的值在 GD32E230 中是 A5,在 STM32F030 中是 AA。本人将需要修改的内容进行了整理,步骤如下:
(1) stm32f0xx_flash.h 中修改 OB_RDP_Level_0 宏定义为 0xA5,如图 7。
(2) 修改 FLASH_OB_Erase 中写选项字节的函数,原始代码是直接对 16 位的结构体成员赋值,现将其修改为 32 位操作即可,做如图 8 两处改动。其他的所有操作选项字节函数都做类似的修改,不在一一进行说明。
(3) stm32f0xx 固件库中有两个对 Flash 编程的函数接口:FLASH_ProgramWord 和FLASH_ProgramHalfWord;其中 FLASH_ProgramWord 中连续写了两次 16 位数据占满了 4 个地址,这样在 E230 上也是可以的,所以 FLASH_ProgramWord 不需要再做修改,当然也可以把连续写两次 16 为数据的操作改为直接写 32 位数据。如果有调用 FLASH_ProgramHalfWord 需要修改驱动改为按字操作,或对该函数进行一点修改,在对目标地址写入 16 位数据后再往后面地址填充一个 0xFFFF,修改内容如图 9。
在进行 Flash 编程时需注意,GD32E230 的 Flash 为 4 字节对齐,在 STM32F030 上可以对偶地址编程,移植到 GD32E230 后 Flash 编程的起始地址必须为 4 的整倍数!
5.4 pwr.c 进入 standby 模式函数修改
为在 standby 模式下达到最低功耗,进入 standby 前需手动关闭 HXTAL,如图 10 在PWR_EnterSTANDBYMode 函数添加如下红框代码:
6. 移植后应用注意事项
6.1 while 和 for 循环
GD32E230 和 STM32F030 工艺、内核、Flash 上都有区别,所以在相同主频下代码效率可能会有差异,应用中如果有软件延时需要进行调整、或使用定时器等进行精准延时。
6.2 Flash
需再次强调:在进行 Flash 编程时需注意,GD32E230 的 Flash 为 4 字节对齐,在 STM32F030 上可以对偶地址编程,移植到 GD32E230 后 Flash 编程的起始地址必须为 4 的整倍数!正常情况编译器会自动的各类型变量都按 4 字节对齐方式分配地址,但如果使用了指定地址的方式定义变量,需注意定义地址按 4 字节对齐地址。
6.3 Flash 和 DMA 操作时序
E230 是 M23 内核,和以往 GD 型号的 M3、M4 总线架构有区别,Flash 操作时 DMA 会出现阻塞,当 Flash 操作(主要是擦除时间比较久,编程操作时间短,每次编程间有间隔)时,最好暂停使用DMA 的外设,特别是 adc,避免 Flash 操作期间请求丢失导致后续搬运 buff 数据错位。
6.4 功能升级
GD32E230 相比 STM32F030 很多外设功能有扩展升级,但基于 STM32F0xx 的代码移植过来的应用程序没有新功能 API,若希望发挥 E230 更多性能建议使用 GD 的官方固件库进行开发。