下面把这块 STM32F103ZET6 开发板的学习流程、程序烧写原理、Keil 操作以及断点调试完整串起来。你后面学习任何外设,都可以重复使用这套方法。

先提醒一点:你当前使用的是正点原子课程例程,但实物开发板和上传的原理图不一定完全同款。你上传的原理图中,调试接口连接 PA13/SWDIO、PA14/SWCLK,八路 LED 使用 PE0~PE7;而当前例程控制的是 PB5。因此,学习芯片内部原理可以继续使用,但判断具体哪个 LED、按键或接口时,必须以实物板对应版本的原理图为准。

你当前的开发板与调试器连接

一、先建立对整个开发系统的认识

你现在使用的系统不是只有一块开发板,而是由四部分构成:

 
电脑
│
│  Keil 编写、编译和调试代码
│
USB
│
ST-LINK/V2 调试器
│
│  SWDIO、SWCLK、NRST、GND、VTref
│
STM32F103ZET6 开发板
│
│  GPIO、串口、定时器、ADC、SPI、I²C、CAN……
│
LED、按键、LCD、传感器等外围器件

它们分别负责:

部分 作用
Keil 写代码、编译、下载、设置断点、查看变量
ST-LINK 将电脑命令转换为 STM32 能识别的调试信号
SWD ST-LINK 与 STM32 之间的通信协议
STM32 真正执行程序、控制硬件
开发板外围电路 LED、按键、LCD、传感器、通信接口等

ST-LINK和SWD不是同一个东西

可以这样理解:

 
ST-LINK = 调试器设备
SWD     = 调试器和STM32之间使用的通信方式

你当前配置是:

 
调试器:ST-LINK/V2
通信方式:SWD

连接中最重要的信号:

信号 作用
SWDIO 双向调试数据
SWCLK 调试时钟
GND 公共地
VTref/3.3V 目标板电平参考
NRST 芯片复位

二、STM32程序是怎样从代码变成板上动作的

你现在看到的是 C 语言代码:

 
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
delay_ms(200);

但是 STM32 不能直接理解 C 语言,它最终执行的是机器指令。

完整过程是:

 
main.c、led.c等源文件
          ↓
       编译 Compile
          ↓
每个源文件生成目标文件 .o
          ↓
       链接 Link
          ↓
生成 atk_f103.axf
          ↓
Keil通过ST-LINK下载
          ↓
写入STM32内部Flash
          ↓
STM32复位
          ↓
执行启动文件
          ↓
进入main()
          ↓
PB5输出电平变化

1. 编译的作用

在 Keil 中按:

 
F7

编译器会完成:

 
C代码 → 汇编指令 → 机器码

例如:

 
HAL_Init();

编译后可能变成类似:

 
BL.W HAL_Init

编译成功时会看到:

 
0 Error(s), 0 Warning(s)

至少必须保证:

 
0 Error(s)

2. 链接的作用

工程中不仅有 main.c,还有:

 
led.c
delay.c
sys.c
stm32f1xx_hal_gpio.c
startup_stm32f103xe.s

链接器负责:

  • 把所有目标文件组合起来;
  • 为函数分配地址;
  • 为全局变量分配内存;
  • 生成中断向量表;
  • 生成最终的 atk_f103.axf

3. AXF和HEX有什么区别

AXF

包含:

  • 机器代码;
  • 函数名;
  • 变量名;
  • 源码与地址对应信息;
  • 调试符号。

Keil 在线断点调试主要使用 AXF。

HEX

主要包含需要写入 Flash 的程序数据,常用于脱离 Keil 的量产烧写。

三、程序烧写到 STM32 的完整原理

在完成 STM32 工程代码编写后,需要将程序转换成芯片能够执行的机器指令,并通过调试器写入 STM32 内部 Flash。这个过程通常称为程序烧写、程序下载或程序烧录

在 Keil MDK 中,完整流程可以概括为:

保存源代码
    ↓
编译和链接工程
    ↓
生成 AXF/HEX 程序文件
    ↓
通过 ST-LINK 连接 STM32
    ↓
擦除目标 Flash
    ↓
写入程序
    ↓
校验程序
    ↓
复位并运行

需要特别注意:

“编译程序”和“下载程序”是两个不同的操作。
编译只是生成程序文件,下载才会把程序真正写入 STM32。


3.1 烧写程序需要哪些硬件

烧写程序时,系统由以下几部分组成:

电脑
  │
  │ USB
  ↓
ST-LINK 调试器
  │
  │ SWD
  ↓
STM32 开发板

各部分作用如下:

设备 作用
电脑 运行 Keil,完成代码编辑、编译和下载
Keil MDK 将 C 代码编译为机器代码,并控制下载过程
ST-LINK 连接电脑和 STM32,负责程序下载和在线调试
SWD ST-LINK 与 STM32 之间使用的调试通信协议
STM32 内部 Flash 保存最终的用户程序

ST-LINK 通过 USB 与电脑连接,通过 SWD 接口与 STM32 连接。

SWD 常用信号包括:

信号 作用
SWDIO 调试数据输入、输出
SWCLK 调试通信时钟
GND 公共地
VTref/3.3V 目标板电平参考
NRST STM32 复位信号

烧写前应确认:

  1. STM32 开发板已经正常供电;

  2. ST-LINK 已通过 USB 连接电脑;

  3. ST-LINK 与开发板之间的 SWD 接线正确;

  4. 调试器与开发板必须共地;

  5. BOOT0 一般保持低电平,从内部 Flash 启动;

  6. 同一时间不要使用两个调试器连接同一块开发板。

【建议配图:电脑、ST-LINK、开发板之间的连接实物图】


3.2 在 Keil 中配置 ST-LINK

第一次使用工程时,需要先配置下载器。配置完成后,后续通常不需要重复设置。

3.2.1 打开工程配置窗口

点击 Keil 顶部菜单:

Project
→ Options for Target

也可以点击工具栏中的“魔术棒”图标。

该窗口用于设置:

  • 目标芯片;

  • 编译参数;

  • 调试器;

  • Flash 下载算法;

  • 程序输出格式。

【建议配图:Keil 工具栏中的 Options for Target 魔术棒按钮】


3.2.2 检查目标芯片

进入:

Device

确认选择的芯片与开发板实际芯片一致。

以 STM32F103ZET6 为例,通常应选择:

STM32F103ZE

芯片选择会影响:

  • 启动文件;

  • Flash 容量;

  • SRAM 容量;

  • 寄存器定义;

  • Flash 下载算法;

  • 链接地址。

如果芯片型号选择错误,可能出现程序无法下载、Flash 容量错误或程序运行异常。


3.2.3 选择 ST-LINK 调试器

进入:

Debug

在右侧调试器下拉框中选择:

ST-Link Debugger

然后点击:

Settings

在设置窗口中确认:

Unit:ST-LINK/V2
Port:SW

其中:

  • ST-LINK/V2 表示使用的硬件调试器;

  • SW 表示使用 SWD 通信方式。

如果连接正常,窗口中通常可以看到:

  • ST-LINK 序列号;

  • ST-LINK 固件版本;

  • ARM CoreSight SW-DP;

  • 芯片调试接口 IDCODE。

这说明连接链路已经建立:

Keil
  ↓
ST-LINK
  ↓
SWD
  ↓
STM32

如果显示:

No Debug Unit Device Found

表示电脑没有识别到 ST-LINK。

如果能够识别 ST-LINK,但显示:

No Target Connected

表示 ST-LINK 已被电脑识别,但没有成功连接 STM32,需要检查开发板供电、排线方向、SWDIO、SWCLK 和 GND。

【建议配图:ST-LINK Debug 设置窗口,标注 Unit、Port 和 SW Device】


3.3 配置 Flash 下载算法

STM32 不同型号的 Flash 容量不同,因此必须选择正确的 Flash 编程算法。

在 ST-LINK 设置窗口中打开:

Flash Download

对于 STM32F103ZET6,应看到类似:

STM32F10x High-density Flash
Device Size:512KB
Address Range:0x08000000~0x0807FFFF

STM32F103ZET6 内部 Flash 为 512KB,因此使用 High-density 下载算法。

如果算法列表中没有对应选项,可以点击:

Add

然后添加:

STM32F10x High-density Flash

推荐下载选项

建议选择:

Erase Sectors
Program
Verify
Reset and Run

各选项含义如下:

选项 作用
Erase Full Chip 擦除整片 Flash
Erase Sectors 只擦除程序使用到的 Flash 区域
Do not Erase 下载前不擦除,一般不建议使用
Program 将程序写入 Flash
Verify 下载后读取并校验程序
Reset and Run 下载成功后复位并运行程序

日常开发通常选择:

Erase Sectors

这样不需要每次擦除整个芯片,下载速度更快。

【建议配图:Flash Download 页面,标注 High-density、Erase Sectors、Program、Verify 和 Reset and Run】


3.4 保存工程代码

在下载程序之前,首先需要保存修改后的代码。

点击工具栏中的软盘图标,或者使用快捷键:

Ctrl + S

保存的作用是将代码编辑器中的修改写入电脑磁盘。

如果代码已经修改但没有保存,Keil 可能仍然编译旧版本文件,因此建议在每次编译前先执行:

Ctrl + S

3.5 编译工程

保存代码后,需要将 C 代码编译成 STM32 可以执行的机器代码。

可以使用以下任意一种方式:

方法一:点击 Build 按钮

点击 Keil 工具栏中的:

Build

其图标通常位于工具栏左侧,由多个向下箭头或工程构建图标组成。

方法二:通过菜单编译

点击:

Project
→ Build Target

方法三:使用快捷键

按:

F7

三种方法作用相同。

编译的主要工作

Keil 在编译过程中会依次完成:

预处理
  ↓
编译
  ↓
汇编
  ↓
链接
  ↓
生成最终程序文件

具体包括:

  1. 处理 #include 和宏定义;

  2. .c 文件编译为目标文件;

  3. 将启动汇编文件编译为目标文件;

  4. 将所有目标文件和库文件链接在一起;

  5. 分配函数和变量地址;

  6. 生成 AXF、HEX 等程序文件。

编译成功后,Build Output 中通常会显示:

0 Error(s), 0 Warning(s)

或者:

0 Error(s), 1 Warning(s)

只有 Error(s) 为 0 时,才能生成可下载程序。

如果出现:

Target not created

表示存在编译或链接错误,应先处理错误,再进行下载。

Build 与 Rebuild 的区别

Keil 中常见两个编译操作:

操作 作用
Build Target 只重新编译发生变化的文件
Rebuild All Target Files 重新编译整个工程的所有文件

日常修改少量代码时使用:

Build Target

如果修改了宏定义、头文件、工程配置,或者怀疑增量编译结果异常,可以使用:

Project
→ Rebuild all target files

3.6 下载程序到 STM32

工程编译成功后,才能执行程序下载。

可以使用以下任意一种方式。

方法一:点击 LOAD 按钮

点击 Keil 工具栏中的:

LOAD

该按钮通常带有向下箭头或“LOAD”文字,用于将程序写入目标芯片。

方法二:通过菜单下载

点击:

Flash
→ Download

方法三:使用快捷键

按:

F8

三种方式作用相同。

完整操作顺序为:

Ctrl + S
    ↓
F7
    ↓
确认 0 Error(s)
    ↓
F8

其中:

F7 = 编译程序
F8 = 下载程序

必须明确:

按 F7 之后,程序只生成在电脑中,并没有进入 STM32。
只有按 F8 或点击 LOAD 后,程序才会真正写入 STM32 内部 Flash。

【建议配图:Keil 工具栏上的 LOAD 按钮】


3.7 下载过程中 Keil 做了什么

点击 Download 后,Keil 会自动完成以下过程。

第一步:加载程序文件

Build Output 中会显示:

Load "...\Output\xxx.axf"

表示 Keil 正在读取编译生成的 AXF 文件。

AXF 文件中包含:

  • STM32 可执行机器代码;

  • 程序存储地址;

  • 函数和变量信息;

  • 调试符号;

  • 源代码与机器地址的映射关系。


第二步:连接 ST-LINK

Keil 通过 USB 驱动访问 ST-LINK。

Keil
  ↓ USB
ST-LINK

ST-LINK 再通过 SWD 访问 STM32 内核和存储器。

ST-LINK
  ↓ SWDIO、SWCLK
STM32

第三步:将 Flash 编程算法加载到 SRAM

Flash 擦写需要执行专门的编程算法。

Keil 会先将一段很小的 Flash 编程程序加载到 STM32 的 SRAM 中,例如:

RAM Start:0x20000000

然后控制 STM32 执行这段临时程序。

这段程序负责:

  • 解锁内部 Flash;

  • 擦除 Flash 扇区;

  • 写入程序数据;

  • 检查 Flash 状态;

  • 返回烧写结果。

这段 Flash 算法只是临时存放在 SRAM 中,断电后会消失,不属于最终用户程序。


第四步:擦除 Flash

如果选择了:

Erase Sectors

Keil 会擦除用户程序将要使用的 Flash 区域。

成功后显示:

Erase Done.

Flash 擦除的原因是:

Flash 通常只能直接将数据位从 1 写成 0,不能直接将 0 改回 1。
因此在写入新程序前,需要先进行擦除。

擦除后的 Flash 通常为:

0xFF

第五步:写入程序

擦除完成后,Keil 会将 AXF 中的程序数据发送给 ST-LINK,由 Flash 编程算法写入 STM32 内部 Flash。

STM32 用户程序通常从以下地址开始:

0x08000000

写入完成后显示:

Programming Done.

这说明程序已经写入 STM32。


第六步:校验程序

如果勾选了:

Verify

Keil 会重新读取 STM32 Flash 中的数据,并与电脑中的程序进行比较。

校验成功后显示:

Verify OK.

这表示:

  • 数据写入成功;

  • 写入内容与编译结果一致;

  • Flash 中没有检测到数据错误。


第七步:复位并运行

如果勾选:

Reset and Run

下载完成后,Keil 会通过 ST-LINK 向 STM32 发送复位命令。

输出信息通常为:

Application running ...

STM32 随后从内部 Flash 启动,开始执行用户程序。

完整成功信息通常为:

Erase Done.
Programming Done.
Verify OK.
Application running ...

看到以上信息,说明程序烧写成功并已经开始运行。


3.8 程序烧写后的启动过程

程序写入 STM32 后,芯片复位并不会直接跳到 main()

其启动过程为:

STM32复位
    ↓
读取0x08000000处的初始栈指针
    ↓
读取0x08000004处的复位处理函数地址
    ↓
执行Reset_Handler
    ↓
初始化系统内存
    ↓
初始化.data段
    ↓
清零.bss段
    ↓
执行SystemInit()
    ↓
进入C运行库初始化
    ↓
调用main()

其中:

  • 0x08000000 保存初始主栈指针;

  • 0x08000004 保存 Reset_Handler 的入口地址;

  • Reset_Handler 位于启动文件中;

  • main() 是用户程序入口。

因此,一个完整 STM32 工程通常包含:

启动文件
系统初始化文件
HAL或标准库文件
用户main函数
外设驱动文件

3.9 常用按钮与快捷键总结

操作 菜单路径 快捷键 作用
保存 File → Save Ctrl+S 保存当前代码
编译 Project → Build Target F7 编译发生变化的文件
全部重编译 Project → Rebuild all target files 重新编译整个工程
下载程序 Flash → Download F8 将程序写入 STM32 Flash
打开配置 Project → Options for Target 设置芯片、下载器和编译参数
进入调试 Debug → Start/Stop Debug Session Ctrl+F5 进入在线调试
复位芯片 Debug模式下点击RST 重新运行已烧写的程序

最常用的烧写顺序是:

Ctrl + S
→ F7
→ 检查0 Error(s)
→ F8
→ 检查Verify OK

3.10 编译、烧写、复位和调试的区别

这几个操作很容易混淆。

编译

F7

作用:

C代码 → 机器代码

结果只保存在电脑中。


下载或烧写

F8

作用:

电脑中的程序 → STM32内部Flash

会更新芯片中的程序。


复位

点击:

RST

作用:

重新执行STM32中已经存在的程序

复位不会重新编译,也不会重新下载。


在线调试

按:

Ctrl + F5

作用:

  • 通过 ST-LINK 控制 STM32;

  • 设置断点;

  • 单步运行;

  • 查看变量;

  • 查看内存;

  • 查看寄存器。

在线调试本身并不等同于程序烧写。


3.11 常见下载结果判断

下载成功

Erase Done.
Programming Done.
Verify OK.
Application running ...

表示擦除、写入、校验和运行全部成功。

未检测到调试器

No Debug Unit Device Found

可能原因:

  • ST-LINK未连接;

  • USB线异常;

  • ST-LINK驱动未安装;

  • Keil中选择了错误的调试器。

未检测到目标芯片

No Target Connected

可能原因:

  • 开发板没有供电;

  • SWDIO和SWCLK接错;

  • 没有共地;

  • 排线方向错误;

  • SWD速度过高;

  • 芯片处于异常状态。

Flash算法缺失

可能出现:

No Algorithm found

需要在 Flash Download 页面添加与芯片容量匹配的 Flash 编程算法。

下载后程序没有运行

可以检查:

  • 是否勾选 Reset and Run

  • BOOT0是否为低电平;

  • 程序是否进入异常;

  • 系统时钟初始化是否失败;

  • 看门狗是否导致反复复位;

  • 工程芯片型号是否选择正确。


3.12 程序烧写流程总结

STM32程序烧写的标准操作流程为:

第一步:连接开发板、ST-LINK和电脑
第二步:在Keil中选择正确的目标芯片
第三步:选择ST-Link Debugger
第四步:设置SWD通信方式
第五步:添加正确的Flash下载算法
第六步:保存代码
第七步:按F7编译工程
第八步:确认没有编译错误
第九步:按F8下载程序
第十步:确认Programming Done和Verify OK
第十一步:STM32复位并运行用户程序

其底层数据流向为:

C源代码
  ↓
Keil编译器
  ↓
AXF/HEX程序文件
  ↓
USB
  ↓
ST-LINK
  ↓
SWD
  ↓
STM32 SRAM中的Flash编程算法
  ↓
STM32内部Flash
  ↓
复位运行

理解这一过程后,就可以清楚区分代码保存、工程编译、程序下载、芯片复位和在线调试之间的关系。

 

 

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐