开头可以先从一个真实到过很多人手脚的场景说起。
我第一次认真去调一个 USB-C 供电的嵌入式设备时,卡了整整一个下午。问题不在代码,也不在硬件短路,而是“供电协商”像一团黑盒:充电器插上去,设备能亮,但电压和我预期的不一样;有时候启动到一半又掉电重启;万用表只能看到 VBUS 上的最终电压,完全看不到 CC 线上发生了什么。后来借来一套逻辑分析仪,接上 CC 引脚,才第一次看到 USB-C Power Delivery(PD)的协商消息——那一瞬间我意识到,这个领域的调试工具确实太少了。
最近看到有人展示一个开源项目:一台硬件上开源、固件开源、协议解析逻辑也开源的 USB-C PD 分析仪,同时还能作为可编程 sink,主动向电源请求指定电压电流。这个项目最让我在意的不是某个具体功能,而是它把“电源协商”这件事,从只能猜、只能测结果,变成了可以观察、可以控制、可以重复触发。这篇文章我不打算复述项目文档,而是想从“这类工具到底解决什么问题”出发,讲清楚它的原理、用法、工程化路径和边界。
1. USB-C 供电不是“插上就有电”,而是先要谈条件
很多开发者第一次碰到 USB-C 设备供电问题,都会有一个直觉:插上充电器,VBUS 有电压,就能给设备供电。但 USB-C 和传统 MicroUSB 最大的不同,就是多了一条 CC(Configuration Channel)通道。这条通道承担了方向检测、角色定义、模式协商和 PD 电源协商。换句话说,VBUS 上的电压不是插上就固定的,而是 Source 和 Sink 在 CC 线上通过协议“谈”出来的。
1.1 插上充电器之后,CC 线上发生了什么
一次标准 PD 协商,可以简化成下面这样:
- Source 端(充电器)在 CC 线上广播自己的能力,发送 Source_Capabilities 消息,里面包含一组 PDO,比如 5V/3A、9V/3A、15V/3A、20V/5A。
- Sink 端(被供电设备)收到后,评估自己需要哪一档,然后发送 Request 消息,选择某一个 PDO,并附带电流需求,这会生成 RDO。
- Source 收到 Request 后,如果接受,就回 Accept。
- Source 开始调整 VBUS 输出电压,等输出稳定后,发送 PS_RDY,告诉 Sink 可以拉载了。
- Sink 开始正常工作。
如果之后 Sink 想切到另一档电压,它还可以再次发起 Request,重复上面的过程。到了 PD3.0 之后,还有 PPS(Programmable Power Supply)模式,Source 可以在一个连续可调范围内按 20mV 步进调整电压,以适应直接充电等场景。
这个流程看起来不复杂,但实际调试时会发现,问题集中出现在 CC 线上。CC 线上的信号不是普通的 UART,而是 BMC 编码,速率大约在 300kbps 到 600kbps 这个量级。消息之间还有严格时序,一旦某一方向没有回应,整个协商就会卡住。最麻烦的是,这些消息只发生在协商发生的瞬间,普通万用表根本没机会看到。
1.2 普通仪器为什么看不到这段协商
用示波器可以抓到 CC 线上的波形,也能看到 BMC 编码的边沿,但要把这些波形翻译成“Source_Capabilities: 5V/3A, 9V/3A”这样可读的信息,就需要协议解码。高端的示波器可能有 PD 解码选项,但价格并不便宜。逻辑分析仪也能做,但要自己写解码脚本,还要保证采样率和触发时机正确。对于大多数嵌入式开发者和硬件爱好者来说,这个门槛已经很高。
更麻烦的是,PD 协商是双向的、有状态的过程。你很难用一台普通仪器同时观察 Source 和 Sink 两条方向的响应,也很难把“请求了 15V”和“实际输出了 15.02V”放在同一条时间线上。
所以这个开源项目做了一个很聪明的选择:把分析功能做成独立硬件,串接在 Source 和 Sink 之间,除了抓取 CC 线上的消息,还能同时采样 VBUS 电压和电流。这样你看到的不再是孤立的波形,而是一段带时间轴、带因果关系、带电气参数的完整协商记录。
2. 分析仪和可编程 sink,一个负责看,一个负责要
这个开源项目最有意思的地方,是它把两个功能做在了同一个工具里。一个是“分析仪”,被动观察 PD 协商;另一个是“可编程 sink”,主动向电源请求特定电压电流。这两件事分开看都不稀奇,但合在一起,会让调试方式发生质变。
2.1 分析仪:把 CC 线上的协商翻译成人话
分析仪的核心价值,是让开发者不用理解 BMC 编码细节、不用自己写解码器,直接看到 PD 消息。典型的使用方式是,分析仪有两个 USB-C 口,一个接 Source,一个接 Sink,中间是采样和解码电路。数据可以输出到上位机、通过串口打印,也可以直接显示在一块小屏幕上。
实际使用中,最有用的是看“协商失败”的现场。比如设备在请求 20V 时,Source 回了 Reject,那么原因可能不在你的设备,而在 Source 的能力范围。又比如设备一直重复发送 Request,但始终没有收到 Accept,这大概率是 Sink 请求的电压超出了 Source 支持的 PDO 范围。这些问题如果不用分析仪,光靠量电压基本定位不出来。
2.2 可编程 sink:模拟真实设备,主动要电压
可编程 sink 的意思,是让设备本身可以像一台真实受电设备一样,主动和 Source 协商,请求一个指定档位的电压。比如你想验证某个充电头在 9V/3A 下能不能稳定输出,直接用一个固定电阻去拉载是错的,因为充电头不会直接进入 9V 状态,它必须先收到 Sink 的 Request。
有了可编程 sink,你就可以通过串口或上位机设置请求目标,比如“请求 15V/3A”,然后观察电源是否 Accept、是否输出稳定电压。这个能力非常有用,因为很多充电器和适配器内部有精细的电源策略,不是把所有档位都默认开放。你可以通过不断改变请求,摸清一台电源的“脾气”。
需要说明的是,可编程 sink 不等于所谓的“诱骗”。它是一个受控的、用于测试和开发的工具。它的意义在于,让开发者可以安全地模拟不同功率等级的负载组合,来验证电源能力。
2.3 为什么“看”和“要”放在一起更强大
如果只有分析仪,你只能看到现有设备是怎么协商的,但很难主动改变会话过程。如果只有可编程 sink,你会发现协商是成功了,但中间每个消息到底发生了什么,仍然是个黑盒。把两者放在一起,就可以快速做“遍历测试”:先让分析仪抓一次 Source_Capabilities,列出这台电源支持哪些档位,然后用 sink 逐档请求,记录每一档的输出电压、电流和协商结果,几分钟就能得到一份兼容性表格。
这种组合还方便复现问题。比如你怀疑某台充电器在 5V→20V 升压瞬间有跌落,就可以用 sink 设置请求 20V,同时分析仪记录瞬间的 VBUS 曲线。如果问题能稳定复现,就能进一步定位是 Source 的响应时间太长,还是 Sink 的实际负载太重。
3. 从零搭一套开源方案:硬件选型和最小系统
如果你想在这个开源项目基础上自己搭建一套,或者参考它的思路做定制,可以从硬件模块开始拆解。这类项目通常不会是很复杂的电路,但有几个关键模块必须想清楚。
3.1 先分清楚你需要哪几个模块
一个典型的开源 PD 分析仪 + 可编程 sink,硬件上大致包含这几块:
| 模块 | 作用 | 选型考虑 |
|---|---|---|
| PD 协议芯片/MCU | 处理 CC 线通信,维护 PD 协议状态机 | 是否支持 PD3.0/3.1,是否支持 PPS,是否有现成协议栈 |
| USB-C 前端 | 两个 USB-C 接口,用于串接 Source 和 Sink | 是否带 CC 方向检测,是否支持 E-mark 线缆识别 |
| VBUS 采样 | 测量 VBUS 电压和电流 | 采样电阻阻值、ADC 分辨率、最大耐压、功率 |
| 主控 | 汇总协议数据、采样数据,输出日志 | 串口数量、处理速度、是否需要 USB 接口 |
| 输出外设 | 屏幕、按键、旋钮、USB 转串口 | 是否需要独立操作界面,还是接上位机 |
如果只是用来学习和调试,主控和 PD 协议芯片可以用常见的 MCU 开发板代替,不一定要专门做 PCB。开源方案的优点也在这里:硬件原理图、固件、上位机都可以改,你可以先跑通,再决定要不要缩小体积、提高采样率。
3.2 最小可运行流程:先让它看到一次 Source_Capabilities
搭好硬件之后,第一次验证不建议急着做复杂功能。最小目标是:分析仪能解析出一次 Source_Capabilities,并且打印在串口上。
大致流程是:
- 准备一个支持 PD 的电源适配器,比如 65W 的氮化镓充电头。
- 把分析仪的 Source 口接到充电器,Sink 口先空着,或者接一个简单的 PD sink 板。
- 分析仪通过 USB 转串口连接到电脑,打开串口助手,设置正确的波特率。
- 给分析仪上电,插上充电器,观察串口输出。
如果能看到类似下面的信息,说明最小链路已经通了:
[src] Source_Capabilities: 5.0V/3.0A, 9.0V/3.0A, 15.0V/3.0A, 20.0V/5.0A [snk] Request: 15.0V/3.0A [src] Accept [src] PS_RDY [meas] VBUS=15.0V, I=0.02A注意:这只是一个通用输出示例,具体格式由你的固件决定。重点是你能在一条时间线上看到两端的消息,并把 VBUS 测量结果和协商消息关联起来。
3.3 硬件上最容易忽略的三个细节
第一个是 CC 线方向。USB-C 插座内部有两组 CC 引脚,插入方向不同,使用的 CC 引脚也不同。如果分析仪没有处理方向检测,就需要在插入后自动切换 CC 通道,否则要么收不到消息,要么消息只通一半。很多第一版 DIY 板子都栽在这里。
第二个是 VBUS 采样电阻的功率。测大电流时,采样电阻的功耗会迅速上升。比如 0.1Ω 的采样电阻通 5A,功耗是 2.5W,普通贴片电阻直接烧掉。更稳妥的做法是用毫欧级合金采样电阻,或者改用电流检测芯片。
第三个是地线关系。分析仪通常需要和被测的 Source、Sink 共地,否则无法正确采样 VBUS。如果被测对象是隔离电源,或者有高压部分,要注意测试端的安全隔离。这个项目本身是开发调试工具,不是高压计量设备,不要轻易拿它去测超过设计范围的高压节点。
注意:第一次上电不要直接请求最高电压。先用 5V 跑通协商,确认日志、VBUS 采样、CC 方向都正常,再逐步往上加电压和电流。
4. 第一次完整调试:抓一次 USB-C PD 协商
最小链路跑通之后,就要进入真正的调试场景了。这个阶段的核心是:你能不能从一个“看起来正常”的协商里发现问题。
4.1 判断一次协商是否正常:从消息序列开始
一次完整 PD 协商的消息序列,可以用下表来对照:
| 顺序 | 消息方向 | 含义 | 缺失/异常时的含义 |
|---|---|---|---|
| 1 | Source -> Sink | Source_Capabilities | Source 没广播,可能是 CC 线路问题或 Source 不支持 PD |
| 2 | Sink -> Source | Request | Sink 没回应,检查 Sink 协议状态机 |
| 3 | Source -> Sink | Accept | Source 拒绝了请求,可能超出 PDO 范围 |
| 4 | Source -> Sink | PS_RDY | Source 未就绪,可能电源内部输出异常 |
如果你发现协商停在第 2 步,也就是只有 Source_Capabilities 没有 Request,问题几乎一定出在 Sink 侧。有可能是 Sink 的协议栈没有跑起来,也有可能是 Sink 认为所有 PDO 都不满足需求。此时可以先用可编程 sink 替换被测设备,看它能不能发出 Request。如果可编程 sink 能协商成功,说明问题在被测设备的软件逻辑,而不是充电器。
如果你发现 Source 发出 Accept 后迟迟没有 PS_RDY,那问题更多在电源端的输出调理。比如充电器在切换电压时过流保护触发,或者输出电容充电太慢。此时用分析仪叠加 VBUS 采样,能直接看到电压爬升曲线,比单独看消息更直观。
4.2 用可编程 sink 做一次电压请求测试
手动测试时,我一般会按这种顺序操作:
- 先把 sink 设为空载,也就是请求一个电压,但不接额外负载。
- 用分析仪看协商结果,确认 VBUS 电压稳定到目标值。
- 再给 sink 接入电子负载,按照需求缓慢增加电流。
- 观察实际输出电压是否跌落、是否有保护触发。
可编程 sink 的配置方式因项目而异,但通常会有类似这样的命令入口:
# 常见命令行工具的配置方式(示例结构,具体以你的工具为准) pd-sink set-volt 20.0 pd-sink set-curr 3.0 pd-sink start pd-sink status不要一上来就设成最大电流。先空载确认协商,再逐步加压加流,可以避免把仪器和电源都推到保护状态。
4.3 关键参数:电压范围、电流范围、PPS 支持
选择 PDO 时,要区分普通 PDO 和 APDO。普通 PDO 是固定档位,比如 5V、9V、15V、20V;APDO 是 PPS 可编程档位,支持更细粒度的电压调整,比如 3.3V 到 21V 之间按 20mV 步进调节。如果你要测试的是手机快充或者新款充电器,可编程 sink 必须支持 APDO 请求,否则很多充电头不会进入 PPS 模式。
另一个容易被忽略的点是电流能力。PDO 广播里会写“5V/3A”,但这只是 Source 能提供的上限。你请求的电流也必须在该档位允许范围内。很多 DIY sink 只实现了电压请求,没有实现电流字段,结果 Source 会认为你在请求一个非常低的电流,这往往不是我们想测的场景。
5. 从“跑通一次”到“可重复测试”:日志、脚本和自动化
很多开源硬件项目停留在“能跑通示例”的阶段,但真正要把它用起来,必须把它工程化。PD 分析仪和可编程 sink 尤其如此,因为它的核心价值不是一次抓包,而是可重复的协议测试。
5.1 手工测试只能说明“能通”,不能说明“稳定”
你手动点一次“请求 20V”,充电器输出 20V 成功,这只能说明这一台充电器、这一根线、这一个固件版本在这个环境里能通。如果换一台充电器呢?换一根 5A 线缆呢?温度变化一下呢?都可能产生不同的行为。
手工测试可以发现问题,但无法量化问题的出现频率。比如某台充电器在“5V→20V”切换时,偶尔会晚 10ms 才发 PS_RDY。这种不稳定只有反复测试才看得见,而手工测试很难积累足够的样本。
5.2 一个可复用的自动化测试框架
我建议把 PD 测试分成四个阶段,写成一个脚本流程:
- 枚举:分析仪抓取 Source_Capabilities,解析出所有 PDO 和 APDO 档位。
- 逐档请求:对每一个档位,让 sink 发起 Request,等待 Accept 和 PS_RDY。
- 加负载验证:对每个档位设定一个目标电流,接电子负载从 0 开始缓慢增加到目标值,记录电压跌落。
- 输出报告:把每档的协商时间、输出电压、电流、是否成功、异常消息写入 CSV,便于对比。
如果自己写脚本,建议把“等待响应超时”也作为一种结果记录。很多时候电源并不是直接拒绝,而是根本不回消息,这本身就是一条很有用的信息。
提示:自动化测试不是减少人工确认,而是把重复劳动变成脚本。真正判断某台电源是否合格,仍然需要工程师结合功率需求和硬件设计来处理。
5.3 排查链路:当测试结果不稳定时,按什么顺序查
自动化测试跑起来之后,一定会遇到结果不稳定。这时候不要直接改脚本,而是按下面的链路逐层检查:
- 先看物理层:线缆是否支持 PD、是否带 E-mark、触点是否氧化、USB-C 座子是否虚焊。
- 再看 CC 电平:用示波器或万用表检查 CC1/CC2 上是否有正确的 Rp/Rd 电平。Source 端会有上拉,Sink 端会有下拉。
- 再看协议层:用分析仪抓包,确认 Source_Capabilities 是否每次都一样。有时电源会进入保护后重启,导致广播内容变化。
- 再看电源层:VBUS 电压是否稳定,电流是否触发限流,纹波是否过大。
- 最后看工具本身:分析仪固件版本、采样率、串口 buffer 是否溢出,有没有丢消息。
这里的顺序不是随意排的。物理层和 CC 电平问题最容易造成“时好时坏”,协议层问题可以靠抓包定位,电源层问题才是最后应该怀疑的对象。先看工具,往往会把问题引向错误方向。
6. 哪些场景建议用它,哪些场景千万别凑合
写到最后一部分,必须把适用边界说清楚。开源 USB-C PD 分析仪和可编程 sink 是一个很好的开发工具,但它不是万能的。
6.1 适合:开发调试、兼容性测试、教学
如果你在做嵌入式设备,尤其是带充电管理、电池充电、Type-C 接口的产品,这类工具会非常有用。它可以帮你确认协议有没有走通,也可以帮你复现“设备充电偶发失败”的问题。
它也适合做电源适配器的兼容性测试。给一个可编程 sink 配上自动遍历脚本,很快就能得出某款充电头支持的档位表、每档的实际电压误差。这个信息对硬件选型很有价值。
教学场景同样合适。PD 协议对很多学生来说很抽象,有了分析仪,就能把“Source_Capabilities→Request→Accept→PS_RDY”变成屏幕上真实可见的事件序列,比看文档容易理解得多。
6.2 不适合:精密计量、合规认证、大功率安全测试
如果你的目标是做严苛的电源质量检测,比如确认输出电压精度、纹波、转换效率,那么开源分析仪自带的采样电路不一定能满足精度要求。它更适合做“看趋势、看时序、看协议状态”,而不是替代高精度数字万用表或功率分析仪。
如果要做 PD 认证相关的预测试,也要谨慎。合规认证对协议实现的一致性、时序容限、异常处理都有严格标准,开源固件通常没有经过权威机构验证,测试结果只能作为参考。真正的认证仍然需要专业设备或认证实验室。
还有一类场景不建议轻易尝试:大功率安全测试。如果你要测量几百瓦的电源,或者做故障注入测试,建议使用有隔离、有保护、有认证的专业设备。开源硬件如果设计余量不足,一旦发生电压过冲或短路,可能损坏被测设备,甚至带来安全风险。
注意:涉及高电压或大电流的测试,优先使用专业设备和隔离措施。不要让开发工具承担超出设计范围的工作。
6.3 工具思维的边界:开源是入口,不是终点
如果把这类开源项目只停留在“刷固件、看日志”的层面,就太可惜了。它真正的价值在于,给了你一个可以修改的底层入口。你可以改成自己需要的电压请求策略,可以加自动重试,可以接进现有的自动化测试平台,也可以把数据转发给上位机做进一步分析。
但这种改造能力是有代价的。你需要去读 PD 协议规范,需要理解 source/sink 状态机,需要会看硬件原理图。开源不保证你能直接用,它只是把可能性打开。
所以我对这类项目的态度一直是:先把它当作一个学习工具,跑通一次完整协商,理解每条消息的含义;然后把它当作一个开发助手,结合自己的项目需求加功能;等到你对它的机制足够熟悉,再去考虑让它成为生产环境里的一部分。那种“下载完固件就会解决所有问题”的期待,无论对开源硬件还是商业工具,都是不现实的。
回到最开始那个下午。如果当时有一套开源 PD 分析仪和可编程 sink,我不会靠猜测去换充电器、换线、改代码,而是会在几分钟内看到协商停在哪一步,直接指向问题所在。这种“把黑盒打开”的能力,才是这个项目最值得长期关注的原因。