一根标称 240 W 的 USB-C 线,传文件仍可能只有 USB 2.0 速度;笔记本能从扩展坞充电,也不保证该端口支持显示输出。连接器、数据传输、视频和供电是相互关联但分别声明的能力。本篇先拆开这些概念,再沿设备枚举与电源协商解释“插上以后发生什么”。
数据 480M / 5G / 10G / 20G / 40G / 80G 供电 方向、协商电压、电流与线缆额定 视频 DP Alt Mode 或 USB4 视频隧道 角色 数据 Host/Device 与电源 Source/Sink 同一个 USB-C 外形,四种能力必须分别确认 端口、线缆、扩展坞和设备形成一条链;任一段階缺少目标模式,都可能降低可用能力。
想确认的能力 查阅入口 必须一起核对
文件能传多快 数据模式与有效吞吐 主机、线缆、Hub、设备及共享上行
为什么系统不识别 枚举与端点 数据线、电源稳定、描述符、配置、驱动
USB-C 正反插如何工作 引脚分组与 CC 方向检测、布线与高速复用
能否充到目标功率 PD 合同 Source、Sink、线缆、电源路径与温度
能否带显示器 DP Alt Mode 与 USB4 lane 数、速率、色深、压缩与设备支持
连接器名称不能代替数据模式
Type-A、Type-B、Micro-B、Type-C 是连接器类型,不是速率。传统 USB 2.0 Type-A 有 VBUS、D−、D+、GND 四个触点;SuperSpeed Type-A 增加五个触点,其中四个组成两对高速差分信号,另一个为参考触点。增加的是五个触点,绝不是五对差分线。
USB-C 插座的完整定义有 24 个触点,但只实现 USB 2.0 的产品可不连接高速数据通道;某些简化连接器也不提供全部触点。不能因为插座外形相同,就推断实现了完整数据或视频功能。
常见数据能力 对应模式示例 理解边界
1.5 / 12 / 480 Mbit/s USB 低速 / 全速 / 高速 USB 2.0 设备不必支持 480 Mbit/s
5 Gbit/s USB 3.0、USB 3.1 Gen 1、USB 3.2 Gen 1×1 不同规范中的同级速率名称
10 Gbit/s USB 3.1 Gen 2、USB 3.2 Gen 2×1 USB 3.2 另有双通道组合,不只看 Gen 数字
20 Gbit/s USB 3.2 Gen 2×2 或 USB4 20Gbps 相同标称速率不代表相同链路模式
40 / 80 Gbit/s 对应 USB4 能力 端口和线缆需支持相应模式
USB-IF 的用户侧命名以 USB 5/10/20/40/80Gbps 表达性能。USB4 Version 2.0 已扩展到 80 Gbit/s 级别,因此把 USB4 一律写成最高 40 Gbit/s 已不完整;版本名称仍不等于每个产品都实现所有可选能力。USB-IF:数据性能命名 、USB4 概览
这些是链路速率,不能直接当作文件速度。以 5 Gbit/s、8b/10b 编码为例,仅编码后就只剩 5×8/10=4 Gbit/s,即 500 MB/s;包头、流控、重试、USB 存储协议、主控和介质还会继续消耗预算。不要把它当作实测磁盘一定能达到的吞吐,也不要把双向速率简单相加后宣传为单向速度。
一个 USB4 端口连接 USB 3.2 Gen 2×2 设备时,仍要看是否共同支持 Gen 2×2;“主机数字更大”不保证所有较低数字的链路组合都能运行。Hub 的多个下行口也共享上行带宽,不会每增加一个接口就凭空增加主机通道。
USB 2.0 与 SuperSpeed 的线路并不相同
USB 2.0 使用 D+/D− 进行半双工传输。低速和全速的上拉位置用于连接/速度识别;高速设备通过复位阶段的握手进入高速模式,不能仅看 D+ 上拉就区分全速与高速。高速信号电气条件与低/全速不同,不能统一写成“USB 2.0 差分 3.3 V”。
SuperSpeed 使用独立发送与接收差分通道,并有链路训练、电源状态与流控。USB-C 的高速对还需按插入方向和使用模式复用。USB4 则进一步通过路由与隧道组织支持的协议流;它不是把 USB 2.0 D+/D− 直接加速,也不能把所有 USB 世代的连接检测都画成 D+ 上拉。
传统 USB 总线以主机/根 Hub 为根形成分层树,Hub 扩展下游连接。主机控制传输调度,设备通过端点提供功能;这不等于设备永远不能发送任何链路通知或请求唤醒,而是普通功能数据不能像任意对等网络那样自行抢占总线。
枚举:从有电到驱动可用,中间有多个状态
以普通 USB 2.0 外设说明:设备连接后,主机进行端口复位,使用默认地址 0 的控制端点读取初始信息、分配地址,再获取完整描述符和选择配置。不同系统的读取顺序可有差别,但默认控制端点、地址和配置是不同阶段。
连接与复位 检测连接;高速能力在复位握手阶段协商 默认地址 0 读取所需初始描述信息;端点 0 已可用于控制传输 分配设备地址 SET_ADDRESS 完成后,按新地址继续通信 读取完整描述符 设备、配置、接口、端点与必要的类描述符 选择配置与驱动绑定 SET_CONFIGURATION;类/厂商驱动准备相应接口 USB 2.0 设备建立数据通路:端点 0 先承担控制请求 这是教学主线;主机实现可重复读取或调整请求顺序,不能把“已分配地址”等同于业务可用。
对象 描述什么 常见误解
Device VID/PID、版本、配置数等 VID/PID 不是唯一的驱动匹配规则
Configuration 接口集合与相应属性 读到描述符不等于已选中该配置
Interface / Alternate setting 一项功能及其端点组合 一个物理设备可以有多个接口与驱动
Endpoint 方向、传输类型、包长等 端点不是连接器上的独立电线
IN/OUT 始终以主机视角命名:IN 是设备到主机,OUT 是主机到设备。端点 0 承担默认控制传输;其他端点由配置和接口描述符声明。一个复合设备可以同时有键盘接口和厂商数据接口,并分别绑定驱动,不应把“加载一个设备驱动”当作所有设备的固定模型。Microsoft:USB 端点与管道
四种传输类型承诺的并非同一种“可靠”
类型 主要用途与调度特征 不能保证什么
Control 枚举、配置、控制请求,有错误处理 请求内容一定被业务接受
Bulk 尽力利用可用带宽,适用数据完整性优先场景 固定吞吐或最坏延迟
Interrupt 周期服务机会,适合小量及时数据 外设用硬中断直接抢占主机总线
Isochronous 为实时流保留服务机会,错过的数据不按普通事务重试追回 每个数据单元都必达
端点调度约束与应用收到数据的时间仍隔着控制器、驱动、缓冲和系统调度。音视频可以接受少量丢失来维持时间连续性;文件传输通常选择完整性优先。USB 传输成功也不等于应用已把数据持久化,设备内部缓存和命令完成语义需另行确认。Linux:USB 主机 API 与传输模型
常见类包括 HID、Mass Storage、CDC ACM/NCM、Audio、Video、DFU。所谓“免驱”通常是操作系统已有兼容类驱动;版本、描述符、设备子类和厂商扩展仍会影响支持。CDC 是一组通信类定义,不能把 CDC 全部标成需驱动、再把其中 ACM 标成不需驱动;实际一直有驱动,只是是否需要用户额外安装不同。
Type-C 引脚按功能分组
引脚组 作用 实现注意点
VBUS / GND 供电与回流 多触点分流、电流能力及电源路径控制
D+ / D− USB 2.0 数据 插座两面的对应同名触点按参考设计连接
四对高速信号 USB 3.x、USB4 或模式复用 方向检测、差分阻抗和合适的 MUX/retimer
CC1 / CC2 连接、方向、电流通告、PD 相关通信 两个 CC 不可直接短接
SBU1 / SBU2 模式相关边带信号 例如 DP Alt Mode 的 AUX,不是通用第二组 USB 数据
这里按信号功能解释,不提供可能混淆正面/背面的焊盘坐标;画 PCB 必须按所选连接器的数据手册、观察方向和封装脚号核对。
CC 检测的是连接与电源角色,角色可继续协商
常见 Source 提供 Rp,Sink 提供 Rd;插入后由有效 CC 路径检测连接和方向。简单固定 Sink 插座在 CC1、CC2 上分别设置独立 Rd,常用标称 5.1 kΩ;两个引脚不能合用一个电阻短接,也不能只装一侧导致某个方向异常。需要完整角色、电流检测或 PD 时应使用适当控制器与电源路径设计。TI:Type-C 工程指南
Type-C 电流通告包括 USB Default、1.5 A、3 A 等 5 V 能力。USB Default 要结合相应 USB/充电规则判断,不能一律当成“插上就可取 500 mA”,更不能因为看到两个 Rd 就默认可以取 3 A。Sink 需按实际通告和协议限制取电。
数据角色 Host/Device 与电源角色 Source/Sink 应分开。例如笔记本可以作为数据主机管理扩展坞,同时作为 Sink 从坞站充电;支持 PD 的设备可按能力进行角色交换。未用于当前 CC 通信的相应触点还可能承担 VCONN,为线缆电子器件供电,VCONN 与大功率 VBUS 不是同一条供电路径。
PD:先建立合同,再按合同供电
普通 Type-C 连接首先完成安全的连接检测和默认供电流程,不能一插入就施加任意高压。PD 通过 CC 上的消息交换请求新的供电条件;Source 提供能力,Sink 根据自身、电缆和系统限制提出 Request。固定 PDO 示例流程如下。
Source Sink Source_Capabilities:例如提供 5 V / 3 A、9 V / 3 A Request:请求 9 V / 2 A Accept:同意该请求 PS_RDY:切换完成,电源已就绪 供电切换窗口:不得把 Accept 当作新电压已经稳定 固定 PDO 协商:Accept 是接受请求,PS_RDY 才报告电源就绪 省略 GoodCRC 等协议细节;此例是固定供电合同,不是 PPS,也没有自动进入 EPR。
Source 发送 Accept 只表示接受请求,电源还需要切换并稳定,再以 PS_RDY 报告就绪。PPS 是可编程电源能力,不能当作 Accept 后的通用状态。Request 可能被拒绝,供电能力也可能因多口共享或温度变化而重新协商,设备必须处理协商失败和合同变化。
功能 解决什么 需要避免的推断
SPR 固定电压 常见 5/9/15/20 V 等合同,范围可达 100 W 每个充电器都提供所有电压和 5 A
EPR 扩展电压范围,包含 28/36/48 V,最高 240 W 普通旧 5 A 线自动支持 48 V
PPS 在声明范围内请求可编程电压/电流 设备内部无需充电管理或功率转换
PD 3.1 引入的 EPR 把上限扩展到 48 V×5 A=240 W,需要端口、线缆和电源路径共同具备相关能力;标称 PD 版本并不能替代具体能力声明。USB-IF:USB Power Delivery
PPS 可让电源输出更适合设备充电链路,减少某些转换损耗,但电池仍需要受控电压/电流、保护和热管理,常见系统仍使用降压或电荷泵等电路。PPS Request 的编程粒度也不等于实测电压精度或电流纹波;充电速度由电池状态和整机策略共同限制。
功率算例:接口输入功率不是电池功率
假设协商到 20 V、3 A,接口上限为 60 W;在 3 A 负载、完整供电回路电阻 0.10 Ω 的教学条件下,线缆压降为 0.30 V、损耗 0.90 W,接收端约得到 59.1 W。若设备自身消耗 10 W,余下功率再经过假设 90% 效率的充电路径,电池得到约 (59.1−10)×0.9=44.19 W。
这是分配预算,不是某台手机或电脑的实测效率。提高协商功率也不保证设备持续按上限吸收;端口共享、电池充电阶段和温控都可能改变实际值。
Accept 之后,能立即按新电压取电吗?
先尝试Reject,原来的就绪条件保持;再接受一次请求,电源状态进入“转换中”,不会立刻展示目标电压已经可用。这里保留请求、应答、就绪的因果顺序,按钮对应协议事件,不能任意跳过前置条件。
正在呈现知识画面 重新加载
Accept 之后,能立即按新电压取电吗? Accept只接受请求;等待电源完成转换并报告PS_RDY,才把新供电条件交付为就绪。
{"id":"pd-accept-ready","title":"Accept 之后,能立即按新电压取电吗?","summary":"Accept只接受请求;等待电源完成转换并报告PS_RDY,才把新供电条件交付为就绪。","height":1000,"html":"<h2 data-i18n=\"heading\"></h2><p class=\"intro\" data-i18n=\"intro\"></p><div class=\"actions\"><button id=\"r9\" data-i18n=\"r9\"></button><button id=\"r20\" data-i18n=\"r20\"></button><button id=\"accept\" data-i18n=\"accept\"></button><button id=\"reject\" data-i18n=\"reject\"></button><button id=\"ready\" data-i18n=\"ready\"></button><button id=\"reset\" data-i18n=\"reset\"></button></div><div class=\"metrics\"><div><span data-i18n=\"state\"></span><strong id=\"state\"></strong></div><div><span data-i18n=\"requested\"></span><strong id=\"requested\"></strong></div><div><span data-i18n=\"usable\"></span><strong id=\"usable\"></strong></div></div><section class=\"panel\"><h3 data-i18n=\"history\"></h3><div id=\"history\"></div></section><details class=\"scope\"><summary data-i18n=\"scopeLabel\"></summary><p data-i18n=\"scope\"></p></details>","css":".intro{margin:8px 0 18px;color:var(--muted);font-size:14px}.caption,.hint{font-size:12px;color:var(--muted);margin-top:12px}.control{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:6px 12px;align-items:center;margin:14px 0;font-size:13px}.control label{font-size:13px}.control output{color:var(--accent);min-width:5em;text-align:right;font-variant-numeric:tabular-nums}.control input{grid-column:1/-1;width:100%;margin:0}.presets{display:flex;gap:4px;align-items:stretch}.presets button{flex:1 1 0;min-width:0;overflow-wrap:anywhere;font-size:13px}.actions{display:flex;gap:8px;flex-wrap:wrap;margin:14px 0}.actions button{flex:1;min-width:0;font-size:13px;min-height:42px}.copy{display:grid;font-size:14px;margin:16px 0}.copy>*{grid-area:1/1;margin:0}.reserve{visibility:hidden}.scope{margin-top:14px;color:var(--muted);font-size:12px}.scope summary{padding:8px 0;cursor:pointer}.scope p{margin-top:10px}.two{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.card{border:1px solid var(--rule);border-radius:9px;padding:14px;min-width:0}.card header{font-size:14px;font-weight:600;margin-bottom:10px}.card button{font-size:12px;width:100%;min-width:0}.card small{display:block;font-size:12px;color:var(--muted)}.card code{font-size:12px;overflow-wrap:anywhere}.metrics{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:16px 0}.metrics>div{border-left:2px solid var(--accent);padding-left:10px;min-width:0}.metrics span{display:block;min-height:3.2em;color:var(--muted);font-size:12px}.metrics strong{font-size:23px;display:block;font-weight:550;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.formula{border-top:1px solid var(--rule);padding-top:12px;margin-top:14px;font-size:13px;font-variant-numeric:tabular-nums;overflow-wrap:anywhere}.value{font:550 20px ui-monospace,monospace}.legend{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:12px;color:var(--muted);margin:12px 0}.legend span:before{content:'';display:inline-block;width:8px;height:8px;border-radius:2px;background:var(--accent);margin-right:6px}.legend .second:before{background:var(--second)}.check{display:flex;align-items:center;gap:8px;font-size:13px;margin:12px 0}.check input{width:16px;height:16px;flex-shrink:0;accent-color:var(--accent)}select,input[type=text],input[type=number]{background:var(--paper);color:var(--ink);font:inherit;font-size:13px;padding:10px;border:1px solid var(--rule);border-radius:7px;max-width:100%;min-width:0}select{width:100%;min-height:42px}.band{height:20px;display:flex;background:var(--surface);border-radius:4px;overflow:hidden}.band i{height:100%;display:block;background:var(--accent);transition:width .25s}.band i.second{background:var(--second)}button:disabled{cursor:default}.status{font-size:13px;min-height:4.8em}.mono{font-family:ui-monospace,monospace;font-variant-numeric:tabular-nums}.muted{color:var(--muted)}\n@media(max-width:480px){.two{gap:8px}.card{padding:12px 9px}.actions button,.presets button{font-size:12px}.metrics strong{font-size:20px}.metrics{gap:8px}}\n@media(prefers-reduced-motion:reduce){*,*::before,*::after{transition:none!important;animation:none!important}}\n.track-row{margin:16px 0}.track-row>span{display:block;font-size:12px;color:var(--muted);margin-bottom:7px}.track{display:flex;gap:5px;min-width:0}.cell{flex:1;min-width:0;min-height:48px;border:1px solid var(--rule);border-radius:5px;background:var(--surface);display:flex;align-items:center;justify-content:center;text-align:center;padding:5px 3px;font-size:12px;overflow-wrap:anywhere;font-variant-numeric:tabular-nums}.cell.on{background:var(--accent-soft);border-color:var(--accent)}.cell.gold{background:var(--second-soft);border-color:var(--second)}.cell.empty{border-style:dashed;color:var(--muted)}.cell.error{border-color:var(--second);text-decoration:line-through}.choices{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;margin:14px 0}.choices button{min-width:0;padding:10px 4px;font-size:12px;overflow-wrap:anywhere}.choices button[aria-current=true]{border-color:var(--accent);background:var(--accent-soft)}.relation{display:grid;grid-template-columns:minmax(0,1fr) 28px minmax(0,1fr);align-items:center;gap:6px;margin:12px 0}.relation .cell{min-height:72px}.relation>i{text-align:center;font-style:normal;color:var(--accent)}.readout{font-size:13px;white-space:pre-line;min-height:6.4em;overflow-wrap:anywhere}.plot{position:relative;border-left:1px solid var(--rule);border-bottom:1px solid var(--rule);padding:8px 0;margin:18px 0}.plot-row{height:28px;position:relative;margin:4px 0;background:var(--surface)}.plot-row i{position:absolute;inset-block:5px;background:var(--accent);min-width:2px;transition:width .2s,left .2s}.plot-row b{position:relative;padding:4px 6px;font:11px/28px ui-monospace,monospace;background:var(--paper);border-radius:3px}.axis{display:flex;justify-content:space-between;font-size:11px;color:var(--muted)}\n\n/* Action labels must remain readable across locales and narrow embeds. */\n.actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}\n.actions button{overflow-wrap:anywhere;white-space:normal;min-height:58px;padding:8px}\nbutton{overflow-wrap:anywhere}\n@media(min-width:640px){.actions{grid-template-columns:repeat(3,minmax(0,1fr))}}\n\n.metrics span{overflow-wrap:anywhere}\n.panel{border:1px solid var(--rule);border-radius:9px;padding:12px;margin:14px 0;min-width:0}.panel h3{font-size:13px;margin:0 0 10px;color:var(--muted)}.source{font:13px/1.8 ui-monospace,monospace;white-space:pre-wrap;overflow-wrap:anywhere;margin:12px 0}.source mark{background:var(--accent-soft);color:var(--ink);border-bottom:2px solid var(--accent)}.source .fault{background:var(--second-soft);border-color:var(--second)}.diagram{display:block;width:100%;height:auto;max-height:320px;margin:14px 0;overflow:visible}.diagram text{fill:var(--ink);font:12px ui-monospace,monospace}.diagram .edge{stroke:var(--muted);stroke-width:1.5;fill:none}.diagram .edge.on{stroke:var(--accent);stroke-width:3}.diagram .node{fill:var(--surface);stroke:var(--rule);stroke-width:1.5}.diagram .node.on{fill:var(--accent-soft);stroke:var(--accent)}.diagram .node.gold{fill:var(--second-soft);stroke:var(--second)}.log{font:12px/1.8 ui-monospace,monospace;white-space:pre-line;overflow-wrap:anywhere;min-height:7.2em}.table{display:grid;gap:5px;margin:14px 0}.table .tr{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:5px}.table .tr>*{padding:8px 5px;background:var(--surface);border-radius:4px;min-width:0;overflow-wrap:anywhere;font-size:12px}.table .tr .on{background:var(--accent-soft)}.table .tr .gold{background:var(--second-soft)}.choices button{min-height:44px}.metrics strong{min-height:1.6em}.code-line{display:block}.code-line.on{background:var(--accent-soft);border-left:2px solid var(--accent);padding-left:6px}.status-badge{font-size:12px;color:var(--accent)}.tile-grid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:6px}.tile-grid .cell{min-height:40px}.actions button{min-height:48px}.form-field{display:grid;gap:8px;margin:14px 0;font-size:13px}.form-field input{width:100%;font-family:ui-monospace,monospace}.metrics.three{grid-template-columns:repeat(3,minmax(0,1fr))}.formula{min-height:3.2em}.presets{flex-wrap:wrap}.presets button{flex-basis:25%;min-height:44px}\n\n.budget{display:flex;height:28px;margin:16px 0;background:var(--surface);border-radius:5px;overflow:hidden}.budget i{display:block;background:var(--accent);transition:width .2s}.budget i.gold{background:var(--second)}.intervals{margin:16px 0}.interval{position:relative;height:36px;background:var(--surface);margin:6px 0;border-radius:4px;overflow:hidden}.interval i{position:absolute;height:100%;background:var(--accent-soft);border-left:2px solid var(--accent)}.interval i.gold{background:var(--second-soft);border-color:var(--second)}.interval span{position:relative;z-index:1;font:12px/36px ui-monospace,monospace;padding-left:7px}.table .tr>*{min-height:4.8em}.formula{white-space:pre-line;min-height:7.2em}.actions:has(>button:only-child){grid-template-columns:1fr}.metrics strong{min-height:3.2em}.rangegrid{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:3px;margin:14px 0}.rangegrid .cell{min-height:30px;padding:3px 1px;font-size:10px}.message{min-height:7.2em;white-space:pre-line;font:13px/1.8 ui-monospace,monospace;overflow-wrap:anywhere}\n/* Allow CJK hanging punctuation without overflowing a metric's border box. */\n.metrics>div{padding-right:4px}.metrics span{line-break:anywhere}\n\n.chart-wrap{margin:18px 0}.chart-label{font-size:12px;color:var(--muted);min-height:3.2em}.curve{display:block;width:100%;height:auto;max-height:320px;overflow:visible}.curve text{font:11px ui-monospace,monospace;fill:var(--muted)}.gridline{stroke:var(--rule);stroke-width:1}.metrics strong{font-size:20px;min-height:3.2em}.formula{font:12px/1.8 ui-monospace,monospace;min-height:9em}.readout{min-height:8em}.presets button{flex-basis:30%}.scope p{overflow-wrap:anywhere} .unit-note{font-size:12px;color:var(--muted);margin:10px 0}\n\n.metrics span{word-break:break-all;line-break:strict}.metrics>div{padding-right:6px}\n\n#state,#usable{min-height:6.4em}#history{min-height:8em;white-space:pre-line;font-size:13px}","js":"const $=s=>document.querySelector(s);const set=(id,v)=>$('#'+id).textContent=v;const t=k=>viz.t(k);function cells(id,values){$('#'+id).replaceChildren(...values.map(v=>{const e=document.createElement('div');e.className='cell '+(v.cls||'');e.textContent=v.text;e.title=v.title||v.text;return e;}));}function pressed(mode){document.querySelectorAll('[data-mode]').forEach(e=>e.setAttribute('aria-pressed',String(e.dataset.mode===mode)));}const esc=s=>String(s).replace(/[&<>\"']/g,c=>({'&':'&','<':'<','>':'>','\"':'"',\"'\":'''}[c]));const fmt=s=>'{'+[...s].sort().join(', ')+'}';function graph(id,nodes,edges){const el=$('#'+id);el.setAttribute('viewBox','0 0 360 200');el.innerHTML='<defs><marker id=\"arrow-'+id+'\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"5\" markerHeight=\"5\" orient=\"auto-start-reverse\"><path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"var(--muted)\"/></marker></defs>'+edges.map(e=>{const a=nodes[e[0]],b=nodes[e[1]],dx=b.x-a.x,dy=b.y-a.y,d=Math.hypot(dx,dy)||1;if(edges.some(r=>r[0]===e[1]&&r[1]===e[0])){const nx=-dy/d,ny=dx/d;return '<path class=\"edge '+(e[2]?'on':'')+'\" d=\"M '+(a.x+dx/d*22+nx*12)+' '+(a.y+dy/d*22+ny*12)+' Q '+((a.x+b.x)/2+nx*38)+' '+((a.y+b.y)/2+ny*38)+' '+(b.x-dx/d*25+nx*12)+' '+(b.y-dy/d*25+ny*12)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}return '<line class=\"edge '+(e[2]?'on':'')+'\" x1=\"'+(a.x+dx/d*25)+'\" y1=\"'+(a.y+dy/d*25)+'\" x2=\"'+(b.x-dx/d*28)+'\" y2=\"'+(b.y-dy/d*28)+'\" marker-end=\"url(#arrow-'+id+')\"/>';}).join('')+nodes.map(n=>'<g><circle class=\"node '+(n.cls||'')+'\" cx=\"'+n.x+'\" cy=\"'+n.y+'\" r=\"25\"/><text x=\"'+n.x+'\" y=\"'+(n.y+4)+'\" text-anchor=\"middle\">'+esc(n.name)+'</text>'+(n.sub?'<text x=\"'+n.x+'\" y=\"'+(n.y+43)+'\" text-anchor=\"middle\">'+esc(n.sub)+'</text>':'')+'</g>').join('');}function table(id,rows){$('#'+id).classList.add('table');$('#'+id).replaceChildren(...rows.map(r=>{const row=document.createElement('div');row.className='tr';row.style.gridTemplateColumns='repeat('+r.length+',minmax(0,1fr))';r.forEach(x=>{const c=document.createElement('div');if(typeof x==='object'){c.textContent=x.text;c.className=x.cls||'';}else c.textContent=x;row.append(c)});return row;}));}function band(id,parts,total){$('#'+id).replaceChildren(...parts.map((p,i)=>{const e=document.createElement('i');e.style.width=(100*p.value/total)+'%';e.className=i%2?'gold':'on';e.title=p.name+': '+p.value;return e}));}function intervals(id,items,total){$('#'+id).replaceChildren(...items.map(p=>{const row=document.createElement('div');row.className='interval';const bar=document.createElement('i');bar.style.left=(100*p.start/total)+'%';bar.style.width=(100*(p.end-p.start)/total)+'%';bar.className=p.cls||'';const label=document.createElement('span');label.textContent=p.label;row.append(bar,label);return row;}));}function plot(id,series,xr,yr,opts={}){const e=$('#'+id),X=x=>42+(x-xr[0])/(xr[1]-xr[0])*298,Y=y=>175-(y-yr[0])/(yr[1]-yr[0])*148;let out='<defs><clipPath id=\"clip-'+id+'\"><rect x=\"42\" y=\"27\" width=\"298\" height=\"148\"/></clipPath></defs>';for(let i=0;i<3;i++){let x=xr[0]+i*(xr[1]-xr[0])/2,y=yr[0]+i*(yr[1]-yr[0])/2;out+='<path class=\"gridline\" d=\"M '+X(x)+' 27V175M42 '+Y(y)+'H340\"/><text x=\"'+X(x)+'\" y=\"194\" text-anchor=\"middle\">'+esc(opts.xfmt?opts.xfmt(x):Number(x.toFixed(2)))+'</text><text x=\"36\" y=\"'+(Y(y)+4)+'\" text-anchor=\"end\">'+esc(opts.yfmt?opts.yfmt(y):Number(y.toFixed(2)))+'</text>';}out+='<g clip-path=\"url(#clip-'+id+')\">';for(const s of series){out+='<path fill=\"none\" stroke=\"'+(s.color||'var(--accent)')+'\" stroke-width=\"2.5\" '+(s.dash?'stroke-dasharray=\"5 4\"':'')+' d=\"'+s.pts.map((p,i)=>(i?'L':'M')+X(p[0]).toFixed(2)+','+Y(p[1]).toFixed(2)).join(' ')+'\"/>';}for(const p of opts.points||[])out+='<circle cx=\"'+X(p[0])+'\" cy=\"'+Y(p[1])+'\" r=\"4\" fill=\"var(--second)\" stroke=\"var(--paper)\" stroke-width=\"1.5\"/>';if(opts.cursor!==undefined)out+='<path d=\"M'+X(opts.cursor)+' 27V175\" stroke=\"var(--muted)\" stroke-dasharray=\"3 3\"/>';e.innerHTML=out+'</g>';e.dataset.curves=JSON.stringify(series.map(s=>s.pts));}const curve=(fn,lo,hi,n=120)=>Array.from({length:n+1},(_,i)=>{const x=lo+(hi-lo)*i/n;return[x,fn(x)]});function inputs(draw){document.querySelectorAll('input,select').forEach(e=>{e.addEventListener('input',draw);e.addEventListener('change',draw)});draw()}const n=id=>+$('#'+id).value;const show=(id,v,d=3)=>set(id,Number(v.toFixed(d)));let state='idle',voltage=5,request=null,log=[];function draw(){set('state',t(state));set('requested',request===null?'—':request);set('usable',state==='switching'?t('transition'):voltage+' V');set('history',log.slice(-5).join('\\n'));$('#r9').disabled=$('#r20').disabled=state!=='idle';$('#accept').disabled=$('#reject').disabled=state!=='waiting';$('#ready').disabled=state!=='switching';$('#state').dataset.state=state;$('#usable').dataset.voltage=state==='switching'?'unknown':voltage;}for(const v of[9,20])$('#r'+v).onclick=()=>{request=v;state='waiting';log.push('Request '+v+' V');draw()};$('#accept').onclick=()=>{state='switching';log.push('Accept');draw()};$('#reject').onclick=()=>{state='idle';log.push('Reject');request=null;draw()};$('#ready').onclick=()=>{voltage=request;request=null;state='idle';log.push('PS_RDY '+voltage+' V');draw()};$('#reset').onclick=()=>{state='idle';voltage=5;request=null;log=[];draw()};draw();","audio":false,"strings":{"accept":"Source:Accept","heading":"Accept 之后,能立即按新电压取电吗?","history":"事件记录","idle":"就绪","intro":"请求9 V或20 V,分别观察接受、切换和就绪状态。","r20":"请求20 V","r9":"请求9 V","ready":"Source:PS_RDY","reject":"Source:Reject","requested":"本次请求(V)","reset":"重置","scope":"已有5 V就绪连接,只演示固定PDO交换。Accept至PS_RDY期间不指定实际VBUS波形,不模拟完整PD状态机、超时和电流规则。","scopeLabel":"模型范围与约定","state":"交换状态","switching":"接受,转换中","transition":"转换中,等待PS_RDY","usable":"电源状态","waiting":"请求待回应"}}
线缆标识与视频能力要分别核对
USB-IF 的 USB-C 线缆认证标识区分数据性能和功率能力。USB 2.0 数据线同样可以支持较高 PD 功率,因此“240 W”不是高速线的证明;e-marker 是线缆能力识别的一部分,也不能仅凭有芯片便判断支持所有速率。USB-IF:线缆与连接器 、Type-C 产品说明指南
DP Alt Mode 可把高速信号对分配给 DisplayPort:常见两条 DP lane 方案保留另一组 USB 3.x 收发连接,四条 DP lane 方案则把高速对用于视频,USB 2.0 D+/D− 仍可使用。分辨率并非仅由 lane 数决定,还取决于链路速率、消隐、刷新率、色深、色度抽样及 DSC 支持,不能固定写成“两 lane 就是 4K60”。VESA:DisplayPort Alt Mode
USB4 中的视频隧道是在 USB4 连接内分配带宽,与把连接器高速对直接切换为原生 DP 的 Alt Mode 不同。Thunderbolt 也有自身版本和认证要求,不能把所有 USB4 产品直接等同于某一代 Thunderbolt。
按失败阶段定位,比反复换“更贵的线”更明确
现象 先分辨哪一层 核对重点
C-to-C 不上电,A-to-C 能用 CC 连接检测 Rd、方向、Source/Sink 配置、电源开关
能充电,系统看不到设备 数据与枚举 线缆数据能力、D+/D−、高速路径、描述符与日志
只在一个方向工作 插座与方向复用 两侧 CC、USB 2.0 对应触点、高速 MUX
USB-C 显示无输出 视频能力与模式 主机端口、线缆、坞站、显示器和模式协商
传文件慢 实际链路与共享负载 协商速率、Hub 上行、存储介质及协议开销
充电达不到铭牌功率 供电合同和整机策略 PDO、线缆额定、多口分配、温控及电池阶段
复算带宽与功率
from math import isclose
encoded_byte_rate = 5e9 * ( 8 / 10 ) / 8
assert encoded_byte_rate == 500e6 voltage , current , loop_r = 20 , 3 , 0. 10
loss = current * * 2 * loop_r
received = ( voltage - current * loop_r ) * current
assert isclose ( loss , 0. 9 ) and isclose ( received , 59. 1 )
assert isclose ( received + loss , voltage * current )
assert isclose ( ( received - 10 ) * 0. 9 , 44. 19 )
assert 48 * 5 == 240
print ( ' 编码吞吐、线缆压降、功率分配与 EPR 上限算式检查通过' )
继续查阅