CH347/339W是一款国产多功能接口芯片,它集成了SPI、I2C、JTAG、SWD、UART和GPIO等多种接口功能。这个开源项目旨在充分发挥该芯片的潜力,为嵌入式开发者提供一套完整的硬件调试和程序下载解决方案。在前三篇文章中,我们已经介绍了该芯片的基本功能、温湿度监测应用以及Xilinx FPGA的下载调试功能。本文将重点讲解如何利用CH347的USB转SWD/JTAG功能,结合OpenOCD工具实现常见MCU(如STM32系列)的程序下载。
对于嵌入式开发者来说,一个可靠、高效的调试和下载工具至关重要。传统方案往往需要购买昂贵的专用调试器,而CH347提供了一种高性价比的替代方案。它不仅能实现基本的程序下载功能,还能通过开源工具链进行深度定制,满足不同开发场景的需求。
要完成本项目的搭建,你需要准备以下硬件设备:
CH347与目标MCU的连接方式取决于你使用的调试接口类型(SWD或JTAG)。以下是两种常见连接方式:
code复制CH347 STM32
SWDIO --> SWDIO
SWCLK --> SWCLK
GND --> GND
3.3V --> VCC (可选,可为目标板供电)
code复制CH347 STM32
TMS --> JTMS
TCK --> JTCK
TDI --> JTDI
TDO --> JTDO
GND --> GND
3.3V --> VCC (可选)
重要提示:由于CH347的引脚复用特性,SWD/JTAG功能不能与FPGA调试功能同时使用。在实际操作前,请确保硬件跳线或软件配置正确。
首先需要安装CH347的USB驱动程序:
验证驱动是否正常工作:
bash复制# Linux系统下可以使用lsusb命令检查
lsusb | grep "1a86:55db"
# 应该能看到类似输出:Bus 001 Device 003: ID 1a86:55db QinHeng Electronics CH347
OpenOCD是开源的片上调试工具,我们需要对其进行定制以支持CH347:
bash复制sudo apt install openocd
# 或者从源码编译最新版
git clone git://git.code.sf.net/p/openocd/code openocd
cd openocd
./bootstrap
./configure --enable-ch347
make
sudo make install
创建CH347专用的OpenOCD配置文件(ch347.cfg):
tcl复制# CH347接口配置
interface ch347
ch347_vid_pid 0x1a86 0x55db
ch347_jtag_clock 1000
# 目标MCU配置(以STM32F1x为例)
source [find target/stm32f1x.cfg]
# 调试选项
reset_config srst_only
adapter speed 1000
项目提供的图形化界面主要包含以下几个功能区域:
硬件连接检查
软件配置步骤
文件选择注意事项
执行烧录操作
实测技巧:如果遇到连接失败,尝试以下步骤:
- 降低通信速率
- 检查硬件连接,特别是GND线
- 重启OpenOCD服务
- 确认目标MCU没有处于低功耗模式
默认配置下,CH347的SWD/JTAG接口工作在相对保守的速率。通过以下方法可以优化传输速度:
tcl复制# 在ch347.cfg中增加
adapter speed 4000 # 单位kHz,根据实际情况调整
tcl复制program filename.bin fast verify
tcl复制program filename.bin verify off
如果项目中使用的MCU不在默认支持列表中,可以通过以下步骤添加支持:
示例(为STM32L4系列添加支持):
tcl复制# stm32l4x.cfg
source [find target/stm32l4x.cfg]
# 覆盖默认配置
set WORKAREASIZE 0x4000
set FLASH_SIZE 0x100000
我们对CH347在不同模式下的编程速度进行了测试(以STM32F103C8T6为测试目标,编程128KB数据):
| 模式 | 速率(kHz) | 擦除时间(s) | 编程时间(s) | 总时间(s) |
|---|---|---|---|---|
| SWD | 1000 | 1.2 | 4.8 | 6.0 |
| SWD | 4000 | 1.2 | 2.1 | 3.3 |
| JTAG | 1000 | 1.2 | 5.2 | 6.4 |
| JTAG | 4000 | 1.2 | 2.3 | 3.5 |
从测试数据可以看出:
我们将CH347方案与常见的ST-Link和J-Link进行了对比:
| 特性 | CH347+OpenOCD | ST-Link V2 | J-Link EDU |
|---|---|---|---|
| 最大速率 | 4MHz | 4MHz | 15MHz |
| 多接口支持 | 是(SWD/JTAG) | 仅SWD | 是 |
| 跨平台支持 | 优秀 | 一般 | 优秀 |
| 价格 | ¥50-80 | ¥100-150 | ¥1000+ |
| 开源支持 | 完全开源 | 部分开源 | 闭源 |
CH347方案的优势在于高性价比和多功能性,特别适合预算有限或需要灵活接口的开发者。而专业调试器在稳定性和极限性能上仍有优势。
在小型批量生产中,可以使用CH347配合自动化脚本实现无人值守编程:
python复制import subprocess
import time
def program_device(hex_file):
cmd = f"openocd -f ch347.cfg -c 'program {hex_file} verify reset exit'"
try:
subprocess.run(cmd, shell=True, check=True)
return True
except subprocess.CalledProcessError:
return False
# 主循环
while True:
if new_file_available():
hex_file = get_latest_hex()
if program_device(hex_file):
move_to_done_folder(hex_file)
CH347非常适合用于嵌入式教学实验平台:
实验设计思路:
教学优势:
典型实验流程:
mermaid复制graph TD
A[编写实验代码] --> B[编译生成HEX文件]
B --> C[通过CH347烧录]
C --> D[观察实验现象]
D --> E[调试修改代码]
E --> A
通过USB Hub连接多个CH347适配器,可以实现多设备并行调试:
硬件配置:
OpenOCD配置示例:
tcl复制# 设备1配置
interface ch347
ch347_vid_pid 0x1a86 0x55db
ch347_serial "A1001"
source [find target/stm32f1x.cfg]
# 设备2配置
interface ch347
ch347_vid_pid 0x1a86 0x55db
ch347_serial "B2002"
source [find target/stm32f4x.cfg]
bash复制openocd -f device1.cfg -c "telnet_port 4444" &
openocd -f device2.cfg -c "telnet_port 4445" &
通过OpenOCD的TCL脚本扩展,可以添加自定义调试命令:
tcl复制proc read_reg {reg} {
set value [mrw $reg]
echo [format "Register 0x%08x: 0x%08x" $reg $value]
return $value
}
proc write_reg {reg value} {
mww $reg $value
echo [format "Write 0x%08x to 0x%08x" $value $reg]
}
tcl复制source [find custom_commands.tcl]
bash复制telnet localhost 4444
> read_reg 0x40021000
Register 0x40021000: 0x00000000
> write_reg 0x40021000 0x00000001
Write 0x00000001 to 0x40021000
通过扩展界面功能,可以添加实时性能监控:
添加传输速率显示:
添加时序分析功能:
优化建议生成:
本项目所有资源均开源提供:
最新版本获取方式:
bash复制git clone https://github.com/your-repo/ch347-openocd.git
cd ch347-openocd
git submodule update --init
欢迎开发者参与项目改进:
代码贡献流程:
文档改进建议:
测试反馈渠道:
项目维护了常见问题知识库,涵盖:
知识库访问方式:
code复制/docs/FAQ.md
短期计划(v1.1):
中期计划(v2.0):
长期愿景:
基于用户反馈,下一代硬件可能改进:
软件方面的持续优化包括:
在实际使用CH347进行MCU开发的过程中,我发现合理配置OpenOCD参数对稳定性影响很大。特别是在高速传输时,适当增加延时参数往往能解决看似复杂的连接问题。另一个实用技巧是在批处理脚本中添加自动重试逻辑,可以显著提高生产环境下的编程成功率。