ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GD32F103开发环境搭建与工程模板创建实战指南

GD32F103开发环境搭建与工程模板创建实战指南 1. 别急着写代码先把GD32的环境搞顺做嵌入式开发这么多年我见过太多人在GD32F103上栽跟头十有八九不是芯片的问题而是开发环境没搭好。GD32F103是国内厂商兆易创新推出的Cortex-M3内核通用MCU从引脚定义到外设寄存器基本和STM32F103是兼容的但坑就藏在“基本”这两个字里。它的内核、启动流程、时钟树、烧写协议都有自己的差异如果你拿一套STM32的习惯直接套轻则编译告警满天飞重则芯片跑起来完全不是你预期的那样。这套入门实践文章我会从零开始带着你完整走一遍GD32F103的开发流程。第一篇先把地基打牢配置开发环境、搭建一个干净可复用的工程模板、把程序烧进板子并确认跑起来了。这篇做完你手里会有一套属于自己的GD32F103工程模板后面写流水灯、串口通信、驱动LCD12864、移植RTOS都可以基于它直接扩展不需要每次重新搭积木。这篇文章适合谁看没用过GD32、但熟悉其他Cortex-M芯片的人以及用过STM32F103、想切换到GD32F103做项目选型对比的同学。我会尽量把每个步骤背后的原因解释清楚不光告诉你“怎么做”也告诉你“为什么这样做”。2. 硬件准备和开发环境选型2.1 硬件清单与选型思路先把手里要用的东西理清楚。开发GD32F103最少需要几样东西GD32F103系列开发板或者自己画的板子。最常见的是GD32F103C8T6小容量64脚和GD32F103RCT6中等容量64脚很多入门板子用C8T6因为便宜、引脚够用、资料也多。调试/烧写器。官方有GD-Link和ST-Link用法类似但注意GD-Link的驱动和固件和ST-Link并不是完全通用的。我实际测试下来J-Link配合GD32F103用也比较稳尤其是用J-Link的SWD接口烧写速度和平稳性都让人放心。如果你手头暂时没有GD-Link用J-Link或者ST-Link部分版本也能顶一阵子但不同调试器的兼容性表现不一样下文我会专门说一下这个问题。USB转TTL模块。这个不是必须的但建议备一个。后面调试串口通信、看打印日志都离不开它入门阶段提前准备好没坏处。若干杜邦线、面包板、LED、电阻、按键之类的基础元件。这篇只烧一个点灯程序不需要太多外围但后面做外设实验肯定用得上。选型上的个人建议是第一块板子选带板载GD-Link或者板载调试器的开发板这样烧写这部分直接插USB就能搞定能少踩很多环境适配的坑。如果你手头已经有一块空板那就用J-Link的SWD方式连接四根线SWDIO、SWCLK、GND、3.3V接上就能用。2.2 开发工具为什么选Keil MDKGD32F103的开发工具链主流选择有三个我列一个对比开发工具上手难度调试体验兼容性适合场景Keil MDK低好对GD32官方库支持完善绝大多数入门者和公司项目IAR EWARM中等好也支持GD32但工程配置稍繁琐老手、已有IAR项目基础的人GCC VSCode/CLion偏高一般需要自己配链接脚本和编译链喜欢折腾、或者做开源项目的人我的建议非常直接入门阶段老老实实用Keil MDK。原因很简单——GD32官方提供的标准外设库、固件库示例、应用笔记默认都是基于Keil工程组织的你网上搜到的资料、踩坑帖子也大多以Keil为例。用最主流的工具意味着当你卡住的时候能找到最多人帮你。等后面你对整个编译链接流程很熟了再切到GCC或者折腾VSCode里的C/C环境也不迟。Keil MDK在官网下就行安装的时候需要选对芯片支持包。安装完主程序后要单独装一个“GD32F10x AddOn”设备支持包否则在芯片选择列表里根本看不到GD32F103。这个支持包可以到Keil官网的Device Pack页面搜索GD32F10x直接下载也可以从兆易创新的官网下载集成包。装好之后新建工程的Device弹窗里选GigaDevice目录下的GD32F103系列具体型号整个环境才算配好。2.3 烧写工具GD-Link、J-Link与串口ISP程序写完编译出hex文件之后要进到芯片里跑这一步叫烧写。GD32F103支持的烧写方式主要有三种第一种基于SWD/JTAG接口的调试器烧写。这是日常开发最常用的方式。GD-Link是官方推荐的ST-Link也能被Keil识别J-Link就更不用说了。我实测下来GD32F103对J-Link的SWD响应速度比较快下载32KB左右的程序基本是秒级完成。GD-Link在兼容性上虽然不是问题但很多山寨GD-Link的固件版本参差不齐偶尔会出现识别不到芯片的怪问题。第二种串口ISP烧写。GD32F103出厂自带Bootloader可以通过串口把程序烧进去。这种方式的优点是不需要额外调试器一个USB转TTL模块就够了缺点是速度慢、不能在线调试、每次烧写要手动设置启动模式。具体做法是把BOOT0引脚拉高、BOOT1拉低复位后芯片进入Bootloader模式然后用官方上位机或者第三方工具通过串口发送固件。这个方法我在量产或者没有调试器的场景下用过几次当作备用手段是够的但日常开发不建议用这个。第三种J-Flash等独立烧写工具。如果只是需要把编译好的hex文件烧进芯片不想打开Keil可以用J-Flash单独操作。这个在产线批量烧写的场景比较常见。开发阶段一般直接在Keil里按F8下载两步到位。不管用哪种方式有一个前提必须满足芯片的供电要正常、复位电路要可靠、SWD引脚没有被复用或锁死。很多新手烧不进程序最后查来查去发现是板子上电时序有问题或者SWDIO引脚被代码里设置成了普通IO口。这个问题我后面单独说。3. 搭建第一个GD32F103工程模板3.1 GD32标准外设库和“最小工程”的思路GD32F103的裸机开发官方给了一套标准外设库配合Firmware Library也有第三方像RT-Thread等社区整理的精简版GD32库这套外设库的代码组织结构非常有规律。对一个新项目来说关键不是把整个库的全部文件扔进工程而是搭一个“最小可编译、最小可跑”的骨架后续再按需添加外设驱动。这个思想很重要——很多人一上来把整个库都加进去编译一大堆用不到的文件看着很厉害实际上出了问题很难定位。一个真正能达到“最小可跑”标准的GD32F103工程通常由这几部分组成启动文件负责初始化堆栈、调用SystemInit、跳转到main函数。这是芯片上电后执行的第一段代码。系统时钟配置一般在system_gd32f10x.c里用来配置系统时钟比如把外部晶振倍频到108MHzGD32F103最高主频是108MHz注意不是STM32的72MHz这个差别经常有人忽略。标准外设库的核心文件包括寄存器的地址定义、中断号定义、GPIO和RCC等基础外设的驱动文件。链接脚本分散加载文件对于Keil来说就是.sct后缀的文件决定代码、数据、堆栈放在Flash和RAM的哪些区域。Keil通常会自动生成一份自己建的裸工程里也可以手动指定。main.c和gd32f10x_it.c一个是主逻辑一个是中断服务函数集合。这个结构说白了就是芯片上电后启动文件先做“暖场”把必要环境初始化好然后交出控制权给main()时钟配置保证CPU按正确频率运行外设库让你不用手抠寄存器就能操作GPIO、串口等外设链接脚本保证编译出来的程序和内存布局是正确的。四者分工明确缺一不可。3.2 从官网下载固件库并理解目录结构先去兆易创新官网找到GD32F10x的固件库Firmware Library下载后解压。你会发现目录结构大概是这样的GD32F10x_Firmware_Library ├── Board // 板级支持包比如LED、按键初始化 ├── CMSIS // ARM内核相关文件 │ ├── CMSIS_Include │ └── GD32F10x_Include // 设备头文件、系统配置源文件 ├── Firmware // 外设库源文件 │ ├── GD32F10x_standard_peripheral │ │ ├── inc // 外设头文件比如gd32f10x_gpio.h │ │ └── src // 外设源文件比如gd32f10x_gpio.c │ └── GD32F10x_usbfs_library // USB相关入门先用不到 ├── Template // 官方给的工程模板 ├── Utilities // 辅助调试函数 └── Projects // 官方示例按照开发板型号分目录不要被这个目录吓住你真正需要的是几个核心文件的组合。我的习惯是把我需要的文件复制到一个自己的工程目录里而不是直接改官方目录。这样做的好处是工程整洁、可迁移性强、不会被官方库里没用的文件干扰。具体复制哪些文件我在下一节直接给你一张清单。3.3 手动创建工程目录结构与Keil新建步骤我每做一个新项目工程目录都遵循同一个规范强烈建议你从一开始养成这个习惯。以这个模板工程为例目录是这样GD32F103_Project ├── User │ ├── main.c // 主函数 │ ├── gd32f10x_it.c // 中断服务函数 │ ├── gd32f10x_it.h │ └── systick.c // 可选系统节拍定时 ├── Core │ ├── startup_gd32f10x_hd.s // 启动文件 │ └── system_gd32f10x.c/h ├── Periph │ └── gd32f10x_xxx.c/h // 用到哪个外设就加哪个 ├── FWLib │ └── 外设库的inc和src ├── Output // Keil生成的中间文件和hex └── Doc // 放数据手册和笔记在Keil里创建工程的操作步骤如下打开Keil菜单Project → New uVision Project选择你的工程根目录输入工程名。在弹出的Device选择界面找到GigaDevice目录展开后选择你用的具体型号比如GD32F103C8T6。接下来Keil会弹一个“是否添加启动文件”的对话框建议选“否”我们手动手动添加官方针对GD32的启动文件。因为Keil自动添加的可能还是ST的启动文件搞错了编译能过跑起来必出问题。然后在工程里创建对应的分组比如User、Core、Periph、FWLib把我们准备的文件加进去。最后配置Output、C/C编译选项、Debug选项具体参数看3.5节。这里要重点提醒芯片型号如果是C8T6这种小容量芯片启动文件要用startup_gd32f10x_ld.s如果是RCT6这种用hd版本。选错了也可能编译通过但内存布局完全不对程序初始化和向量表都会偏移轻则中断进不去重则上电直接跑飞。3.4 启动文件、系统时钟和外设库之间的关系这节我从运行原理的角度讲一下它们之间的关系这部分搞懂了后面Debug查问题会轻松很多。GD32F103上电后硬件复位释放CPU的第一条指令是取“向量表”的第一个word作为栈顶地址MSP第二个word是复位中断处理函数的地址。这个向量表就放在Flash的起始位置启动文件里就定义了整个向量表和复位处理函数的骨架。复位中断函数Reset_Handler做三件事调用SystemInit()配置时钟树把系统时钟设置到目标频率。把数据段的初始值从Flash复制到RAM把BSS段清零。调用__main最终跳转到用户的main()。看到没有如果SystemInit有问题时钟配置不对即使main()里的代码逻辑完全正确整体行为仍然是错的。典型的表现是程序烧进去不跑、跑得极慢、串口波特率不对。所以我建议初学者在调试阶段先确认自己板子的时钟是正常的最简单的方法是用LED点灯然后对比闪烁频率是否符合预期。GD32F103的系统时钟配置和STM32F103有个关键区别需要注意STM32F103的系统时钟最高一般是72MHz而GD32F103文档里标称的是108MHz内部PLL倍频之后。但很多网上流传的代码模板和教程都还是按72MHz来配这不是不能跑只是没有发挥出这个芯片的全部性能。官方固件库里system_gd32f10x.c默认配置了三种时钟源你可以按自己的外部晶振频率去修改PLL倍频系数。如果板子上用的是8MHz外部晶振配置到108MHz的PLL系数和配置到72MHz是不一样的具体数值在官方头文件里有注释我建议入门时先用官方的默认配置确认能跑通后再研究超到108MHz的事。3.5 Keil工程的关键配置项新建工程之后有几个编译和调试的配置项必须设置对否则后面会出现莫名其妙的问题。我按重要程度从上往下排第一Output选项卡。勾选Create HEX File这样编译后会生成hex二进制文件方便用独立工具烧录。如果想Debug的时候查看变量和寄存器把Browse Information也打开。第二C/C选项卡。这里最核心的是Define预定义宏。使用GD32标准外设库的工程通常需要定义“GD32F10X_HD”或者“GD32F10X_MD”这个宏明确告诉外设库你用的是哪种容量的芯片配合头文件里的条件编译来选择寄存器定义。其次要确认Include Paths把所有头文件目录都加进去了否则编译会报找不到头文件的错误。第三Debug选项卡。选择你用的调试器。如果选J-Link然后在右侧的Settings里确认能识别到芯片ID如果选ST-Link也同理。这里有一个很常见的坑——Keil的调试器下拉列表里默认是ULINK很多人忘记改成自己的调试器第一次按下载按钮就会报错“Cannot load Flash Device Description”。第四Utilities选项卡。这里要勾选“Use Debug Driver”或者“Use Flash Download Tool”并且在Flash Download里选对编程算法Flash Algorithm。GD32F103C8T6是64KB Flash需要对应容量的算法文件。如果算法不对烧写时会提示“No Algorithm found”或者“Erase Failed”。一个额外的注意点Keil工程文件.uvprojx一旦在某台电脑上配置好了换一台电脑打开不要急着编译先全选一遍上面的配置。因为我遇到过很多次工程在A电脑编译烧写正常到B电脑就报各种诡异错误最后都是因为编译器版本不一样或者调试器配置没改跟代码本身没关系。3.6 编写一个最小点灯程序来验证模板主体框架搭好之后我们写点实际代码让它编译、烧录、跑起来。我在模板里放一个最简单的GPIO点灯程序验证整个工程从编译到烧写的通路是否正常。GD32F103的RCUReset and Clock Unit相当于STM32的RCC也就是复位和时钟控制器。操作任何外设之前第一步永远是开启该外设对应的时钟。以PB2引脚接LED为例完整代码如下#include gd32f10x.h void led_config(void) { rcu_periph_clock_enable(RCU_GPIOB); gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2); gpio_bit_reset(GPIOB, GPIO_PIN_2); } int main(void) { led_config(); while(1) { gpio_bit_set(GPIOB, GPIO_PIN_2); delay_1ms(500); gpio_bit_reset(GPIOB, GPIO_PIN_2); delay_1ms(500); } }注意这里用到的delay_1ms需要自己实现一种简单方式是使用SysTick。SysTick是Cortex-M内核自带的24位递减计数器用它做时间基准既省资源又不占用额外定时器。我这里给出一个非常精简的实现static volatile uint32_t delay_count 0; void delay_1ms(uint32_t ms) { delay_count ms; while(delay_count ! 0); } void SysTick_Handler(void) { if(delay_count ! 0) { delay_count--; } }然后在main之前或者SystemInit之后调用SysTick_Config(SystemCoreClock / 1000)这样SysTick中断频率就是1kHz每毫秒触发一次中断。编译前再确认一遍system_gd32f10x.c里根据外部晶振配置了正确的系统时钟Keil的Preprocessor Symbols里定义了正确的芯片容量宏Debug设置里选了正确的调试器并且能识别芯片。都确认无误之后按F7编译看看0 Error 0 Warning然后按F8下载。如果一切顺利LED会以500ms间隔闪烁你的GD32F103开发环境就算正式打通了。4. 烧写环节的完整流程与掉坑指南4.1 Keil内置下载的使用步骤Keil内集成了Flash下载功能正常情况下一键就能烧进芯片。但你得先保证三个前提调试器连接正确、调试器驱动正常、芯片供电正常。具体流程是这样的给开发板上电确认电源指示灯亮。用SWD方式连接调试器如果是板载调试器直接插USB即可。在Keil的Debug选项卡里选择对应调试器打开Settings窗口。正常情况下这里能看到芯片的IDCODE以及SW Device列表里出现目标芯片信息。如果这里就是空白的先别急着下载检查连线。确认Utilities里的Flash Download配置正确勾选了对应的编程算法。按F8下载。下载过程中Keil会先擦除Flash然后写入最后自动执行复位并运行程序。我观测到的实际效果是用J-Link下载一个10KB左右的程序到GD32F103耗时在2到3秒左右如果是ST-Link稍微慢一点但也在可接受范围。调试模式的进入和退出偶尔会有小概率失败最常见的原因是调试器连接线太长或者接触不良SWD频率太高导致时序不稳定。遇到这种情况先换短线或者在Debug设置里把SWD时钟频率调低重试。4.2 用J-Flash独立烧录的替代方案某些场景下你不会打开Keil去烧程序比如产线批量烧录、替客户烧录、现场升级固件。这时候可以用SEGGER的J-Flash工具配合J-Link硬件来操作。它的逻辑很简单新建工程选择芯片型号GD32F103C8T6或者RCT6取决于你的具体型号然后打开hex文件按F7编程。这里有一个容易碰到的坑J-Flash的芯片型号列表里GD32相关型号不是按兆易创新的名字排在前面而是在器件选择窗口里搜索“GD32F103”后选择。选错型号或者选成ST的同型号在有些情况下也能擦写成功但读回来的芯片ID、Flash容量信息会异常不建议混用。生产环境中我还用过一种方式——先用J-Flash烧录一个Bootloader然后通过串口或者CAN、USB等方式升级应用程序。这种方式对批量生产特别有用因为板子出厂后不需要每个都接调试器产线工人只要接上电源和通信线用上位机软件就能完成固件更新。后面如果涉及批量交付非常建议实现一个简单的IAP方案把Bootloader和App分开管理。4.3 串口ISP烧写方法详解说完调试器烧录再说一下不依赖调试器的串口ISP烧录。这个方法完全利用芯片出厂固化的Bootloader好处是硬件成本最低一个USB转TTL模块就能干活。操作步骤把BOOT0和BOOT1引脚按一定电平配置。对于GD32F103通常是BOOT01、BOOT10将芯片设置为系统存储器启动模式。连接USB转TTL模块的TX、RX到芯片的USART0或USART1看具体型号对应引脚同时共地。给板子重新上电或者按复位键。打开官方上位机软件可以到兆易创新官网找选择串口号和固件文件hex或者bin点击下载。烧写完成后把BOOT0跳线恢复为0重新复位程序就开始运行了。这个方式的缺点是不能在线调试每次烧完都要手动改跳线对开发阶段来说效率太低。而且在芯片的main函数里如果已经配置了复用串口引脚使用同一个串口做ISP需要确认没有冲突。我一般是把它当作没有调试器时的应急方案不推荐作为主要烧写方式。4.4 烧写报错“No Target Connected”的排查思路烧写报错是极其常见的一类问题我不能不提。我见过很多初学者第一次尝试下载弹出的不是绿灯而是一堆红色错误最常见的就是“No Target Connected”或者“Cannot connect to target”。遇到这个别慌张按下面顺序排查先从最简单的开始。看开发板的电源指示灯亮不亮亮说明供电正常。然后看SWD四根线是不是连对了SWDIO连接SWDIO、SWCLK连接SWCLK、GND必须有3.3V在某些情况下可以不用连因为目标板自己有电源但不连的话逻辑电平参考会出问题所以最好还是接上。如果连线都对还是找不到芯片把调试器的SWD速率调低再试。默认的4MHz或5MHz在部分连线上会因为信号质量不好而失败降到1MHz以下往往就好了。我曾经遇到过一块板子怎么连都不识别最后发现调试器下载线质量太差换成10厘米的短杜邦线瞬间正常。再往下排查检查芯片本身是否处于异常状态。比如代码里把SWDIO引脚复用成普通GPIO了、或者芯片进入了休眠模式、或者看门狗在疯狂复位。这种系统级问题通过普通的复位连接很难救回来。解决办法之一是在尝试连接时按住复位键在Keil点击下载后、连接到目标的瞬间立刻松开复位键——这是嵌入式老江湖惯用的“裸奔连芯片”技巧。另一个办法是用串口ISP方式擦除整个Flash恢复正常启动后再用SWD调试。有一种情况特别坑如果你之前烧过一段代码把PB3、PB4这些默认的JTAG引脚复用成普通IO了那么J-Link/ST-Link通过JTAG协议连接自然会失败。不过GD32F103默认是SWD和JTAG同时启用的一般用SWD两线接口不受影响除非你的代码把PA13、PA14也一起改了那才是真正的“自杀式操作”。遇到这种情况别无他法只能靠串口ISP擦除救命。4.5 关于烧写算法和Flash容量的坑GD32F103C8T6标称Flash 64KBGD32F103RCT6是256KB。Keil在下载时需要一份“烧写算法”描述怎么擦除和写入这颗芯片的Flash。如果在Flash Download配置里选的算法不对下载会中途报错。我在实际项目里遇到过一种情况从网上下载的某个“通用GD32工程模板”它的烧写算法是给512KB的型号配的我换成C8T6之后忘记改每次下载到一半就失败。排查了很久最后在Utilities里把Flash Algorithm改成GD32F103C8T6对应的算法问题立刻消失。所以建议是每个新工程第一次下载前打开Utilities → Settings → Flash Download看一眼里面的Programming Algorithm列表。如果芯片型号是C8T6就确保是64KB的算法如果是RCT6则是256KB。另外勾上“Reset and Run”下载完成后芯片自动复位运行省去手动按复位键的步骤。5. 常见问题速查与排错技巧5.1 我把干过的坏事都记下来了——典型问题清单做教程这么多年我积累了一份“新手必踩坑”清单下面用表格列出来方便你排查现象根本原因解决方法编译报错No such file or directoryInclude路径没加全把所有包含头文件的目录都加到C/C Include Paths编译报错identifier xxx is undefined芯片容量宏没定义Preprocessor Symbols里定义GD32F10X_HD或GD32F10X_MD下载时报错No Target ConnectedSWD接线错误或速率过高检查四根线降速率到1MHz以下再尝试下载时报错Cannot Load Flash Device DescriptionFlash算法缺失或型号不对Utilities里添加正确型号的Flash Algorithm板子能识别但下载失败Erase FailedFlash算法和芯片实际容量不匹配换对应容量的烧写算法文件程序烧进去不跑启动文件用错或者时钟配置异常检查启动文件是否为GD32特定版本SystemInit配置是否正确程序能跑但LED闪烁频率不对时钟配置和实际晶振不匹配对照板子外部晶振频率确认PLL系数用一个工程烧两个不同型号第二个报错芯片型号选择没更新确认Options for Target里的Device型号和目标是同一个这个表几乎覆盖了我自己能想到的入门阶段80%以上的报错场景。如果你遇到的问题不在列表里还有一个通用策略编译和下载过程本身就是最好的诊断工具。先看编译警告很多问题在编译阶段就暴露了再看下载阶段的日志输出Keil的Build Output窗口会告诉你卡在哪一步。5.2 识别芯片ID判断调试器是否正常排错过程中有一个基础操作特别有用读取芯片ID。在Keil的Debug设置里打开Settings窗口如果一切连接正常你会看到SW Device列表里有你的芯片信息包括设备ID、内核类型等。不同厂家的Cortex-M芯片其设备ID不完全一样。如果SW Device列表里出现了一长串问号或者错误代码通常是下面几种情况SWDIO和SWCLK接反了。赶紧换过来。复位引脚被拉低芯片一直处于复位状态调试器无法建立连接。芯片功耗异常电流不足导致内核无法稳定工作。调试器本身驱动有问题重装驱动或者换个USB口试试。我遇到过最哭笑不得的一次芯片板子完全正常就是我忘记给调试器插USB了。所以顺手也提醒一下——先看物理连接再怀疑代码这是嵌入式Debug的第一法则。5.3 从串口ISP模式中恢复一只“死芯片”大部分“芯片死了”的情况并不是芯片真的损坏而是Flash里跑了一段不正常的程序或者调试端口被占用了。这时候串口ISP模式是最后的救命稻草。把BOOT0拉高、BOOT1拉低复位芯片芯片进入系统存储器中的Bootloader。这时候通过串口连接用官方工具和芯片建立通信执行全片擦除然后再把BOOT0拉低、复位芯片就恢复了出厂时的空白状态SWD调试接口也重新可用。这个方法我已经救回过好几块“砖”可靠度极高。还有一点如果串口ISP模式也连不上检查USB转TTL模块的驱动是否正常以及TX、RX是否接反。接反这种情况太常见了芯片的TX接模块的RX芯片的RX接模块的TX别搞成同名相连。5.4 初始化代码执行不到的排查思路还有一个问题很隐蔽程序明明能编译、能烧写但执行效果不对。比如LED不亮、串口没输出、某个外设没反应。这种情况的排查思路我的经验是按“时钟→引脚→外设配置→逻辑”四层递进排查。先确认时钟有没有开。GD32F103的所有外设都需要先通过RCU打开对应时钟不开时钟操作寄存器是无效的。再看引脚复用配置是否正确。比如串口的TX/RX引脚不仅要配置为复用功能还要选对对应的AFIO映射。再看外设初始化是否正确比如波特率、引脚模式、中断优先级等参数。最后才怀疑逻辑代码本身。我之前带过一个人他写了个串口发送程序串口一点反应都没有。他检查了好几遍逻辑代码最后发现是RCC里没使能USART的时钟。这种错光是看代码逻辑根本看不出来必须一层层往上追。6. 模板工程还能怎么扩展第一篇的内容到这里其实已经完成了“配环境、建模板、烧程序”三个目标。但你手里这个刚搭好的模板不应该只用来点个灯。我把这个模板后续的扩展方向简单列一下下一篇或者你自己实践的时候可以直接接上加串口驱动。在Periph目录里添加USART的驱动文件实现printf重定向用串口输出调试日志。这是后续所有调试的必备基础。加Systick优先级管理。如果后面频繁使用延时函数建议把Systick的优先级配置好避免在中断里调用延时导致系统卡死。加按键扫描。外部中断或者轮询都行配一个状态机处理按键消抖、长短按识别这些都是工程实践中特别常用的基础模块。移植RTOS。目前很流行在GD32F103上移植RT-Thread或者FreeRTOS这个模板的时钟配置和启动文件如果规范移植RTOS会非常顺利。有些朋友在宿舍搞GD32F103移植RTOS卡住的地方往往是systick的优先级问题和内存大小分配问题基础工程打好了这两块就能少踩很多坑。我个人的体会是一个干净、可复用的模板工程价值远远超过它看起来的那几KB代码。因为你在后面所有项目中积累的工具函数、驱动模块都是围绕着这个基础模板不断叠加的。模板本身设计得好后面每加一个功能都会很顺手模板乱糟糟的后面越改越难受直到某一天不得不推倒重来。这篇的实操内容就分享到这里。大家在实际操作中如果遇到“环境都对但不工作”的怪问题欢迎在评论区贴出你的具体报错信息和硬件连接方式一起分析解决。下一篇我会基于这个模板带大家一起实现串口通信和调试日志输出那个阶段能做的事就多起来了。
返回列表