news 2026/9/24 12:34:52

无ST-LINK也能烧录STM32:USB DFU模式详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无ST-LINK也能烧录STM32:USB DFU模式详解

先说实话,我之前也一直默认“烧录STM32就得用ST-LINK”,直到手里只剩一块板子和一根USB线、下载器又落在办公室的时候,才认真把DFU模式翻出来研究了一遍。折腾完发现,USB DFU烧录这个方案比想象中成熟得多,而且在不少量产和现场维护场景里,它比ST-LINK更省事——毕竟USB接口谁都认识,不用额外装一堆调试器驱动。这篇就把我摸出来的完整路径写清楚,目标是让手里没ST-LINK的人也能顺利把程序灌进STM32。

1. 为什么没有ST-LINK也能烧录:DFU模式的本质和坑点

很多初学者会把“烧录程序”误解为必须依赖ST-LINK这个硬件,其实这个思路不完全对。ST-LINK只是把PC上的烧录指令转换成SWD/JTAG时序的桥梁,芯片本身才是一切烧录动作的最终执行者。STM32出厂时,在系统存储器(System Memory)里固化了一段Bootloader,这段Bootloader平时不跑,当你把BOOT引脚配置成从系统存储器启动时,它就会接管芯片,通过USB、UART或CAN等外设接收固件并写入Flash。这就是DFU模式的底层原理。

DFU全称是Device Firmware Update,即设备固件升级协议,USB-IF组织定义的标准。STM32里的DFU Bootloader把USB接口虚拟成一个DFU设备,电脑端通过ST官方工具或开源工具即可完成固件传输。这个设计最初主要用于产品固件升级,但反过来也能用来做初期烧录,只是国内多数教程都围绕ST-LINK展开,把DFU这条路埋没了。

这里最大的坑在于:不是所有STM32型号的USB DFU Bootloader都有完整功能。以经典STM32F103系列为例,出厂Bootloader确实支持USB DFU,但要求使用芯片的USB D+引脚和USB D-引脚,并且必须外接1.5k上拉电阻到3.3V,或者使用带内部上拉的封装。很多最小系统板把USB D+的上拉电阻省了,导致DFU枚举失败,电脑一直提示无法识别USB设备。所以动手前得先确认你的板子USB电路是靠外部上拉还是内部上拉,否则后面寸步难行。

还有一个容易忽略的问题:DFU Bootloader只是系统存储器里的一段程序,它本身不占用户Flash,也不会被用户程序覆盖。但有些芯片出厂时会禁用USB DFU功能,比如STM32F107和STM32F2/F4的早期批次,官方文档会标明这些器件不支持USB DFU。我的建议是:烧录前先查对应型号的AN2606应用笔记,确认系统存储器的Bootloader支持列表,能省很多无用功。

2. BOOT引脚配置和硬件接线:DFU启动的第一步

想让STM32进入DFU模式,核心动作是设置BOOT0和BOOT1引脚,让芯片从系统存储器启动。不同型号的引脚定义和启动模式表不完全一样,这里以最常见的STM32F103系列为例:

启动模式选择引脚启动模式说明
BOOT0=0,BOOT1=x主Flash启动正常运行用户程序
BOOT0=1,BOOT1=0系统存储器启动进入Bootloader,DFU/串口烧录
BOOT0=1,BOOT1=1SRAM启动一般调试用,不常用

实际操作时,很多现成开发板已经把BOOT1通过电阻下拉接地,你只需要把BOOT0跳线帽拨到“1”的位置,然后按一下复位键,芯片就会从系统存储器启动。如果你的板子两个BOOT引脚都对外开放,那就用杜邦线把BOOT1接地,BOOT0接3.3V,再复位。

接线部分比想象中严格,因为DFU走的是USB信号,不是普通串口。你得确保用的是USB数据线,不是那种只能充电的电源线——这是新手最容易踩的坑。判断方法很简单:把线插到电脑上,看设备管理器里有没有反应,如果完全没反应,先换根线再试。另一头连接到板子的USB口或芯片的PA11(USB D-)、PA12(USB D+)引脚,注意有些板子MINI USB口和调试口共用,不影响。

上电顺序有个细节:先把BOOT0拉到1,然后再插USB线给板子供电。如果反过来,芯片可能已经用用户程序里的USB配置枚举了设备,DFU模式进不去。正确的操作是:拔掉USB线,设置BOOT0=1,插上USB线,此时芯片直接进入DFU模式。如果是DC供电,那就把USB线插到电脑的瞬间按一下板子的复位键,也能强制进入DFU。

这里有一个很多人不知道的技巧:进入DFU模式后,芯片不会自动退出。烧录任务完成后,必须把BOOT0拨回0并重新上电或复位,程序才会从Flash启动。如果你忘了拨回BOOT0,就会发现明明烧录成功了,但程序没跑起来,这种“烧录成功但运行失败”的现象最容易让人一头雾水。

3. 驱动安装和设备识别:让电脑认出DFU设备的全流程

把BOOT0设置好、USB线接上之后,电脑端的表现通常是:设备管理器里出现一个带有感叹号的未知设备,名字可能叫“STM32 Bootloader”或者“DFU Device”,但Windows无法自动识别它。这是因为STM32的DFU设备没有内置于Windows的驱动程序,需要手动安装。

我第一次折腾时在这里卡了快两个小时,主要原因是驱动版本不对。当时从某个老网站下载了一个2009年的DFU驱动,装上后设备能识别成“STM32 DFU Device”,但烧录工具怎么都连不上,后来换用ST官方工具自带的驱动才解决。如果你是玩STM32CubeProgrammer,安装目录下通常会有驱动文件,路径类似STM32CubeProgrammer/drivers/DFU,里面包含stm32_dfu.inf和对应的驱动文件。

驱动安装步骤建议这样操作:

  1. 打开设备管理器,找到带黄色感叹号的DFU设备。
  2. 右键选择“更新驱动程序”,再选“浏览我的电脑以查找驱动程序”。
  3. 指向STM32CubeProgrammer安装目录下的DFU驱动文件夹。
  4. 如果系统提示“Windows已确定最佳驱动程序”,但设备状态还是不正常,需要手动选择“从磁盘安装”,并指定到inf文件。

装完驱动后,设备管理器里应该能看到一个正常的“STM32 BOOTLOADER”设备,此时DFU模式才算真正被电脑识别。如果驱动装好后拔插USB线又变回感叹号,大概率是USB线数据线质量不好或接触不良,换一个USB口试试,优先用主机背面的USB口,前置USB口供电和数据稳定性都差一些。

另一个容易忽略的问题是Windows的驱动签名策略。Win10/Win11的64位系统会对未签名驱动做拦截,如果安装时提示“系统找不到指定的文件”或“安装失败”,可以临时禁用驱动签名强制策略:设置-系统-恢复-高级启动-立即重新启动,然后在疑难解答-高级选项-启动设置中选择“禁用驱动程序强制签名”。重启后再安装DFU驱动,成功率会高很多。

4. 烧录文件准备:从Keil工程到可烧录固件的完整链路

DFU模式不是直接把你的Keil编译产物扔进去就能烧,得先搞明白几种固件格式的区别。Keil默认编译会生成.axf文件,但这玩意儿只能在调试器里用。通常的烧录文件是.hex或.bin,DFU工具能直接识别这两种格式,只是它们内部组织方式不同。

Keil里需要做一步关键配置:在Options for Target -> Output选项卡里勾选“Create HEX File”,然后重新编译,工程目录下会生成一个.hex文件。如果你拿到的是.bin文件,也可以直接用,DFU工具会把bin文件按偏移地址写入Flash,但前提是你知道程序应该烧到哪个扇区。绝大多数STM32用户程序的Flash起始地址是0x08000000,在DFU工具里填这个地址就行。

如果你的工程是STM32CubeIDE编译的,默认会生成.elf和.bin文件,在Debug或Release目录下能找到。用.hex或.bin烧录都行。

这里要说一个DFU烧录的尴尬问题:DFU模式下,USB设备每次只能接收一个固件文件,且不支持增量写入。所以如果你只想更新一小段代码或某个数据区,不能像ST-LINK那样直接指定地址操作,得把整个程序重新烧一遍。这意味着在开发调试阶段,DFU模式不太适合频繁修改代码的环节,它更偏向于生产烧录、现场升级和产品返修场景。

还有一点需要特别提醒:如果你在Keil里勾选了“Erase Full Chip”或使用了Flash算法擦除整个芯片,而你的程序又跑在中断向量表偏移后的地址,那么烧录前请确认固件的起始地址和linker脚本匹配。用DFU烧录时,工具默认从0x08000000开始擦除写入,如果linker里设置了别的Flash偏移,烧进去后芯片执行时就会跑飞。我遇到过一次:从ST-LINK换成DFU烧录后,程序下载成功但复位后直接进HardFault,最后发现是IAP工程设置了0x08008000的偏移,DFU工具默认写到0x08000000,两个地址错位导致。

所以建议在烧录前用工具打开固件文件确认一下起始地址,或者直接在CubeProgrammer的下载设置里填写正确的Flash起始地址。这个习惯能避免很多莫名其妙的问题。

5. 实操烧录:STM32CubeProgrammer和DfuSeDemo两种方式

现在到了正式烧录环节,我强烈推荐用STM32CubeProgrammer,它已经是ST主推的多功能工具,一个软件就能搞定DFU、SWD、UART烧录和芯片配置,不用再费劲找老掉牙的DfuSeDemo。但考虑到很多老工程师习惯用DfuSeDemo,我先说CubeProgrammer,再简单提一下DfuSeDemo作为备选。

5.1 用STM32CubeProgrammer走DFU流程

驱动装好、BOOT0=1、USB线连接后,打开STM32CubeProgrammer,右上角选择“USB”模式,在下拉列表里选中你的DFU设备(通常显示为“USB1”或“STM32 BOOTLOADER”),点击“Connect”。

连接成功后,界面上会显示芯片型号、序列号和Flash大小等信息。如果显示“Error: No DFU device found”,要先检查设备管理器的驱动状态和USB线。

连接后点击左侧的“Erase chip”按钮,先把整个Flash擦除干净。首次使用的板子可能出厂就有程序,不擦除直接下载有时会写不进。擦除完成后,点击“Download”图标,选择你的.hex或.bin文件,在“File”类型里选对格式,如果选bin文件,还需要把“Start address”改为0x08000000,hex文件则不用管,因为hex里自带了地址信息。点击“Start Programming”,会发现进度条走得很快,因为USB DFU的传输速度虽然不如ST-LINK,但在小固件上几乎是一瞬间的事。

烧录完成后,把BOOT0拨回0并按复位键,程序就能跑起来了。如果你在CubeProgrammer的连接状态下直接点“Disconnect”,芯片仍停在DFU模式,需要断电重上电才能进入用户程序。

5.2 备选方案:DfuSeDemo的用法和适用场景

如果你的电脑上恰好有ST早期提供的DfuSeDemo软件,也能用,但界面风格比较老旧。打开DfuSeDemo后,在“Available USB Devices”里会列出DFU设备。选择“STM32 Bootloader”,然后点“Choose”选择固件文件,点“Upgrade”即可烧录。注意DfuSeDemo只支持官方.dfu格式的文件,普通.hex需要先用配套的DFU File Manager工具转换成.dfu。

DfuSeDemo的适用场景已经越来越少,我平时也不太推荐它,因为它的文件转换流程繁琐,而且对新型号芯片的支持存在滞后。但如果你在维护老项目,工程里还保留着早期DFU工具链,掌握它总比临时抓瞎强。

5.3 命令行方式和脚本化烧录

批量生产场景下,图形界面点来点去效率太低,但CubeProgrammer提供了命令行模式,可以写脚本批量烧录。基本命令格式如下:

STM32_Programmer_CLI.exe -c port=USB1 -e all -d firmware.hex -hardRst

这条命令的作用是:通过USB连接DFU设备,全片擦除,下载firmware.hex,然后硬件复位运行。如果你的电脑只接了一个DFU设备,port可以直接写USB1,如果同时接了好几个,可以用port=USB@设备序列号的方式精确指定。命令行模式还有个好处是可以集成到自动化测试流程里,比如烧录后自动执行某个测试脚本。

6. 常见DFU烧录失败场景与排查链路

虽然DFU模式听起来不复杂,但实际的翻车率比ST-LINK高不少。我整理了几个高频失败场景,并按“从现象到根因”的思路一一对应,方便你排查。

6.1 电脑完全无法识别DFU设备

故障现象:BOOT0设置正确,USB线也接了,但设备管理器没有任何反应,也没有“叮咚”的插入提示音。排查顺序如下:

  1. 换USB线:这是成功率最高的解决办法,很多USB线只有充电能力,没有数据线芯。
  2. 换USB口:优先用电脑后置USB口,避免用USB Hub。
  3. 量USB D+/D-电压:如果手边有万用表,测量USB D+引脚电压,DFU模式下D+应该有1.5V左右的上拉电压,如果没有,可能是上拉电阻没接或损坏。
  4. 确认BOOT0确实为高电平,有些板子的BOOT0跳线帽松动,接触不良。

6.2 DFU设备带感叹号,驱动装不上

故障现象:设备管理器有“STM32 BOOTLOADER”但带黄色感叹号,驱动更新提示“找不到指定的文件”。这种情况在下64位系统上很常见,按之前提到的“禁用驱动强制签名”步骤重启,再安装一次驱动。如果还不行,手动把Device Instance Path里的VID/PID记下来,在inf文件里手动添加对应条目,但这个方法只在极端情况下用,平时很少遇到。

6.3 烧录工具连接不上DFU设备

故障现象:设备管理器里DFU设备正常,但CubeProgrammer点击Connect后报错。排查重点:

  1. 关闭其他占用USB设备的软件,比如串口调试助手可能占用了同一个USB控制器。
  2. 检查CubeProgrammer的驱动设置里是否选择了正确的USB接口设备。
  3. 先把设备管理器里的DFU设备禁用再启用,强制重新枚举。
  4. 如果用了VMware或VirtualBox,把主机的USB过滤设置关掉,否则虚拟机可能会抢占DFU设备。

6.4 烧录中途报错“Write error”

这种错误多发生在Flash扇区擦除失败或写保护开启的情况下。STM32的Flash有读保护RDP和写保护WRP,如果之前烧录过程序并开启了写保护,DFU模式下同样无法覆盖。解决办法是用CubeProgrammer的“Option Bytes”页面,把RDP等级降回Level 0,或者清除WRP保护。但也别一上来就点“Remove protection”,有些操作会触发全片擦除,数据就没了。

6.5 烧录成功但程序不运行

这应该是“看起来成功、实际失败”里最阴间的现象。先从最简单的开始检查:BOOT0是否已经拨回0。如果确定BOOT0=0,再检查固件起始地址是否和链接脚本匹配。还有一个容易被忽略的细节:烧录后必须断电重新上电,而不是只按复位键。因为DFU模式下USB外设的枚举状态可能干扰芯片启动,断开USB电源再重新插入才是干净的上电过程。

如果你用的是带USB枚举的板子,比如正点原子或野火的开发板,上电瞬间程序跑了但USB枚举过程中又被打断,也会出现类似“程序没跑起来”的错觉。这个时候接个串口看打印日志最靠谱。

7. 从DFU到量产和生产维护的额外经验

如果你通读了前面的内容,其实已经不只是在学“怎么用USB烧录”了,而是掌握了一条可以在生产线上直接复用的固件部署思路。这里我再分享几点只有实际操作过才会注意的经验。

7.1 批量烧录时给每块板子预留DFU入口

在设计产品PCB时,如果计划用DFU模式做生产烧录或现场升级,最好把BOOT0引脚引出来,做成一个测试点或拨码开关。量产时测试工装直接短接BOOT0到高电平,复位后就能通过USB批量灌程序。很多量产方案甚至不需要ST-LINK,产线工人只需要一根USB线和一台装了CubeProgrammer的电脑,操作门槛比用ST-LINK加转接板低很多。

7.2 DFU模式和应用内OTA可以共存

有些人一听DFU就以为它只适合开发阶段,其实DFU模式很适合做产品固件升级的兜底方案。当应用内OTA(比如通过WiFi模块或串口升级)中途断电导致固件损坏时,DFU模式还能让设备恢复到一个可靠的烧录状态。这等于给产品上了一道双保险。我的建议是:在产品设计阶段就把两套升级通道都预留好,毕竟DFU Bootloader是出厂自带的,你不用白不用。

7.3 GD32和国产兼容芯片的DFU兼容性

不得不提一下国产芯片的兼容情况,因为很多公司拿STM32的物料成本做不下来,会换成GD32或其他兼容型号。GD32系列基本保留了USB DFU Bootloader的寄存器级兼容性,但驱动枚举时VID/PID可能不同。用CubeProgrammer连接时,如果识别不到,可以在驱动安装时手动指定到GD32的驱动,或者在设备管理器里改成“通用串行总线设备”。我个人试过GD32F303和STM32F103之间的DFU互烧,大部分情况下能够识别,但偶尔会有枚举不稳定的现象,建议先用官方工具确认支持列表。

7.4 一个提升成功率的实用习惯

DFU烧录前先备份原有固件。虽然听起来老生常谈,但很多人就是不做。用CubeProgrammer的Upload功能可以把芯片里现有固件导出来成一个bin文件,再保存好。这个操作只需要几秒钟,但能在烧录失败后快速恢复现场。尤其是现场维护时,上一个工程师烧了什么东西进去你可能并不知道,先备份再烧是基本职业素养。

串口和USB双保险的开发板设计思路也很值得推广:DFU走USB线,同时把串口也引出来,万一DFU枚举不了,还能通过串口Bootloader进去。很多量产板子上同时保留这两种启动模式的切换跳线,就是为了防止某条通道失效时还有Plan B。

8. 写在最后:关于DFU烧录的一点个人体会

从没有ST-LINK的窘境一路折腾下来,我最大的感想是:工具只是手段,理解芯片的启动机制才是解决一切问题的根本。DFU模式之所以能“没有ST-LINK也烧录”,本质上是因为STM32出厂时已经在ROM里放了一个完整的Bootloader,USB线只是把电脑和这个Bootloader之间的数据传输通道打通了而已。所以你会发现,只要把启动模式、USB枚举和驱动下载这几个关键环节理清楚,DFU烧录一点都不神秘,反而比想象的还简单。

最后给一个小技巧:如果你手里同时有ST-LINK和DFU两个方案,调试阶段用ST-LINK,因为支持断点和单步;需要交付或批量修板的时候用DFU,因为不用带额外硬件,一个USB口就能搞定。把这两种模式配合着用,开发效率和交付稳定性都能兼得。

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

用Clang在Windows上交叉编译ARM Linux程序(告别GCC实战)

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 12:33:30

从零打造开源游戏掌机:硬件选型、软件栈与端侧AI部署实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 12:31:35

GaN快充批量失效元凶:X电容放电芯片可靠性剖析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 12:30:42

异常断电导致硬盘逻辑崩溃的原理与抢救指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 12:30:12

电源防倒灌设计:从二极管到理想二极管控制器的工程演进

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 12:28:06

FT232R驱动安装全攻略:Windows/Linux/macOS配置与问题排查

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华