一文教你如何彻底弄明白使用Keil5软件

📃个人主页:island1314
⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞
- 生活总是不会一帆风顺,前进的道路也不会永远一马平川,如何面对挫折影响人生走向 – 《人民日报》
纯新手教学
一、基本概述
Keil提供了包括C编译器 、宏汇编、链接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(μVision)将这些部分组合在一起。
补充:目前软件对中文的支持不友好,不建议安装网上的一些汉化包之类的。另外建立的工程文件路径也尽量不要存在中文,否则可能会出现一些异常。
二、软件下载安装配置
1. 软件下载
通过网盘分享的文件:MDK535.EXE
链接: https://pan.baidu.com/s/1cPaoAq0jAj-8onEOrRXekg 提取码: j3yy
当前觉得网盘下载慢的,也可以直接官网下载,用注册机生成Lisence即可(网上有教程),个人用没什么问题,企业组织的话最好购买正版
2. 软件安装
这个没什么特殊的,一路next就行。如果是自己用的,一般不建议装在C盘,因为后续芯片包都会默认安装在此目录下,文件会变得很大。
3. 下载/安装芯片包
跟旧版本的Keil不一样,Keil4以前是软件里集成芯片包,也就是只要下载安装完Keil的软件,就有对应的一些芯片可供选择使用。但由于现在软件支持的芯片越来越多,软件的体量也就越来越大,如果把所有芯片包都跟软件打包一起下载,那软件估计得有几百个G。所以为了简洁,Keil把集成环境跟芯片包、例程等东西分开单独下载,具体要用到什么芯片再自己去下载安装对应的芯片包。
这里以 STM32F103 为例
方式一:在Keil里下载
点击 “Pack Installer”,也就是这个图标,第一次打开可能会很慢,因为要从官网自动更新所有芯片包的信息。这时候很坑的一个点是,你不更新,可能又没法找到你想要的芯片,所以在信息更新完前,只能乖乖地等它更新完。然而这种国外链接,又时不时给你断一下。

在更新完后,在左边的窗口中找到想要安装的芯片型号,可以选择整个系列(或具体芯片,结果是一样的),这里以STM32G071为例。然后在右边窗口中,找到"Device Specific"里面 “Keil:STM32F1xx_DFP” 这一项,点击按钮 “Install” 下载安装。(同样的,网络卡的时候下载很慢,还经常断开链接)
等到下载安装完成后(右下角有进度条),“Install"键会变成"up to date”,这时候说明安装成功。
当前也有可能出现 install 是灰色的,这样只能去官方网站下
方式二:官网下载
前面那种方法在很多时候都是行不通的,不是网络不好就是网络不好。所以可以通过另外一个方式更新芯片包,那就是先从官网提前下载好芯片包,再点击安装。
官网链接:https://www.keil.com/dd2/Pack/
同样,先找到对应的芯片(这里展开时可能不会显示所有芯片,找不到对应芯片时,点击下面"View all in family"展示所有芯片),选择"xxxxx_DFP",点"Download Recommended Pack"即可下载。

点击进去之后,如下:

这种方式有个好处就是即使在官网无法下载时,也可以假借他人之手去下载。为了防止小伙伴们在官网下载也出现网络中断的情况,这里提供STM32常用系列的芯片包供下载使用(版本可能不是最新的,可以凑和着用)。
这种方法安装之后的包记得放在软件的 Packs 路径下,如下:

然后直接点击这个包进行安装,一路 Next 即可
4. 注意事项
- 工程路径下不可以有中文,否则可能编译或调试时会有影响。
- 工程文件路径不可过长,这个软件对路径的识别是有长度限制的,当文件的总路径长度超过一定限制后,编译时可能会报无法查找到相关文件。
三、创建工程
步骤 1:新建工程
① 打开 Keil MDK 5
② 点击 Project → New uVision Project

③ 选择保存路径,输入工程名(如 RTC_Time_Demo)
④ 点击保存
步骤 2:选择芯片型号
① 在弹出的设备选择窗口中,展开 STMicroelectronics
② 选择 STM32F1 Series → STM32F103

③ 选择你的具体型号(如 STM32F103C8)
④ 点击 OK
步骤 3:配置运行环境
弹出询问是否添加启动文件和 CMSIS 时:
- 勾选 CMSIS 下的 CORE
- 勾选 Device 下的 Startup
- 点击 OK

这个时候一个工程项目就生成好啦,如下:

新建/添加文件
有了工程还不够,就像建房子一样,这时候只是把钢筋水泥弄好,做出个房子的外型,离真正可以居住的温馨小屋还差亿点点距离。所以这时候就得加点核心进来,也就是我们的源代码。
创建示例工程
用 Pack Installer 安装 DFP 后,直接打开芯片厂商提供的示例工程,理解工程结构
这里以其提供的工程项目为例,如下:

| 示例名称 | 难度 | 用途 |
|---|---|---|
| CMSIS-RTOS Blinky | ⭐ 简单 | LED 闪烁 + RTOS 基础 |
| USB Device Virtual COM | ⭐⭐ 中等 | 串口通信 |
| emWin Example | ⭐⭐⭐ 较难 | 图形界面显示 |
| USB Device HID | ⭐⭐⭐ 较难 | USB 键盘/鼠标 |
| USB Device Mass Storage | ⭐⭐⭐ 较难 | U盘功能 |
| File System Demo | ⭐⭐⭐ 较难 | SD 卡文件操作 |
| CAN/CAN RTR | ⭐⭐⭐ 较难 | CAN 总线通信 |
| emWin GUI Demo | ⭐⭐⭐⭐ 困难 | 复杂图形界面 |
这里为了方便理解,我就选择CSIS-RTOS Blinky
- 点击对应的 Copy 按钮
- 等待下载完成(可能需要几分钟)
- 安装完成后,示例会自动添加到系统中

理解工程结构
打开工程后,会看到以下文件结构:
Project: RTOS_Blinky
│
├───RTE (Run-Time Environment)
│ ├───CMSIS
│ │ └── RTX_Conf_CM.c ← RTOS 配置文件
│ ├───Device
│ │ └── STM32F103C8
│ │ ├───startup_stm32f10x_md.s ← 启动文件
│ │ └───system_stm32f10x.c ← 系统配置
│ └───_RTOS_Blinky
│
├───Blinky.c ← 主程序(LED 闪烁)
├───main.c ← 入口函数
└───README.txt ← 说明文档
📄 关键文件说明:
main.c - 程序入口:
int main(void) {
SystemInit(); // 系统初始化(时钟配置)
osKernelInitialize(); // RTOS 内核初始化
osThreadCreate(osThread(Blinky), NULL); // 创建 LED 任务
osKernelStart(); // 启动 RTOS
}
Blinky.c - LED 闪烁任务:
void Blinky(void const *argument) {
for (;;) {
LED_On(); // 开 LED
osDelay(500); // 延时 500ms
LED_Off(); // 关 LED
osDelay(500); // 延时 500ms
}
}
四、具体使用
1. 打开工程
- 在 Keil 5 中,点击 Project → Open Project(或按
Ctrl+O) - 导航到示例工程目录
- 选择
.uvprojx文件(Keil 5 工程文件) - 点击 Open

打开之后结果如下:

2. 新建/添加文件
如果是有了工程还不够,就像建房子一样,这时候只是把钢筋水泥弄好,做出个房子的外型,离真正可以居住的温馨小屋还差亿点点距离。所以这时候就得加点核心进来,也就是我们的源代码。

创建文件组
- 右击项目选择 Manege Project Items
- 右键 Source Group 1 → Rename → 改为 User
- 右键 Target 1 → Add New Group to Group ‘User’
- 输入:Driver
- 再添加一个组:
- 输入:System

但是当前我是以示例工程作为示例,所以可以不用新增其他文件
3. 配置工程
为了可以正常地跟开发板及烧录器进行匹配,这里我们还需要对工程进行一些配置。
3.1 选择正确的芯片型号
-
右键点击项目名 → Options for Target ‘…’(或点击工具栏魔术棒图标 🔧)

-
在 Device 标签页:
- 点击 Change… 按钮
- 展开 STMicroelectronics → STM32F1 Series
- 选择你的具体型号,例如:STM32F103VB
- 点击 OK

3.2 配置调试器
选择在线调试或离线仿真两种方式,如果有开发板,建议选在线调试直接在板子上进行实验。

离线仿真设置
- 选择仿真器:在 Keil5 中,点击魔法棒图标,进入项目设置页面。在“Debug”选项 卡中,选择“Use Simulator”。
- 设置晶振:输入你所使用的单片机板子的晶振频率。
- 选择 DLL 文件:根据所使用的单片机型号,选择相应的 DLL 文件。例如,使用 STM32 系列单片机时,选择 DARMSTM.DLL。

如果是没有开发板的情况,想要大致跑下自己写的逻辑有没有问题,可以使用离线仿真这种方式。但如果逻辑中涉及跟单片机外设或开发板外围电路的一些配合,则不适合使用这种方式调试。
在线烧录设置
选择了在线调试后,需要选择烧录器的类型。
① 选择烧录器类型(这里我们选择,也就是开发板上自带的这个烧录器的类型)

这里还得看具体的烧录器配置,我之前选择ST-Link导致我后面在烧录的时候出现了:No ST-LINK detected",表示我选错了 选错了调试器类型
② 点击右侧的 Settings 按钮:
-
Port 选择:SW
-
Max Clock 设置为:5 MHz(默认 10MHz)(如果烧录失败,降低到 1 MHz)
-
点击 OK

③ 测试连接:
-
点击 Flash Download 标签页
Programming Algorithm:烧录算法选择,一般选择完芯片后,会自动选择对应的烧录算法。手动添加烧录算法。添加方式很简单,把对应的算法文件(后缀是FLM)放到Keil安装根目录 Keil_v5/ARM/Flash 路径下,点 Add 按钮,选择对应的文件即可。
-
点击 Add 添加 Flash 算法(通常会自动添加)
-
确保看到你的芯片 Flash 信息

- Erase Full Chip:擦除整片,每次下载时,都会对整个Flash进行擦除操作。
- Erase Sectors:擦除部分,每次下载时,只会擦除使用到的Flash扇区(备注:只要在start和size设置好程序擦除的范围就可以避免自己的存储的flash数据被误擦)。
- Do not Erase:不擦除,每次下载时,不擦除原本代码。
- Program:烧录,下载时才会把代码写入Flash,否则不写入。
- Verify:校验,烧录代码之后,对代码进行校验。
- Reset and Run:复位并运行,下载完成之后,立即复位运行程序。
- RAM for Algorithm:给烧录算法的RAM空间,一般选择完芯片之后,按默认就行。
- Start:RAM空间的起始地址。
- Size:RAM空间的大小。
理解 Max Clock
Max Clock 是 SWD/JTAG 调试接口的时钟频率(SWCLK 引脚的信号频率)。
作用原理:
PC (Keil) ←→ CMSIS-DAP←→ SWCLK/SWDIO ←→ STM32芯片
↓
这个时钟频率控制通信速度
- 高频率 = 烧录/调试速度快,但稳定性差
- 低频率 = 烧录/调试速度慢,但稳定性好
场景对比:
| 情况 | 推荐频率 | 原因 |
|---|---|---|
| 短接线、良好环境 | 10 MHz | 速度快,节省时间 |
| 长接线、杜邦线 | 1-5 MHz | 减少信号干扰 |
| 烧录失败、不稳定 | 1 MHz | 最稳定,保证成功 |
| 芯片时钟配置错误 | 1 MHz | 芯片时钟异常时仍能通信 |
常见问题场景:
问题 1:烧录时断时续
Error: Flash Download failed - Target DLL has been cancelled
解决:降低 Max Clock 到 1 MHz
问题 2:调试时经常断开
Error: Could not stop Cortex-M device
解决:降低频率,增加稳定性
问题 3:芯片时钟未配置或错误
- 如果芯片使用内部 8MHz HSI,SWD 频率过高会通信失败
- 降低到 1 MHz 确保可靠通信
Flash 算法
Flash 算法(在 Keil 里通常以 .FLM 文件存在)负责调试器与 MCU 内部 Flash 通信的全套操作:
| 功能 | 说明 |
|---|---|
| 擦除 (Erase) | 按扇区(Sector)或整片(Chip)擦除,将数据恢复为 0xFF |
| 编程/写入 (Program) | 把编译好的代码数据写入 Flash 指定地址 |
| 校验 (Verify) | 写入后立即读回对比,确保数据 100% 正确 |
| 空白检查 (Blank Check) | 检查某块区域是否已是空的(全 0xFF),避免重复擦除 |
| 读/写保护操作 | 解除或设置芯片的 Read/Write Protection 状态 |
🤔 为什么需要它?
不同 MCU 的 Flash 控制器硬件设计完全不同:
- 操作命令序列不同(STM32 是写寄存器解锁→擦除→编程→锁存)
- 时序要求不同(等待 Busy 标志、延迟周期)
- 扇区划分不同(F1 系列是 1KB/页,F4 系列是 16KB/128KB 混合扇区)
- 电压/温度补偿机制不同
Keil 的调试核心(ST-Link/J-Link 固件)是通用的,它不懂具体芯片怎么操作 Flash。Flash 算法就是**“翻译官”**,把通用的下载指令翻译成目标芯片能听懂的寄存器操作。
⚙️ 在 Keil 中是如何工作的?
当你点击下载或进入调试时,幕后流程如下:
- 加载:Keil 从
Flash Download列表中找到对应的.FLM文件 - 搬运:通过 SWD/JTAG 把这段算法代码临时下载到 STM32 的 RAM 中
- 执行:调试器发送命令,让 CPU 执行 RAM 里的算法代码
- 操作:算法代码直接读写 Flash 控制器寄存器,完成擦除/写入/校验
- 清理:操作完成后,算法从 RAM 移除,你的正式程序开始运行
💡 关键点:算法是跑在目标芯片 RAM 里的,不是跑在电脑或调试器里的。
📦 通俗比喻
调试器 (ST-Link) = 快递员
你的代码数据 = 包裹
Flash 算法 = 不同小区的“门禁密码 + 电梯操作指南 + 楼层分布图”
芯片内部 Flash = 一栋结构复杂的公寓楼
没有算法 → 快递员到了门口,不知道按哪个键、怎么进楼、包裹该放几零几
有了算法 → 快递员按指南操作,准确把包裹送到指定房间
3.3 编译选项设置
-
Target 标签页:
XTAL (MHz): 8.0 Read/Only Memory Areas: IROM1: Start = 0x08000000, Size = 0x10000 (64KB)
-
Output 标签页:
-
勾选 Create HEX File(生成 HEX 文件)
-
点击 Select Folder for Objects… 选择输出目录(一般默认生成放在当前工程路径下,所以这个可以不用管的)

有些场合下,只能通过Hex文件进行烧录,这时候就需要在工程里勾选"Create HEX File",这样在编译之后工程会自动生成Hex的可执行文件。
-
-
C/C++ 标签页:(重点⭐⭐,必须设置)
-
Define 框中输入:
USE_STDPERIPH_DRIVER, STM32F10X_MD -
Include Paths 添加必要路径:
-
点击 … 按钮
-
添加:
./RTE/_RTOS_Blinky ./RTE/CMSIS ./RTE/Device/STM32F103VB
-
-

知识补充
🔍Q1.Define 框里的内容到底是什么?
在 C 语言中,#define 用于定义宏。Keil 的 Define 框的作用是:在编译整个工程时,自动在所有源文件头部注入这些宏定义。
1. USE_STDPERIPH_DRIVER
-
字面意思:使用标准外设驱动库(Standard Peripheral Library)
-
底层作用:STM32 的官方库文件(如
stm32f10x.h)里写满了条件编译代码:#ifdef USE_STDPERIPH_DRIVER #include "stm32f10x_conf.h" // 引入外设配置文件 #endif如果你不在 Define 框里写这个宏,编译器就会跳过
#include,导致后续所有 GPIO、USART、RTC 等函数全部报undefined identifier(未定义标识符)。💡 注:如果用的是较新的 HAL 库,这里通常换成
USE_HAL_DRIVER。你看的这个老示例基于 SPL 库,所以是STDPERIPH。
2. STM32F10X_MD
-
字面意思:STM32F10 系列 中容量(Medium Density) 芯片
-
底层作用:STM32F103 有很多子型号,Flash 大小不同,外设也有差异。库文件通过宏来区分:
#if defined (STM32F10X_LD) // 小容量 (16K~32K Flash) #elif defined (STM32F10X_MD) // 中容量 (64K~128K Flash) → 如 C8、RB #elif defined (STM32F10X_HD) // 大容量 (256K~512K Flash) → 如 ZET6、RCT6 #endif定义
MD后,编译器只会编译与你芯片匹配的外设代码,避免编译进不存在的硬件驱动导致报错,同时减小固件体积。⚠️ 注意:如果实际用的是
STM32F103RCT6(256KB Flash),这里必须改成STM32F10X_HD,否则烧录后部分功能会异常!
📂 Q2.Include Paths(头文件路径)为什么必须手动加?
编译器的“找文件”规则:
当写 #include "stm32f10x.h" 时,编译器默认只去两个地方找:
- 当前
.c文件所在的文件夹 - 编译器自带的标准库路径
但 Keil 的 Pack 安装包把文件分散放在了 RTE/ 子目录里,编译器根本不知道去哪找。Include Paths 就是告诉编译器:“去这些文件夹里搜头文件!”
如果不加这些路径 → 编译直接报:
error: #5: cannot open source input file "stm32f10x.h": No such file or directory
🛠 现代 Keil 开发中的“自动 vs 手动”
你问“其他一般默认即可,为啥这个要手动?” 这里有个重要背景:
- 早期 Keil(无 Pack 时代):所有路径和宏都必须手动敲,非常繁琐。
- 现代 Keil 5 + CMSIS-Pack:当通过 Pack Installer 安装 DFP 并在 RTE 界面勾选组件后,Keil 理论上会自动生成 这些路径和宏。
- 为什么还看到需要手动加?
- Pack 安装不完整或路径未刷新。
- 手动配置是最稳妥的兜底方案,尤其适合理解底层机制。
✅ 建议:在新建工程时,如果使用了 Pack 和 RTE 勾选器,通常不需要手动填。但理解这些配置的含义,能让你在遇到
#include找不到、宏未定义、芯片型号不匹配等 90% 的编译错误时,瞬间定位问题.
3.4 RTX RTOS 配置
-
展开左侧项目树,找到 RTE 文件夹
-
双击 RTX_Conf_CM.c 文件
-
检查关键配置:
#define OS_CLOCK 72000000 // 系统时钟 72MHz #define OS_TICK 1000 // RTOS 心跳 1ms

4. 编译工程
方法 1:工具栏按钮
- 点击工具栏的 Rebuild 按钮(两个箭头循环图标 🔄)
方法 2:快捷键
- 按 F7 键
方法 3:菜单
- Project → Rebuild all target files

查看编译结果
底部 Build Output 窗口显示:

成功标志:0 Error(s), 0 Warning(s)
注:如果此时出现了Error信息,则无法编译通过,需要修改源代码直到编译结果0-Error,才可以正常生成可执行文件。如果出现Warning信息,可视情况进行处理,Warning信息不影响编译结果,但建议多关注下这些Warning信息,很多Bug就隐藏在里面。
常见编译错误及解决:
错误 1:找不到头文件
error: #5: cannot open source input file "stm32f10x.h": No such file or directory
解决:
- Options → C/C++ → Include Paths
- 添加路径:
./RTE/Device/STM32F103C8
示例:
D:\lifeskill\Keil5\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include\stm32f10x.h(8347): error: #5: cannot open source input file "stm32f10x_conf.h": No such file or directory
#include "stm32f10x_conf.h"
Blinky.c: 0 warnings, 1 error
compiling Buttons_MCBSTM32E.c...
这个错误非常明确:编译器找不到 stm32f10x_conf.h 文件。这是 STM32 标准外设库(SPL)的核心配置文件,示例工程依赖它来启用/关闭各种外设。
别担心,这是 Keil 导入旧版 Pack 示例时的常见问题。
-
方式一:将该文件(文件可以用 Everything 搜一下就可以了,一般默认放在
\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include)复制到 复制 到工程根目录(即和Blinky.uvprojx同级的文件夹)。原理:Keil 默认会将工程根目录加入头文件搜索路径。文件放这儿,编译器立刻就能找到
-
方式二:在 Keil 中添加头文件路径(更规范)
-
重新编译:点击 Keil 的 Clean(垃圾桶图标)→ 再点击 Rebuild(F7)。
错误 2:未定义符号
error: #20: identifier "LED_PORT" is undefined
解决:
- 检查是否安装了正确的 Pack
- Pack Installer → 安装 STM32F1xx_DFP
错误 3:代码大小超限
Error: L6406E: No space in execution regions
解决:
- MDK-Lite 版本限制 32KB
- 使用教育授权或商业版
5. 烧录程序到开发板
经过前面的步骤,我们已经得到了机器中识别的执行文件.axf。并且工程也已经配置了对应的烧录器及芯片,此时先连接烧录器到开发板上,点击"Project"->“Optinos for Target ‘xxx’”->“Debug”->"Setting"查看当前是否已正常连接。如果已正常连接,点击,可以看到左下方有个烧录的进度条。
烧录程序
方法 1:工具栏按钮
- 点击 Load 按钮(向下箭头⬇️图标)
方法 2:快捷键
- 按 Ctrl + F8
方法 3:菜单
- Flash → Download
此时底部窗口会显示:

✅ 成功标志:Verify OK
烧录失败排查
问题 1:No Target Connected
Error: Flash Download failed - No Target Connected
解决:
- 检查接线
- 检查开发板供电(3.3V LED 是否亮)
- Options → Debug → Settings → 测试 SWD 连接
问题 2:Flash Algorithm 缺失
Error: Flash Download failed - Target DLL has been cancelled
解决:
- Options → Debug → Settings → Flash Download
- 点击 Add 添加正确的 Flash 算法
- 选择 STM32F10x Medium Density Flash
成功烧录之后显示的结果

烧录程序 FlyMcu(mcuisp)
通过串口下载程序
FlyMcu 通过 ISP 烧录与调试器“直接烧录”的最终结果完全一样(都是把 HEX 里的机器码写入 MCU 的 Flash),但实现路径、硬件依赖、速度、功能边界有显著差异。下面按维度对比:
核心区别对比
| 对比维度 | FlyMcu + ISP(串口烧录) | 调试器“直接烧录”(SWD/JTAG) |
|---|---|---|
| 通信接口 | UART(TX/RX) | SWD 或 JTAG 调试接口 |
| 协议/通道 | 依赖芯片出厂固化在 ROM 的 Bootloader | 调试器通过 CoreSight 架构直接访问 Flash 控制器,绕过 Bootloader |
| 硬件依赖 | USB 转 TTL 模块(CH340/CP2102 等) | ST-Link / J-Link / DAP-Link 等仿真器 |
| 引脚要求 | 需配置 BOOT0=1, BOOT1=0(以 STM32F1 为例),使用特定串口引脚 | 仅需 SWDIO、SWCLK、GND、3.3V,不受 BOOT 引脚影响 |
| 烧录速度 | 受限于串口波特率(通常 115.2k~921.6k),几十 KB 需数秒~十秒级 | SWD 有效速率可达数 MHz,通常 1~3 秒完成 |
| 功能支持 | 仅支持擦除、烧录、校验、读 Flash | 支持全功能调试、断点、内存读写、Option Bytes 配置、读保护管理、半主机等 |
| 读保护影响 | 若芯片已开启读保护(RDP L1),ISP 通常直接失败 | 调试器可检测保护状态,支持执行整片擦除解除(需确认是否允许) |
| 适用场景 | 量产烧录、现场固件升级、无调试器的简易开发板 | 日常开发调试、快速迭代、需要在线 Debug 的项目 |
本质相同点
- 写入内容完全一致:HEX 只是 Intel 格式的文本载体,最终都会被转换成二进制机器码写入相同的 Flash 地址。程序运行效果没有任何区别。
- 都不改变硬件设计:只要引脚正确、供电稳定,两种方法写入后 MCU 的行为完全一样。
(1)打开 FlyMcu.exe 如图所示

(2)用数据线连接 EBD-A23 开发板的 USB 口,点击搜索串口,再从 Port 菜单中选择对应的 端口号(可从计算机的设备管理器中获知正确的端口号),如图上的 COM14。
(3)从工程文件夹中,找到对应的 hex 文件,点击打开,如图下所示。

(4)接着选择 STMISP 项,设置如上所示
(5)点击开始编程,则系统监测串口,等待芯片连接信号,如下所示,

(6)在开发板上按住 ISP 按键后(BOOT0 高电位,进入 ISP 模式启动),再按 RESET 按键,释 放 RESET 键后再释放 ISP 键即可将 hex 文件下载到开发板上,如图下所示。可以从开发板 上观察程序运行现象。

6. 运行和调试
方式 1:直接运行(最简单)
- 烧录成功后,拔掉 CMSIS-DAP
- 给开发板单独供电(5V 或 3.3V)
- 观察 LED 闪烁(通常 PC13 引脚)
方式 2:调试运行(推荐学习)
步骤 1:进入调试模式
-
点击工具栏的 Start/Stop Debug Session 按钮(🐞 图标)
-
或按 Ctrl + F5
退出调试界面非常简单,再次按下
Ctrl + F5即可(该快捷键是“进入/退出调试”的切换开关)。🖱️ 鼠标操作方式
-
顶部工具栏按钮:点击那个 带红色叉号的调试图标(鼠标悬停会显示
Start/Stop Debug Session)。(注:实际图标为红色方块或带斜杠的虫子)
-
菜单栏:点击
Debug→Start/Stop Debug Session。
💡 退出后的状态说明
项目 说明 界面变化 自动切回普通的代码编辑视图,底部 Registers/Watch 等调试窗口关闭 芯片状态 MCU 不会复位,会继续独立运行你之前烧录的程序(只要不断电) 代码修改 退出后可直接编辑代码,下次编译会自动覆盖旧程序 按钮变灰 如果按钮呈灰色不可点,说明已退出调试或连接已断开,无需额外操作 -
步骤 2:调试界面介绍

- Disassembly - 反汇编窗口(可关闭)
- Watch - 变量观察窗口
- Call Stack + Locals - 调用栈和局部变量
- Peripherals - 外设寄存器
界面乱了想恢复到原来的样子怎么办,如下:

效果:所有窗口会恢复到 Keil 默认布局,包括 Watch、Registers、Memory 等调试窗口
步骤 3:常用调试操作
| 操作 | 快捷键 | 说明 |
|---|---|---|
| 单步跳过 | F10 | 执行当前行,不进入函数 |
| 单步进入 | F11 | 进入函数内部 |
| 跳出函数 | Ctrl+F11 | 执行完当前函数返回 |
| 全速运行 | F5 | 运行到下一个断点 |
| 设置断点 | Ctrl+B | 在代码行左侧点击 |
| 停止调试 | Ctrl+F5 | 退出调试模式 |
步骤 4:观察 LED 控制
- 在
Blinky.c的LED_On()处设置断点(点击行号左侧) - 按 F5 运行
- 程序会在断点处暂停
- 查看 Peripherals 窗口:
- 展开 GPIOC
- 观察 ODR 寄存器变化
- 按 F5 继续,观察 LED 状态
五、清除 STM32 已烧录程序
当你发现板子没烧录就有灯亮,说明芯片里已经有程序在运行了。以下是几种清除方法:
方法 1:使用 Keil 全片擦除(最简单)
步骤:
-
确保调试器连接正常
- 魔术棒 → Debug → 选择你的调试器(CMSIS-DAP)
- 点击 Settings → 确认能看到芯片信息
-
执行全片擦除:
-
点击工具栏的 Erase 按钮(橡皮擦图标 🧹)
-
或者:Flash → Erase 菜单

-
-
观察输出窗口:
Batch-Build summary: 0 succeeded, 0 failed, 3 skipped - Time Elapsed: 00:00:00 Full Chip Erase Done. Flash Erase finished 11:40:38 -
验证:
- 擦除后,板子上的 LED 应该会熄灭或状态改变
- 因为 Flash 全为 0xFF,程序无法正常运行
方法 2:使用 STM32CubeProgrammer(推荐,功能最强)
从 ST 官网免费下载:
https://www.st.com/en/development-tools/stm32cubeprog.html
擦除步骤:
-
打开 STM32CubeProgrammer
-
选择连接方式:
- 右侧选择CMSIS-DAP
- 点击 Connect
-
全片擦除:
- 顶部菜单点击 Erasing & Programming
- 点击 Full chip erase
- 等待完成
-
验证:
- Memory Editor 查看 Flash 区域,应该全是
FF
- Memory Editor 查看 Flash 区域,应该全是
六、ISP 和 RST 按钮
这两个按钮是 STM32 开发板上最常用的物理按键,理解它们能让你轻松解决 90% 的"烧录失败"和"程序不跑"问题。
1. RST 按钮(Reset / NRST)
我的数码管不亮灯就是因为我没按这个,没招了
作用:硬件复位,让芯片"重启"
工作原理:
按下 RST → NRST 引脚被拉低 → 芯片内部复位电路触发
↓
1. CPU 寄存器清零
2. 程序计数器 PC = 0x00000000
3. 重新执行启动文件 (startup_stm32f10x.s)
4. 跳转到 main() 函数
常见使用场景:
| 场景 | 操作 | 效果 |
|---|---|---|
| 程序跑飞/死机 | 按一下 RST | 芯片重启,程序从头执行 |
| 烧录后不运行 | 烧录完成 → 按 RST | 让新程序立即生效 |
| 调试时重置状态 | Debug 模式下按 RST | 清除所有变量/寄存器状态 |
| 切换启动模式后 | 改完 BOOT 跳线 → 按 RST | 让新启动配置生效 |
小技巧:
- 按住复位键烧录:如果程序禁用了 SWD 引脚导致无法连接,可以按住 RST → 点烧录 → 1 秒后松开,能"抢"在程序运行前完成烧录。
2. ISP 按钮(In-System Programming)
作用:切换启动模式,让芯片进入"系统存储器启动"(用于串口下载)
核心原理:STM32 的三种启动模式
STM32F103 通过 BOOT0 和 BOOT1 两个引脚的电平决定启动方式:
| BOOT1 | BOOT0 | 启动模式 | 用途 |
|---|---|---|---|
| 0 | 0 | Main Flash Memory ✅ | 正常运行用户程序(默认) |
| 0 | 1 | System Memory 🔧 | ISP 模式,用于串口下载 |
| 1 | 0 | SRAM 🧪 | 调试用,断电程序丢失 |
| 1 | 1 | 保留 | 不建议使用 |
ISP 按钮的典型电路:
3.3V
│
10kΩ (上拉电阻)
│
BOOT0 ─┼─────┐
│ │
[ISP] │ ← 按下时 BOOT0 = 0 (接地)
│ │
GND 100nF (滤波电容)
⚠️ 注意:不同板子设计可能相反!有些板子 按下 ISP = BOOT0=1(通过上拉),请以原理图为准。
3. ISP 按钮的使用流程(串口下载专用)
如果调试器坏了,或者想用串口(USART1)直接烧录,就需要用到 ISP 按钮:
步骤 1:硬件准备
开发板 USB转TTL模块
───── ───────────
3.3V → 3.3V
GND → GND
PA9(TX) → RX
PA10(RX)→ TX
步骤 2:进入 ISP 模式
1. 断电
2. 按住 [ISP] 按钮不放
3. 按住 [RST] 按钮 → 松开 → 再松开 [ISP]
(此时 BOOT0=1, BOOT1=0,芯片进入系统存储器启动)
步骤 3:用工具烧录
- 打开 FlyMcu、STM32CubeProgrammer 或 sscom + XMODEM
- 选择正确 COM 口,波特率 115200
- 加载
.hex文件 → 点击"开始编程"
步骤 4:恢复正常运行
1. 烧录完成
2. 断电
3. 松开 [ISP] 按钮(BOOT0 恢复为 0)
4. 按一下 [RST] 重启
5. 程序开始运行!✅
4. 常见问题排查
问题 1:按了 RST 程序还是不跑
可能原因:
- 供电不稳 → 检查 3.3V LED 是否常亮
- 复位电路故障 → 用万用表测 NRST 引脚,按下时应≈0V,松开≈3.3V
- 程序本身有死循环 → 用调试器单步跟踪
问题 2:按 ISP + RST 后串口没反应
排查步骤:
- 确认 BOOT0/BOOT1 电平(万用表测):
- ISP 按下时:BOOT0 应为 1(或 0,依设计而定)
- BOOT1 应始终为 0
- 确认串口接线:TX↔RX 交叉,共地
- 尝试不同波特率:9600 / 115200 / 57600
- 用 FlyMcu 的"清除芯片"功能先擦除
问题 3:烧录后必须按 RST 才运行
正常现象!
因为烧录完成后芯片停在"编程状态",按 RST 才会跳转到用户程序入口
【★,°:.☆( ̄▽ ̄)/$:.°★ 】那么本篇到此就结束啦,如果有不懂 和 发现问题的小伙伴可以在评论区说出来哦,请持续关注我 !!
更多推荐
所有评论(0)