# 4. USB电源传输(PD)协议
## 前言
USB PD协议,是一致性测试里的重头戏。说实话,很多工程师一听到PD就头大,什么消息结构、电压协商、PPS、EPR……感觉比USB 3.x的数据传输还复杂。我个人习惯是把PD协议拆成几个核心模块去理解:**消息怎么传**、**电压电流怎么谈**、**精密调节怎么做**、**高压怎么来**、**电怎么双向走**。把这五件事搞明白,PD这块就通了。
## PD消息结构:PD通信的“语言”
### 消息类型与SOP
PD通信不是简单的电平高低,而是基于FSK调制在CC线上传递字节帧。每一帧消息都有严格的格式。
| 消息类型 | 描述 | SOP类型 |
|---------|------|---------|
| 控制消息 | 无Data Object,用于握手、应答 | SOP |
| 数据消息 | 带Data Object,传递具体参数 | SOP、SOP'' |
| 扩展消息 | 更长Payload,用于VDM等 | SOP |
| 硬复位 | 强制终止通信 | 无SOP |
这里有个关键概念——**SOP(Start of Packet)**。PD消息分四种SOP:SOP、SOP'、SOP''、SOP'''。普通通信用SOP,而SOP''用于线缆通信。
> 我在项目中遇到过一个坑:某家线缆的eMarked芯片不响应SOP'',结果Host始终无法识别线缆的电流能力,PD协商直接退化成5V/0.9A。查了三天才发现是eMarked芯片的SOP''地址写错了。
### 消息结构
一个完整的PD消息由以下部分组成:
- **Preamble**(前导码):同步用
- **SOP**:标识消息起始类型
- **Message Header**:消息类型、数据对象数量、规格版本
- **Data Objects**:根据消息类型不同,内容不同
- **CRC**:校验
- **EOP**:结束
我建议你把Message Header的格式背下来,因为调试PD问题的时候,第一件事就是抓CC线上的消息,然后解析Header。
**Message Header(16bit)结构:**
| 位域 | 长度 | 描述 |
|------|------|------|
| Number of Data Objects | 3bit | 数据对象个数,0-7 |
| Message Type | 4bit | 控制/数据消息类型 |
| Port Data Role | 1bit | 0=UFP, 1=DFP |
| Spec Revision | 2bit | 版本号,01b=PD3.0 |
| Port Power Role | 1bit | 0=Sink, 1=Source |
| Reserved | 5bit | 保留 |
嗯,这里要注意:PD3.0和PD2.0的Header格式略有差异,PD3.0增加了Spec Revision。
## 电压/电流协商:Source和Sink怎么“讨价还价”
### 协商流程
PD的电压/电流协商,说白了就是Source和Sink之间的一轮谈判。
**标准协商步骤:**
1. Source广播能力:发送`Source_Capabilities`,列出所有支持的PDO
2. Sink选择最合适的:发送`Request`,指明想要哪个PDO,以及实际电流
3. Source同意:发送`Accept`,准备切换电压
4. 电压建立:Source切换电压,等待稳定后发送`PS_RDY`
5. 供电开始:Sink检测到电压稳定,开始正常功耗
> 避坑指南:我曾经在测试中遇到Sink请求了12V/3A,但Source回复Accept后迟迟不发PS_RDY。后来抓波形发现,Source的电压建立时间超过了规定的时间窗口(典型值是15ms)。很多设计会低估buck电路从5V到12V的转换时间。
### PDO的概念
PDO(Power Data Object)是电源能力描述的基本单元,每个PDO描述一组电压/电流组合。
PD3.0支持两种PDO:
- **Fixed PDO**:固定电压输出,如5V/3A、9V/3A
- **APDO**:可调电压输出,用在PPS中
每个Source至少要有两个PDO:一个是5V的掉保能力,一个是代表支持的其它能力。
## PPS:精密可编程供电
PPS(可编程供电)是PD3.0引入的重要特性。为什么需要PPS?因为手机快充需要精细控制电池充电电压,比如4.4V、4.6V、4.8V……传统固定档位PDO做不到这一点。
### PPS的工作机制
- Source声明一个电压范围(如3.3V-11V)
- 分辨率20mV一档
- 电流分辨率50mA一档
- Sink可以在充电过程中实时调整电压
| 特性 | 标准PD | PPS |
|------|--------|-----|
| 电压步进 | 按PDO档位跳变 | 20mV细粒度 |
| 电流步进 | 按PDO档位跳变 | 50mA细粒度 |
| 协商时机 | 仅连接时 | 充电过程中可随时调整 |
| 适用场景 | 笔记本、显示器 | 手机直充、小功率设备 |
我在项目中做过一个PPS充电器,刚开始发现Sink请求11V,但是实际输出只有10.6V。查了半天发现是Source的电压感知点取在了输出电容之后,而PCB走线阻抗太大,导致200mA的电流就压降了0.4V。**PPS对阻抗匹配非常敏感。**
## EPR:扩展功率范围
### 为什么需要EPR?
传统PD最高只能到20V/5A=100W,但现在的笔记本电脑功耗动不动就130W、240W。PD3.1引入EPR,将电压扩展到48V,功率突破240W。
| 规格 | 电压范围 | 最大电流 | 最大功率 |
|------|---------|---------|---------|
| SPR(标准功率) | 5V-20V | 5A | 100W |
| EPR(扩展功率) | 28V, 36V, 48V | 5A | 240W |
### EPR的特殊要求
EPR不是简单的把电压拉高就完事了,它对硬件有严格的要求:
1. **线缆必须支持EPR**:线缆内要有eMark,标识EPR能力
2. **连接器要耐高压**:传统的USB-C插座可能只耐20V,EPR需要特制连接器
3. **安全机制更严格**:EPR协商过程比SPR长,增加了多重确认
> 我记得有一次,客户送来一款EPR充电器,测试时发现48V输出时线缆发热严重。不是线缆规格不够,而是EPR的触点电阻比SPR大,大电流下温升明显。后来在CC线上增加了主动热调节,才算通过。
## 双向供电:USB-C的全能性
### DR_Swap机制
USB-C的魅力之一就是**谁都能当供电方**。笔记本可以给手机充电,手机也能给耳机充电——这就靠DR_Swap(双角色交换)实现。
### 角色定义
- **Source**:提供电力的设备
- **Sink**:消耗电力的设备
- **DRP**:双角色,动态切换
DRP端口会定期切换Source和Sink角色,直到检测到对方的角色。这个切换周期叫做**DRP周期**,通常在50ms-100ms之间。
### 切换流程
1. 通过`DR_Swap`消息发起角色交换请求
2. 对方回复`Accept`
3. 双方执行电源角色切换
4. 新角色建立,重新开始PD协商
**实战案例:** 测试一款支持反向充电的笔记本,我让笔记本连一个假负载模拟Sink,然后发DR_Swap让笔记本变成Source。结果笔记本在切换过程中电压掉到0V,重启了。原因是笔记本的PD控制器在切换角色时需要重新初始化内部电源路径,而这个过程中供电完全中断了。正确的做法是保持VBUS不断电,切换只在CC层完成。
### 双向供电的测试要点
测试双向供电时,我最关注以下几点:
- **角色切换时间**:通常<100ms
- **供电连续性**:切换过程不能断电
- **兼容性**:和不同品牌的设备交互
## 核心知识框架
下面这张图我画了好几次才满意,它把PD协议的核心流程串起来了:从初始连接,到能力交换,再到协商、PPS、EPR扩展,最后是双向角色切换。你按这个图走一遍,PD的全貌基本就有了。
## 总结
USB PD协议的核心,就是通过CC线上的消息通信,实现灵活的电源管理。不管你从哪个角度看,PD的核心逻辑都一样:**先连接,再交换,然后协商,最后供电**。PPS让供电更精细,EPR让功率更大,DR_Swap让供电更灵活。
搞懂这些,PD一致性测试就有了方向。