news 2026/4/16 9:07:31

Keil5新建工程系统学习:涵盖全部基础配置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Keil5新建工程系统学习:涵盖全部基础配置

从零开始搭建一个可烧录、可调试的Keil5工程:新手避坑指南

你有没有过这样的经历?
刚装好Keil5,信心满满地点开“新建工程”,结果在一堆弹窗和选项中迷失方向——芯片选哪个?启动文件怎么加?头文件路径报错怎么办?编译完没有HEX文件……最后只能照着视频一步步“复制粘贴”,却始终不知道每一步到底在干什么。

别担心,这几乎是每个嵌入式初学者都会踩的坑。今天我们就来彻底讲清楚:如何从零开始,亲手搭建一个真正可用、结构清晰、能下载、能调试的标准Keil5工程

我们不堆术语,不走形式,只讲你真正需要知道的实战逻辑。


第一步:不是写代码,而是“告诉Keil你的硬件是谁”

很多人一上来就想写main()函数,但其实第一步根本不是写代码,而是让Keil认识你的MCU。

当你点击Project → New µVision Project并保存为Blink_LED.uvprojx后,Keil会立刻弹出一个对话框:

“Select Device for Target ‘Target 1’”

这就像是在问:“你说你要开发,那你目标板上到底用的是哪颗芯片?”

比如你手里的开发板是STM32F103C8T6,那就在这里找到它:
- 制造商选STMicroelectronics
- 型号找STM32F103C8
- 点击OK

这时Keil干了三件关键的事:

  1. 自动设置内存布局
    它知道这片Flash从0x08000000开始,大小是64KB;SRAM起始于0x20000000,共20KB。这些信息直接写进了链接器配置里。

  2. 预加载CMSIS核心头文件
    Cortex-M系列的寄存器定义(如NVIC、SysTick)都来自CMSIS标准,Keil已经内置了core_cm3.h这类文件,无需手动添加。

  3. 提示是否添加启动文件
    接下来它会问你:“要不要复制标准的启动代码?”
    ——一定要点Yes

否则你就得自己去找startup_stm32f103xb.s这个汇编文件,而新手往往连它藏在哪都不知道。

📌 小贴士:GD32用户注意!虽然GD32F103兼容STM32F103,但Keil数据库里没有GD的官方支持。你可以先选STM32型号,后续再替换正确的启动文件和system初始化代码。


第二步:理解那个神秘的.s文件——启动代码到底做了什么?

现在你的工程里应该多了一个叫startup_stm32f103xb.s的文件,放在“Source Group 1”里。

这个名字长得不像人写的,但它至关重要。我们可以把它看作是程序的“开机自检程序”。

它的核心任务只有四个:

阶段动作
1. 设栈把主堆栈指针MSP指向RAM顶部
2. 搬数据.data段从Flash搬到SRAM(因为变量要可读写)
3. 清bss.bss段清零(未初始化全局变量默认为0)
4. 跳main执行__main,最终进入我们的main()函数

如果你打开这个文件,会看到类似这样的代码:

AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __initial_sp __Vectors: DCD __initial_sp ; 栈顶地址 DCD Reset_Handler ; 复位处理函数 DCD NMI_Handler DCD HardFault_Handler ; ... 其他异常

这里的__initial_sp实际上是一个符号,在链接时会被替换成SRAM的最高地址(比如0x20005000)。而Reset_Handler就是复位后CPU第一个执行的地方。

接着往下看:

Reset_Handler PROC LDR R0, =__main BX R0 ENDP

这里跳转到了__main,而不是直接进main()。为什么?

因为中间还有一层C运行时环境需要初始化——这部分由编译器库完成,包括前面说的数据搬运和清零操作。

⚠️ 千万别删掉Reset_Handler或改名!否则整个程序就断在起点了。


第三步:别再把所有文件丢进同一个篮子——合理分组有多重要?

Keil允许你在左侧Project窗口中创建多个“Group”,这不是为了好看,而是为了管理复杂度。

想象一下,如果有一天你要加入FreeRTOS、FatFS、WiFi驱动、USB协议栈……几百个文件全挤在一个目录下,你还找得到自己的main.c吗?

建议这样组织:

Core ├── startup_stm32f103xb.s ├── system_stm32f103xb.c └── main.c Drivers ├── stm32f1xx_hal.c └── stm32f1xx_hal_gpio.c User ├── gpio.c └── usart.c Middleware └── FreeRTOS ├── tasks.c └── queue.c

怎么做?

  1. 右键点击“Source Group 1” → Add Group…
  2. 新建名为CoreDrivers等的分组
  3. 把对应文件拖进去(物理路径不变)
  4. 可以为每个Group单独设置Include路径和宏定义!

例如,Drivers组需要用到HAL库的头文件,就可以右键该组 → Options for Group → C/C++ → Include Paths 添加:

..\Drivers\STM32F1xx_HAL_Driver\Inc ..\Middlewares\FreeRTOS\Source\include

这样做的好处是:不同模块可以有不同的编译条件,避免全局污染。


第四步:编译成功≠能用——这几个选项必须设对

很多人编译通过就以为万事大吉,结果发现程序下不去、看不到变量、没法调试……问题出在哪?就在“Options for Target”里。

必须勾选的三项

✅ Create HEX File

路径:Output 标签页 → 勾选Create HEX File

作用:生成可用于ISP烧录或J-Link下载的Intel HEX格式文件。

如果没有这个选项,即使.axf编译成功,你也无法将程序固化到Flash中。

💡 提示:某些工具链(如PlatformIO)默认输出BIN,但在Keil中HEX更常用。

✅ 设置Include Paths

路径:C/C++ 标签页 → Include Paths

常见路径包括:

.\Inc .\Src .\Drivers\CMSIS\Device\ST\STM32F1xx\Include .\Drivers\CMSIS\Include

否则会报错:

fatal error: stm32f10x.h: No such file or directory

记住:路径是相对于工程文件(.uvprojx)的位置,使用\/都可以,但不要有中文或空格。

✅ 定义必要的宏

同一页面下的Define输入框:

STM32F103xB, USE_HAL_DRIVER

这两个宏的作用非常关键:
-STM32F103xB:让头文件知道自己是哪种封装和容量等级
-USE_HAL_DRIVER:启用ST的HAL库初始化流程

写错了会怎样?
比如写成STM32F103XB(少下划线),HAL库就不会识别,导致RCC、GPIO等外设无法正常工作。


第五步:连接真实世界——调试器怎么配才不翻车?

终于到了下载程序的时候。插上ST-Link,按下Load按钮,却弹出:

“No target connected”

别急,先检查以下几点:

1. 接线是否正确?

SWD模式只需要4根线:
- SWCLK → PA14
- SWDIO → PA13
- GND → 共地
- VDD → 接电源(可选,用于检测电平)

少一根都不行。

2. 调试器设置对了吗?

进入Options for Target → Debug
- Use: 选择ST-Link Debugger
- 点击 Settings

在新窗口中:
-Connect: 改为“Under Reset”
这样可以在芯片复位状态下连接,避免因低功耗模式导致脱机。
-Flash Download: 点击Add,选择对应的算法
对于STM32F1系列,通常是:
STM32F1xx Flash (Medium Density).alg

如果没添加算法,下载时就会失败,提示“Programming Algorithm not found”。

3. 如何启用串口打印?用SWO还是semihosting?

如果你想在调试时看到printf输出,有两种方式:

方式一:Semihosting(适合仿真)
  • 在C/C++中添加宏:__MICROLIB
  • 勾选Use MicroLIB
  • 使用printf("Hello World\n");
  • 输出显示在Keil的Debug (printf) Viewer

缺点:每次调用printf都会暂停程序,不适合实时系统。

方式二:SWO Trace + ITM(真正在跑)

需要:
- 芯片支持ITM(Cortex-M3/M4以上)
- 多接一根SWO引脚(PA10)
- 在调试设置中启用Trace
- 使用ITM_SendChar()发送字符

这种方式才是真正“后台打印”,不影响程序运行。


常见问题现场排雷

❌ 编译报错:Undefined symbol Reset_Handler

原因分析:
- 启动文件没加入工程
- 文件类型被误设为“Ignore”
- 启动文件本身缺失关键标签

解决方法:
1. 检查Project中是否有startup_xxx.s
2. 右键该文件 → Properties → Build Action 应为Assemble
3. 打开文件确认存在Reset_Handler PROC

❌ 找不到stm32f10x.h

典型错误提示:

fatal error: stm32f10x.h: No such file or directory

排查步骤:
1. 是否已下载STM32CubeF1包并导入相关文件?
2. Include Paths是否包含头文件所在目录?
3. 路径是否用了绝对路径?建议改为相对路径,提升移植性。

❌ 编译成功但没生成HEX文件

可能原因:
- Output → Create HEX File 未勾选
- 许可证过期,处于评估模式限制
- 输出路径权限不足或被占用

解决方案:
- 明确勾选生成HEX
- 查看许可证状态(File → License Management)
- 更改输出目录至非系统盘路径


工程模板设计建议:让你的项目更专业

目录结构规范化

推荐采用如下目录划分:

/Blink_LED │ ├── Project │ └── Blink_LED.uvprojx │ ├── Core │ ├── startup_stm32f103xb.s │ ├── system_stm32f103xb.c │ └── main.c │ ├── Drivers │ └── HAL_Library │ ├── stm32f1xx_hal.c │ └── ... │ ├── Inc │ └── user_config.h │ ├── Src │ └── gpio.c │ ├── Objects ← 自动生成,不必提交版本控制 └── Listings ← 日志输出目录

版本控制注意事项

.gitignore至少包含:

*.uvoptx *.uvprojx Objects/ Listings/ *.log .DSLock

保留哪些?
-.c,.h,.s源码
- 工程文件(方便团队共享)
-Readme.md(说明依赖项、编译方式)


写在最后:掌握Keil5工程创建,其实是掌握一种思维方式

你会发现,keil5怎么创建新工程这个问题背后,其实是一整套嵌入式开发的认知框架:

  • 你知道了芯片选择不只是填个名字,而是决定了内存映射和底层行为;
  • 你明白了启动文件不是摆设,而是程序得以运行的前提;
  • 你学会了通过分组和路径管理构建可维护的代码体系;
  • 你也掌握了从编译到下载全过程的关键控制点。

这不是简单的菜单操作,而是一种工程化思维的建立。

下次当你拿到一块新的STM32板子,或者要帮同事排查一个“程序下不去”的问题时,你会比别人更快定位根源——因为你已经看透了Keil背后的逻辑链条。

🔧 所以说,学会新建工程,不是学会了“新建”这件事,而是拿到了通往嵌入式世界的入场券。

如果你正在学习STM32、准备电赛、或是想转型嵌入式开发,不妨动手照着这篇指南完整走一遍。哪怕只是点亮一个LED,那也是你真正掌控硬件的第一步。

欢迎在评论区分享你的第一个Keil工程截图,我们一起debug成长 🛠️

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/14 15:14:21

Potree实战指南:解锁WebGL点云渲染的商业价值

Potree作为一款基于WebGL技术的大型点云可视化开源工具,正在重新定义三维数据的商业应用场景。这款工具能够高效处理数十亿级别的点云数据,在浏览器中实现流畅的交互体验,为建筑测绘、地理信息系统和文物数字化保护等领域提供了革命性的解决方…

作者头像 李华
网站建设 2026/3/30 23:34:30

“做市商”

我们把 “做市商” 这个金融市场上的关键角色彻底讲透。他们就像是市场里的“庄家”或“流动性供应商”,是维持市场运转的隐形引擎。一、核心定义:做市商是什么?简单说,做市商是专业的金融机构或交易公司,他们同时、持…

作者头像 李华
网站建设 2026/4/15 10:38:42

vivado固化程序烧写步骤详解:小白也能轻松掌握

Vivado固化程序烧写实战指南:从零开始搞定FPGA上电自启动 你有没有遇到过这样的场景?辛辛苦苦在Vivado里完成了FPGA设计,功能验证也没问题,结果一拔掉JTAG线、重新上电——芯片“罢工”了。LED不闪,逻辑不动&#xff0…

作者头像 李华
网站建设 2026/4/7 21:25:07

从零搭建GB28181视频平台:我的30分钟部署实战经验

还记得第一次接触GB28181协议时,面对复杂的配置文档和设备对接流程,我几乎要放弃。但当我发现wvp-GB28181-pro这个开源项目后,一切都变得简单起来。今天,我想分享我的亲身实践,告诉你如何在30分钟内完成一个生产级的国…

作者头像 李华
网站建设 2026/4/1 15:11:52

STM32F4通过USB2.0实现DFU升级的全面讲解

STM32F4通过USB2.0实现DFU升级:从原理到实战的完整指南 你有没有遇到过这样的场景? 产品已经发往客户现场,突然发现一个关键Bug。如果要返厂烧录固件,不仅成本高昂,还严重影响用户体验。有没有一种方式,能…

作者头像 李华