第2章:协商流程拆解——Source/Sink角色、VDM消息、电力协商时序
PD协商,说白了就是供电方和用电方之间的一场“谈判”。
我刚开始接触PD时,觉得USB Type-C只是正反插方便,没想到背后还有这么一套复杂的握手流程。如果你在项目中遇到了协商超时,那八成是对这个流程的某个环节理解不到位。今天我就带你把整个流程拆开,看看每个节点都在做什么。
2.1 Source与Sink:谁说了算?
在PD协议里,角色很清晰。
- Source:供电方。通常是充电器、扩展坞、或者支持PD输出的笔记本。
- Sink:用电方。手机、平板、或者是需要充电的笔记本。
你想想看,一个协议里总得有个主控方吧?PD里,Source就是那个主控方。它负责发出协商邀约,决定要不要给电、给多少电。
我建议你在定位问题时,先确认一下双方的角色。如果Source没检测到Sink,或者Sink没正确回应,那后面所有的协商都是白搭。
关键点:Source通过CC引脚检测Sink的存在,并检测Ra电阻(通常为1kΩ)来确认Sink有PD通信能力。
2.2 VDM消息:协商的“语言”
协商不是瞎聊,得有共同语言。PD协议里,双方通过VDM(Vendor Defined Message)和标准数据消息来沟通。
这里面有一种消息特别重要——Source Capabilities。Source会通过这个消息告诉Sink:“我能提供的电压和电流有这几档,你选吧。”
- Source Capabilities:Source定期广播。包含PDO(Power Data Object),比如5V/3A、9V/3A、15V/3A等。
- Request:Sink回复Source,表明自己选择哪一档。
- Accept:Source同意切换。
- PS_RDY:Source完成电压切换,告诉Sink“可以正常用电了”。
避坑指南:我曾经遇到过一个项目,Sink端总是超时。最后发现,Source发Capabilities时,Sink的协议栈在处理某个自定义VDM时卡住了,没及时回复Request。所以,如果你看到协商卡在某个点上,先检查一下Sink的协议栈是不是在忙于处理其他消息。
2.3 电力协商时序:时间就是生命
PD协议对时序要求非常严格。Source发完Capabilities后,如果Sink没有在规定时间内回复,Source就会认为协商失败,或者重复发送。
| 时序节点 | 描述 | 超时时间 |
|---|---|---|
| tSrcSink | Source等待Sink响应Request消息 | 24ms + 240μs |
| tSinkTx | Sink等待Source回复Accept/Reject | 4.1ms – 5ms |
| tPSTransition | Source切换电压并发出PS_RDY | 12ms – 145ms |
| tSenderResponse | 收到Request后,Source必须在规定时间内回复 | 2ms – 26.8ms |
嗯,这里要注意:很多超时问题都出在tSinkTx这个时间窗口。Sink端如果有大中断处理,或者MCU主频较低,很容易错过这个时间窗口。
// 伪代码示例:Sink端接收Source Capabilities后,发送Request
function handleSourceCapabilities(pdoList):
// 选择最高电压档
selectedPdo = selectBestPdo(pdoList)
if selectedPdo is not None:
sendRequest(selectedPdo)
startTimer(tSinkTx) // 4.1ms ~ 5ms
else:
sendHardReset()
// 等待PS_RDY
警告:不要在这个时序窗口里做功耗计算或者长循环操作。我曾经见过一个团队,在接收到Capabilities后,先计算了电池电量再去发起Request,结果直接超时。正确的做法是:收到Capabilities后立刻复用预设的策略,后续再用异步方式处理电量计算。
2.4 完整协商时序图
我把整个流程画出来了。你看一下,应该能直观理解Source和Sink是怎么一步步握手成功的。
2.5 实际项目中的常见超时点
我复盘过好几个PD超时项目,总结下来,最常见的坑就这几个:
- Sink端没响应Source Capabilities:CC引脚检测失败,或者Sink协议栈没初始化好。
- Request发送太慢:Sink在解析PDO时耗时太多,超过了tSinkTx。
- Source没收到Accept/Reject的超时:常见于线缆质量不好,或者Source端的接收中断被更高优先级任务抢占。
- 电压切换超时:Source端电源芯片响应慢,或者负载电流导致的电压调节滞后。
个人经验:定位问题的时候,我习惯先在Source端抓CC线上的BMC编码信号。用逻辑分析仪看波形,一眼就能看出是哪个消息没回应。比单纯看代码日志快多了。
理解清楚Source/Sink的角色和时序窗口,是定位协商超时问题的基本功。你想想看,如果连谁先说话、什么时候回话都不知道,那排查起来岂不是大海捞针?