这是一个极简主义的硬件调试工具项目。它利用标准的 UART 串口通信协议,通过巧妙的硬件电路设计(RC 充放电网络),实现了 单根 TX 线同时传输 SWD 时钟与数据,并利用 RX 线读取目标芯片回传的数据。 该项目无需专业的 J-Link 或 ST-Link 调试芯片,仅需几个电阻、电容、三极管和二极管即可自制简易 SWD 下载器,配合浏览器端的 Web Serial API 实现 AXF/HEX/BIN 文件的解析与烧录。
- 极简硬件:仅需电阻、电容、二极管、三极管即可搭建硬件电路。
- 单线复用:创新性地在单根 TX 线上同时生成 SWC(时钟)和 SWD(数据)信号。
- Web 端工具:基于 HTML/JavaScript 实现,无需安装驱动或软件,浏览器直接运行。
- 文件解析:支持 AXF、FLM、HEX、BIN 等常见嵌入式固件格式。
- 高波特率支持:最高可支持 921600bps 及以上的通信速率。
这是一个非常巧妙的设计,利用UART串口通信协议的时序特性,配合RC电路的充放电时间常数,实现了单线(TX)同时产生SWD协议所需的时钟(SWC)和数据(SWD),并能通过RX回读数据。
该设计的核心在于利用UART的“帧结构”来模拟PWM信号,从而在一条TX线上实现时钟与数据的复用。
- 时钟(SWC)的生成:
- UART通信的起始位是一个下降沿。
- 对于SWD协议,SWC(时钟线)需要跳变沿来触发采样。
- 原理:每当UART发送一个字节(如发送
0xFF或0xF0),TX线会产生一个下降沿(起始位),这个下降沿(或随后的上升沿)被直接或通过电容耦合到SWC引脚,作为SWD协议的时钟触发信号。因此,每发送一个字节,就产生一个时钟周期。
- 数据(SWD)的生成(利用RC充电延迟):
- SWD的数据线(SWD)连接在TX线后端的RC电路上。电容两端的电压不能突变,需要时间充电。
- 发送
0xFF(逻辑1):- UART波形:起始位(0) + 8位数据位全1 + 停止位(1)。
- 实际上只有起始位是低电平(1个bit时间),随后立即变高。
- RC效应:TX拉低的时间极短(仅起始位宽度)。根据RC充放电曲线,电容虽然放电,但时间太短,电压尚未降到逻辑低电平阈值(逻辑0),TX就变高开始充电恢复了。
- 结果:SWD引脚上的电压始终维持在逻辑高电平。TX发
0xFF-> SWD读到1。
- 发送
0xF0(逻辑0):- UART波形:起始位(0) + 数据位
00001111。注意UART是LSB优先,实际发送顺序是低位在前。 - 实际上,起始位(0)加上数据位的低4位(0000),TX线会保持至少5个bit时间的低电平。
- RC效应:TX拉低的时间足够长,电容有充足时间放电,电压迅速跌落至逻辑低电平阈值以下。
- 结果:SWD引脚被拉低到逻辑0。TX发
0xF0-> SWD读到0。
- UART波形:起始位(0) + 数据位
- 盲写入优势:
- 这种方式被称为“盲写入”,因为不需要读取芯片返回的数据,只管按节奏发送。由于SWD协议是全双工的(主机在时钟上升沿输出数据,从机同时输入数据),这种时序完全匹配。
- 极速通信:在只写模式下,RC时间常数要求降低。如文中提到,仅需末端10K电阻配合500pF电容,即可支持高达 512000 bps(甚至更高)的波特率,因为此时主要关注的是放电是否充分(生成0),而充电恢复很快。
读取数据利用了SWD接口的开漏输出特性和RX线路上的充电延迟。
- 电路状态:
- 当需要读取数据时,主机通过TX发送
0xFF(全是1,即高电平输出)。 - 此时SWD总线处于“读取相位”。
- 当需要读取数据时,主机通过TX发送
- SWD芯片输出
1(高阻态/弱高):- 芯片内部MOS管截止,芯片不对线路放电。
- 现象:TX发送
0xFF(起始位后迅速拉高),线路通过上拉电阻快速充电。 - RX接收:RX引脚上的电压迅速跟随TX上升,RX接收到的数据与TX发送的一致(收到
0xFF)。 - 判定:TX == RX -> 读到 1。
- SWD芯片输出
0(强下拉):- 芯片内部MOS管导通,将SWD线路强行拉低到地(Sink电流)。
- 现象:TX虽然试图输出高电平(停止位),但由于芯片在“吸电”,SWD线路上的电容充电过程被拖慢,电压上升斜率变平缓。
- RX接收:由于电压上升缓慢,在UART采样点时刻,RX引脚仍处于低电平。UART会将其解析为数据位
0。因此,RX会收到类似0x00或0xF0等含有多个0的数据帧(取决于具体的波特率和电容延迟),即“前面一堆0”。 - 判定:TX != RX (RX收到异常数据) -> 读到 0。
- SS14 二极管的作用:
- 快速放电:当TX输出低电平(起始位或数据0)时,SS14(肖特基二极管)导通,为电容提供了一条低阻抗的放电通路。这大大缩短了电容放电时间,确保了在生成数据
0时能迅速将SWD拉低,同时也为下一次通信做好了准备。 - 单向导通保护:在读取模式下,当TX变高时,二极管截止,防止TX的高电平干扰SWD芯片的下拉动作(读取逻辑),保证RX能准确检测到线路被拉低的状态。
- 快速放电:当TX输出低电平(起始位或数据0)时,SS14(肖特基二极管)导通,为电容提供了一条低阻抗的放电通路。这大大缩短了电容放电时间,确保了在生成数据
这套方案的精妙之处在于**“用时间换逻辑”**:
- 写逻辑:利用**脉宽(低电平持续时间)**控制RC放电深度,从而区分逻辑0和1。
- 读逻辑:利用**充电速度(上升沿斜率)**差异,通过RX检测电压是否被目标芯片“拖住”来判断数据。
- 元件角色:
- RC网络:构建了一个模拟滤波器,将数字脉宽信号“积分”为电平信号(写),并将电平阻抗信号“微分”为时序差异信号(读)。
- SS14:加速放电,提高通信速率上限。 这种设计仅需极简的硬件成本,即可通过标准串口实现复杂的SWD调试功能,非常适合低成本、便携式的嵌入式开发工具。
根据原理图,硬件连接示意如下:
UART 接口 目标芯片 (MCU)
+--------------+ +------------------+
| | | |
| TX ------------------------+-- SWC (Clock) |
| | | | |
| | +---[ RC ]----+-- SWD (Data) |
| | | | |
| RX -----+----+ | |
| | | |
| GND -------------------------- GND |
| | | |
+--------------+ +------------------+
RC 组件建议:
- 写入模式优化:末端 10K 电阻 + 500pF 电容 (可达 512000bps)
- 通用调试:根据波特率调整电容值 (参考下图对应关系)
| 电容值 | 建议波特率 |
|---|---|
| 500 pF | 512,000 bps |
| 1000 pF | 230,400 bps |
| 0.1 µF (100nF) | 2,400 bps |
本项目提供了一个纯前端的 HTML 页面,集成了文件解析、串口通信和烧录逻辑。
- 文件解析 (
Elfparse,hex2bin):- 解析
.axf/.elf文件,提取.text/.data段。 - 解析
.hex文件并转换为 BIN 格式。 - 解析
.flm算法文件,用于自定义 Flash 编程算法。
- 解析
- 串口通信 (
COMHelper):- 基于 Web Serial API 封装。
- 支持十六进制发送与接收。
- 支持自定义波特率配置。
- 下载算法 (
downloadbin):- 内置 PY32F002A 等芯片的下载支持。
- 支持加载外部 FLM 文件扩展支持更多芯片。
- 打开工具:使用支持 Web Serial API 的浏览器(如 Chrome/Edge)打开
index.html。 - 连接硬件:将自制电路连接到电脑串口与目标板。
- 选择串口:点击“打开串口”,选择波特率(建议根据电容选择,或尝试 921600)。
- 选择算法:在下拉框中选择对应的芯片型号(如 PY32F002A)。
- 加载固件:拖入或粘贴
.axf、.hex或.bin文件。 - 开始下载:文件加载完成后,程序将自动开始下载流程。
本项目代码开源,您可以根据需要修改代码以支持更多芯片或优化通信逻辑:
- 增加芯片支持:修改
download_device对象,添加新的下载函数。 - 优化时序:在
wInt/rBus等底层函数中调整延时,适应不同的硬件环境。 - 自定义算法:解析
.flm文件中的FlashDevice结构体,实现通用算法加载。
- 此方案为软件模拟时序,受操作系统调度和 JS 执行效率影响,稳定性不如专用硬件(如 ST-Link)。
- 读取模式对波特率较为敏感,若读取失败请尝试降低波特率或调整电容值。
- 仅支持 SWD 协议,不支持 JTAG 协议。

