工程模板建立
说明:课件示例主要基于
STM32F429ZGTx,当前西门子杯备赛主控是GD32F470VET6。这份笔记保留“工程模板怎么搭”的思路,但芯片型号、库、烧录算法和时钟参数不能直接照抄。
这节课在讲什么
这节课在讲一件很实际的事:先把一个裸机工程模板搭完整,再去写功能代码。这个模板至少要满足几件事:时钟正确、调试口正确、工程结构清楚、Keil 能编译、烧录器能下载、出了问题能 debug。
结合当前备赛规则,这节课的重点不是 RTOS,而是裸机工程框架、调试能力和模块化习惯。RTOS 这一节先建立概念,当前比赛准备阶段仍然要以裸机开发为主。
先回顾:为什么先学工程模板
裸机与调度器的区别
| 维度 | 裸机开发 | 调度器开发 |
|---|---|---|
| 执行方式 | 线性执行,常见为阻塞式 | 按优先级调度,表现为并发 |
| 资源开销 | 小 | 比裸机更大 |
| 可预测性 | 强,时序好分析 | 取决于任务设计和调度策略 |
| 扩展性 | 功能一多就容易乱 | 更适合多任务系统 |
| 适合场景 | 功能单一、资源紧、实时性强 | 多任务、强响应、易扩展 |
课件里的“裸机是单车道公路,调度器是繁忙餐厅”这个比喻很好记。裸机不是“落后”,而是更直接、更可控;调度器也不是“天然效率更高”,它的价值主要在任务组织和响应能力。
当前阶段更该先会的是下面几件事:
-
会搭工程,不是只会新建一个空项目。
-
会用调试器,不是只会点下载。
-
会把自己的代码和自动生成代码分开。
-
老师没展开的地方要主动补问和验证,不能停在“看到过”。
工程创建总流程
可以先把这节课的操作链记成下面 7 步:
-
先确认芯片型号、板卡原理图、外部晶振频率。
-
在
RCC / Clock Configuration里把时钟配对。 -
在
SYS里把调试接口配对。 -
在
Project Manager里把工程生成方式配对。 -
理清
NVIC / SysTick的作用和优先级原则。 -
生成 Keil 工程后,建立自己的
APP目录和分组。 -
把烧录器、下载算法、调试器设置一次性打通。
时钟配置
一句结论:时钟决定系统“跑多快、哪些外设能跑、系统稳不稳”,工程模板第一步就是先确认板子的真实晶振和目标主频。
常见时钟源怎么理解
| 名称 | 含义 | 常见用途 |
|---|---|---|
HSI |
内部高速时钟 | 启动快,方便,精度一般 |
HSE |
外部高速时钟 | 主系统时钟常用来源,精度更高 |
LSI |
内部低速时钟 | 独立看门狗等低速模块 |
LSE |
外部低速时钟,常见为 32.768 kHz |
RTC、实时时钟 |
PLLCLK |
HSI/HSE 经过 PLL 倍频分频后的输出 |
常作为 SYSCLK |
这里最容易混的是 HSE 和 PLLCLK:
-
HSE是外部高速时钟源,本身是“输入源”。 -
PLLCLK是HSE或HSI经过 PLL 处理后的“输出结果”。 -
课件里的常见做法是:
HSE -> PLL -> PLLCLK -> SYSCLK。
本课的实际配置思路
本课的核心不是死记参数,而是先弄明白“板子上到底焊了什么晶振,再决定怎么配”。
先在 RCC 页面把高速外部时钟模式打开:

然后在时钟树页面确认输入频率、PLL 输出和总线分频。课件示例里,外部高速晶振输入是 25 MHz,最后把 SYSCLK 配到 180 MHz:

外部晶振频率不是固定值,必须去看原理图或板卡说明。原稿里这个问题问得对:为什么要改下面那个,不是上面那个?因为上面是 LSE 32.768 kHz,下面才是主系统常用的 HSE 25 MHz。


这一组图对应的结论可以直接记成:
-
32.768 kHz那组一般是LSE,主要给 RTC。 -
25 MHz那组才是HSE,通常参与主系统时钟配置。 -
换板子时不要无脑照抄课件参数,先查原理图。
-
时钟树不只是配
SYSCLK,还要顺带看AHB / APB1 / APB2是否超限。
为什么必须先配时钟
时钟配置的意义主要有四个:
-
保证系统稳定,时钟错了很多外设会异常。
-
决定系统性能,主频和总线频率直接影响执行速度。
-
影响功耗,主频越高一般功耗越高。
-
满足外设要求,比如串口、定时器、ADC 都依赖时钟。
本科阶段暂时不用把功耗放到第一位,但“时钟一定要和板子匹配”这件事必须重视。
SYS 配置
一句结论:大多数日常开发默认优先选 Serial Wire,因为它占用引脚少、兼容主流调试器、配置最省事。
SWD 和 JTAG 怎么选
| 方案 | 引脚占用 | 特点 | 适合场景 |
|---|---|---|---|
SWD |
少,常用 SWDIO + SWCLK |
简洁、稳定、日常开发最常用 | ST-LINK、CMSIS-DAP、常规下载调试 |
JTAG |
多,常见 4 到 5 根线 | 功能更完整,但占引脚 | 更复杂的调试场景 |
这里的 Serial Wire 不是“串口调试”,而是 SWD 调试协议。
在 CubeMX 里把 SYS 设成 Serial Wire 后,PA13 和 PA14 会被调试接口占用:

这一步的实际意义有三点:
-
PA13 = SWDIO,PA14 = SWCLK,后面不要再把它们当普通 GPIO 随便改。 -
如果这里配错,Keil 里就算选了调试器,也可能读不到目标板。
-
CubeMX 里选的调试协议,要和 Keil 里选的调试器设置保持一致。
工程配置
一句结论:Project Manager 的目标不是“先把文件生出来”,而是生成一个后面还能反复迭代、重新生成也不容易把自己代码冲掉的工程。
Project 页面怎么配
原稿里“不要有中文”这个提醒是对的。更准确地说,项目名和专门的工程输出路径尽量避免中文、空格和特殊字符,能减少工具链兼容问题。
课件示例里的基本设置如下:

这一步重点看这几个字段:
-
Project Name:尽量见名知意。 -
Project Location:尽量放在简洁路径下。 -
Application Structure:本课示例选Advanced。 -
Toolchain / IDE:示例选MDK-ARM。
Code Generator 页面怎么配
库文件建议选择“只复制必要文件”:

自动生成代码时,建议至少勾上下面两个选项:
-
Generate peripheral initialization as a pair of '.c/.h' files per peripheral -
Keep User Code when re-generating
对应截图如下:

这里可以直接记两个结论:
-
为每个外设单独生成文件,后期维护和定位更清楚。
-
只有写在
USER CODE BEGIN / END区域里的内容,重新生成时才更容易被保留;自动生成区外面乱写,后面很容易被覆盖。
NVIC 与 SysTick
这一节课里没有深入配置,但概念不能空着。
一句结论:NVIC 管中断优先级,SysTick 常用作系统时基;即使暂时没配复杂中断,也要知道为什么它重要。
可以先记住三条:
-
如果工程里用到了
HAL_Delay()、软件定时或系统时基,SysTick优先级不能太低。 -
中断服务函数要尽量短,耗时逻辑尽量放回主循环或任务里处理。
-
中断优先级分配遵循“越实时、越关键,优先级越高”的原则。
当前阶段先知道“为什么以后一定会碰到它”,就够用了。
Keil 工程整理
一句结论:CubeMX 自动生成的工程只是起点,自己的业务代码最好单独放到 APP 目录,和 Core / Drivers 分开。
自动生成后会出现哪些目录
工程生成后,通常能看到下面这类目录和文件:

可以先把常见目录理解成这样:
| 目录/文件 | 作用 |
|---|---|
.ioc |
CubeMX 的外设和引脚配置文件 |
.mxproject |
工程元数据 |
Core |
主程序、启动、系统初始化、中断相关代码 |
Drivers |
HAL/CMSIS 等驱动和底层库 |
MDK-ARM |
Keil 工程文件和编译配置 |
为什么还要自己建 APP
原稿里“建立一个新的文件夹 APP,后期可细分”这个思路是对的。理由很简单:自动生成代码会反复变化,你自己的业务代码最好有单独地盘。
手动加上 APP 目录后,工程结构会更清楚:

后面可以继续把 APP 拆成更细的模块,例如:
-
bsp_led -
bsp_key -
bsp_uart -
service_protocol -
app_main
Keil 里需要补的两件事
第一件事,是把 APP 路径加到包含目录里:

第二件事,是在工程分组里单独建一个 APP group,再把你的 .c/.h 文件加进去:

这样整理的好处是:
-
自动生成代码和自己写的代码边界清楚。
-
重新生成工程时,不容易把业务代码搞乱。
-
后面做模块化移植时,直接搬
APP更方便。
烧录与调试
一句结论:烧录器不只是“把程序写进去”的工具,它更重要的价值是帮你判断“电脑、调试器、芯片”这条链路到底通没通。
烧录器的作用
烧录器至少做两件事:
-
把编译好的
.hex / .bin / .elf写进芯片的 Flash。 -
作为调试器读取芯片状态、断点调试、排查问题。
常见选择可以先这样记:
| 烧录器 | 特点 | 适合场景 |
|---|---|---|
ST-LINK |
官方生态友好,便宜,常见 | STM32 入门、学习、日常开发 |
J-LINK |
速度快、功能强、覆盖广 | 专业开发、复杂调试 |
DAPLink / CMSIS-DAP |
开源、灵活、成本低 | 创客、教育、开放工具链 |
结合当前西门子杯备赛规则:录制演示视频时不能依赖
DAP的虚拟串口,所以后面做比赛方案时,下载链路和串口方案要分开考虑。
接线时至少记住什么
最常见的是 SWD 接口,至少要确认这几根线:
-
SWDIO -
SWCLK -
GND -
VTref / VCC:不是每次都强制,但强烈建议接
能不能下载,往往不是代码问题,而是下面几项有没有对上:
-
调试器型号对没对。
-
驱动装没装。
-
协议选的是
SWD还是别的。 -
目标板有没有供电。
-
GND和VTref有没有接好。
Keil 里的基础配置
先在 Device 里把芯片型号选准:

再在 Debug 页选择你实际在用的调试器。原稿截图里用的是 CMSIS-DAP Debugger,如果你手上是 ST-LINK 或 J-LINK,这里也要对应改:

下载算法页面通常至少勾上 Program、Verify、Reset and Run:

到这一步,如果能识别到目标芯片或 ID CODE,说明“电脑 → 调试器 → 芯片”这条链基本打通了。
常见报错先怎么查
原稿里的这几张报错图很有价值,因为它们代表的是最常见的两类问题。
No Debug Unit Device found 这类报错,通常先查“电脑认没认出调试器”:

ST-LINK connection error 这类报错,通常先查“调试器到目标芯片这段链路通没通”:

排查时可以按这个顺序来:
-
先确认目标板上电。
-
再确认
SWDIO / SWCLK / GND / VTref接线。 -
确认 CubeMX 和 Keil 里都用了同一套调试协议。
-
确认 Keil 的
Device和 Flash Algorithm 选的是正确芯片。 -
如果还不通,降低
SWD Clock,或尝试Connect under Reset。 -
某些情况下可以切换
Reset方式,例如SYSRESETREQ,看哪种更稳定。
补一条很重要的迁移提醒:
-
课件示例是
STM32F429。 -
当前备赛主控是
GD32F470。 -
如果你把
GD32板子按STM32F429的下载算法、芯片型号、库文件去配,出问题是正常的。
本节课结论
-
工程模板不是“先把文件生成出来”,而是先把时钟、调试、工程结构和下载链路全部打通。
-
时钟配置里最关键的不是背参数,而是先确认板子的真实
HSE晶振频率,再决定PLLCLK和目标主频。 -
SWD是日常最常用的调试方式,记住它会占用PA13 / PA14。 -
自己的代码尽量放在
APP目录和USER CODE区域,不要和自动生成代码混写。 -
烧录器既是下载工具,也是定位问题的入口;能读到目标芯片,才说明链路真的通了。
后续学习建议
-
用当前比赛主控
GD32F470VET6再完整走一遍这套模板,不要停留在 STM32 课件示例上。 -
把
APP目录继续细分成模块,练习“一个模块一个.c/.h”的写法。 -
单独补
头文件保护、启动文件、SysTick/NVIC、寄存器版外设初始化这几块。 -
当前阶段单纯背代码价值不高,更重要的是会搭工程、会移植、会上板验证、会排错。
-
老师没展开的地方,要主动去问、去查、去试,这部分往往才是后面真正决定你工程能力的内容。