Type-C双向供电主从切换方案:LDR6500 IO电平硬切Sink/Source
发布时间:2026/9/29 20:38:59 锦皓数字建站

上周把一个 Type-C 双向供电原型板调通了最折腾的地方反而不是 DC-DC也不是功率路径而是这个口到底该当“供电方”还是“受电方”。同一个 Type-C 口插到电脑上要当 Sink从电脑的 PD 口取电插到充电器上又要反过来当 Source给后面的设备送电。角色切来切去协议芯片的身份识别和切换总是差点意思。折腾一圈之后我最终选了最土但最稳的方案用 LDR6500 的 IO 电平来控制主从切换。这篇文章就把这个落地思路完整拆开讲一遍包括 Type-C 的身份究竟放在谁的引脚上、IO 电平是怎么左右这个身份的以及从原理图到调试台会遇到哪些坑。适合正拿着 LDR6500 做 Type-C 取电、PD 诱骗、设备角色切换或者准备画 Type-C 供电板的朋友。看完你应该能自己搭一个最小系统并且知道怎么排查“插上没反应”“角色切不过去”这类问题。1. Type-C 的身份不在协议里而在 CC 引脚的两颗电阻上1.1 身份协商的本质Rp 和 Rd 一上一下很多人第一次玩 Type-C 的时候以为“这个口能不能供电、能不能被供电”是芯片通过复杂协议决定的其实第一步恰恰是纯硬件行为。Type-C 的电源角色是靠 CC 引脚上的两颗电阻完成的供电方Source在 CC 引脚上拉一颗电阻到自己的电源轨这颗电阻叫 Rp受电方Sink在 CC 引脚上下拉一颗 5.1kΩ 电阻到地这颗电阻叫 Rd。插上去的瞬间Source 通过 CC 引脚读到的电压就是电源轨经过 Rp 和 Rd 分压后的值。电压落在一个特定区间Source 就认为“对面是个 Sink”于是打开 VBUS电压完全为 0则认为线是空悬的。这个过程和串口检测设备在位很像但更简单、更快。PD 协议本质上是叠加在这个电阻网络上的一层 BMC 编码通信双方在 CC 线上协商电压、电流以及数据角色。换句话说哪怕完全不跑 PDType-C 也可以只做“默认 5V 电源”身份检测照样由电阻完成。1.2 LDR6500 在身份体系里的位置LDR6500 这种 PD 协议芯片内部已经集成了 CC 检测比较器、协议解析逻辑和 Rd 网络。规格书里所谓的“CC1/CC2 检测”指的就是它会判断 CC 线上有没有被对面的 Rp 拉起来。从角色上看LDR6500 更偏 Sink它检测到对面是 Source 之后会主动发送 PD Request请求把电压从 5V 提到 9V、12V 甚至 20V。很多 Type-C 诱骗线、电源触发板就是拿它做的这也是它最常见的用法。但标题里的“主从切换”单靠 LDR6500 本身不够。LDR6500 决定的是“我作为受电端要多少电压”而系统整体对外是 Source 还是 Sink还要靠外部功率路径和一个 IO 电平来定。我在实际项目中用到的思路是把 LDR6500 当作“非常会讨价还价的受电端”由 IO 电平决定它是否参与工作同时用另一路 MOSFET 控制 VBUS 的走向。这样一个小系统就能在“插上电脑取电”和“插上充电器给别人供电”之间切换。1.3 电源角色和数据角色别混为一谈Type-C 的世界里其实有两套“主从”电源主从Source/Sink和数据主从Host/Device。Rp/Rd 直接决定电源角色但数据角色还要靠 USB 枚举。一个 Type-C 口可以同时是 Sink正在充电又同时是 Host带着 U 盘手机就是这样。所以做“主从切换”之前必须先把话说清楚你要切的是电源身份还是数据身份还是两个一起切LDR6500 只管电源侧。如果项目还需要切换 USB 数据通道比如同一个口既要连电脑做 Device又要接 U 盘做 Host那就得在 D/D- 上加模拟开关由同一个 IO 电平或另一路 GPIO 控制。很多人在产品阶段翻车就是没分清这两套主从关系以为协议芯片把电源身份切好了USB 枚举就自然正确实际完全不是一回事。2. IO 电平控制主从切换的硬件思路——为什么硬切比协议切更省心2.1 为什么选 IO 电平而不是 I2C 寄存器PD 协议本身有 PR_Swap 这种角色交换机制可以让两个已经连接好的端口动态交换 Source/Sink 身份。问题在于跑 PR_Swap 需要协议芯片支持、需要 MCU 维护协议状态、还需要处理各种对方不配合的情况调试周期一下子拉长。IO 电平方案完全不同。它是一个纯粹的物理信号上电瞬间就定死不需要初始化、不需要握手。在工业设备里一个继电器触点、一个光耦隔离输入甚至一个船型开关都能控制身份。对很多固定场景来说——插到电脑上取电、插到充电器上供电——这种硬切足够用了而且异常情况少。逻辑分析仪一看就知道当前 IO 是什么状态排查问题非常直观。相比之下I2C 配置地址、寄存器、时序每一步都是潜在故障点。2.2 IO 电平怎么左右身份两条路实际落地有两条路。第一条如果协议芯片本身支持双角色DRPIO 电平直接切换芯片内部的 Rp/Rd 状态。芯片自己完成 Source 侧或 Sink 侧的全部物理层逻辑外部电路很干净。但这条路要求芯片选型时就选对LDR6500 这种偏 Sink 的芯片不一定能直接这么用。第二条更常见也更现实的组合方案LDR6500 负责 Sink 侧的 PD 协议IO 电平控制外部功率路径和一个“Rd 接入开关”。当系统需要对外表现 Sink 身份时IO 让 LDR6500 正常工作CC 上的 Rd 接好外部电源可以通过 VBUS 进来当系统需要表现 Source 身份时IO 先停止 LDR6500同时把 CC 上的 Rd 断开再把外部电源送到 Type-C 口。关键就在“断开 Rd”这一步很多人的 Source 模式一开就短路就是因为忘了 CC 上还挂着 5.1kΩ 对地电阻。IO 电平状态系统对外身份LDR6500 在干嘛VBUS 通路方向低Sink启用 CC 检测与 PD 协商外部电源进入系统高Source停止抢电CC 上的 Rd 被断开系统电源输出到外部2.3 两块 IO 还能顺便选电压档位LDR6500 这类芯片在很多固件里会提供两个 IO 引脚用来选择 PD 请求电压档位。两个 IO 的组合能表达 4 个状态正好对应常见的 5V、9V、12V、20V。比如IO1IO2请求电压示意低低5V高低9V低高12V高高20V这段只讲原理。不同批次、不同固件版本的实际映射可能完全不一样一定以你拿到的 LDR6500 规格书或供应商提供的参数表为准。我自己的习惯是拿到芯片先做一个小板验证把两个 IO 分别拉高拉低用示波器看 CC 线上的 PD 握手确认固件行为再往下设计。2.4 最小系统接线要点一个可用的最小系统大致包含这些节点VBUS、GND、CC1、CC2、IO1、IO2以及最终的电源输出。Sink 模式下CC1/CC2 通过芯片内部的 Rd 网络挂在检测电路上VBUS 从 Type-C 口进到系统电源路径Source 模式下CC1/CC2 外部改接到我们自己搭的 Rp 上拉网络VBUS 则由系统电源送出。这里有几个容易出现低级错误的地方。第一不要在 CC 线上加太大的对地电容CC 上要跑 BMC 编码的 PD 通信脉冲电容一大边沿变缓协议容易握手失败。第二IO 引脚不要在外部悬空哪怕芯片内部有弱上拉也建议外部再并一个 10kΩ 电阻明确默认身份。第三VBUS 路径必须加负载开关或者背靠背 MOSFET不要让外部电源无控制地倒灌进系统。这几点是“画板前就要想清楚”的不是等板子回来再调。3. 落地实操从原理图到示波器验证的完整流程3.1 第一步把 LDR6500 的 IO 行为查清楚拿到芯片或者模块第一件事不是画原理图而是确认 IO 电平的有效极性。有些固件里IO 拉低代表 Sink拉高代表 Source有些正好相反。还有些批次会默认把 IO 内部拉到某个固定电平外部接法必须配合内部状态否则你的“拉高”可能被内部拉低淹没了。我的做法是焊一块最小板CC1/CC2 引出测试点用一个可调电源模拟 Source把 IO 分别接到 3.3V 和 GND看 CC 电压和 VBUS 输出状态的变化。这一步花两个小时后面省两个星期。尤其是从不同渠道买到的 LDR6500固件版本可能不同IO 行为也可能不同不要想当然。3.2 第二步设计 CC 网络与 VBUS 功率路径Sink 模式比较简单CC 上的 Rd 网络让芯片自己处理VBUS 进到负载开关再进到系统。Source 模式真正麻烦你必须在系统对外体现 Source 身份时把原来连接在 CC 上的那颗 Rd 完全断开同时接入自己的 Rp 上拉网络。实际操作中我一般用一个 P-MOS 或 N-MOS 做 Rd 断开开关IO 电平低时 MOS 导通Rd 接入地IO 电平高时 MOS 关断Rd 从电路上消失。VBUS 路径则用背靠背 MOSFET这样无论哪边先上电都不会出现电流倒灌。如果你觉得 MOSFET 驱动麻烦也可以用现成的负载开关芯片但要注意负载开关的导通电阻和最大电流Type-C PD 动辄 3A、5A压降不能太大。3.3 第三步固件状态机与 IO 读取LDR6500 本身很多功能是硬件完成的但主从切换需要一个控制方通常是 MCU。下面是一段伪代码展示 IO 电平控制主从切换的主循环思路// 伪代码IO 电平控制身份切换 #include ldr6500_driver.h #define IO_MODE_PIN GPIO_PIN_5 typedef enum { MODE_SINK, MODE_SOURCE } sys_mode_t; sys_mode_t read_sys_mode(void) { // 外部电平决定身份低电平Sink高电平Source具体极性以硬件为准 return gpio_read(IO_MODE_PIN) ? MODE_SOURCE : MODE_SINK; } void system_switch_role(sys_mode_t new_mode) { // 安全第一先断开 VBUS避免切换瞬间两边打架 vbus_path_disable(); if (new_mode MODE_SINK) { ldr6500_sink_enable(1); // 启用 LDR6500 的 CC 检测和 PD 协商 cc_rd_connect(1); // 接上 5.1k Rd对外表现为 Sink } else { ldr6500_sink_enable(0); // 停止 LDR6500 抢 VBUS cc_rd_connect(0); // 断开 Rd避免把电源拉死 } delay_ms(10); // 等待 CC 电平稳定 if (new_mode MODE_SOURCE) { vbus_path_enable(); // 把外部电源送到 Type-C 口 } } int main(void) { sys_mode_t mode read_sys_mode(); system_switch_role(mode); while (1) { sys_mode_t cur read_sys_mode(); if (cur ! mode) { mode cur; system_switch_role(mode); } delay_ms(100); } }这段代码的核心思想是“切换身份之前先断 VBUS”。我踩过一次坑直接把 IO 从 Sink 切到 Source结果 LDR6500 还在抓着之前的 VBUS 不放外部电源也同时送过来两边电压一碰适配器直接打嗝。先关路径、再切身份、最后送电这个顺序不能反。3.4 第四步示波器验收调试的时候示波器至少抓三个点CC1、CC2、VBUS。Sink 模式下插入 Source 后 CC 应该由低变高被对面 Rp 拉起来然后出现一段 BMC 编码脉冲那是 PD 协商过程VBUS 从 0 跳到请求的目标电压。Source 模式下CC 应该由我们自己的 Rp 网络维持在一个偏高的电平接入一个 Sink 设备后CC 会被对方 Rd 拉低到分压点VBUS 则是我们主动送出的。判断主从切换是否成功最直接的就是看 CC 和 VBUS 的先后关系。如果 VBUS 起来了CC 还没有稳定说明身份检测和功率输出之间存在竞争条件需要增加延时或者调整切换顺序。这一步不要节省时间波形存下来后面改板子的时候还能拿来对比。4. 调板踩坑记录——CC 电阻、热插拔和 CH340 那些邻居4.1 坑一IO 浮空身份随机这是最隐蔽的坑。有些模块的 IO 引脚不做任何处理直接留给用户如果 MCU 还没启动或者用户忘了接IO 就浮空。浮空状态下芯片内部的弱上拉/弱下拉会随机决定一个身份表现就是“这次插上去取电下次插上去居然往外面送电”。解决方式很简单外部加一个 10kΩ 下拉或上拉把默认身份固定下来。如果你希望默认是 Sink就在 IO 上并联 10kΩ 到地如果希望默认是 Source就并联 10kΩ 到电源轨。MCU 接管之后再通过 GPIO 主动输出覆盖这个默认状态。另外MCU 和 LDR6500 共用电源域时注意一下上电时序别让 MCU 的 GPIO 在初始化之前输出一个不确定电平。4.2 坑二插上电脑没反应多半是 CC 少了 5.1kΩ用 Type-C 座子做设备端最常见的问题是插上电脑完全没反应。绝大多数情况不是芯片坏了而是 CC 引脚上的 5.1kΩ 下拉电阻没有放。主机只会通过 CC 引脚的电压判断是否有受电设备接入如果 CC 悬空电压不在 Sink 检测窗口内主机的 VBUS 根本不会打开。一个标准 Type-C 母座USB 2.0 相关信号的引脚分组大致是这样引脚位置信号作用A1/A12GND地A4/B4VBUS总线电源A5CC1身份检测 / PD 通信B5CC2身份检测 / PD 通信A6/B6DUSB 2.0 数据A7/B7D-USB 2.0 数据CC1 和 CC2 上必须各放一颗 5.1kΩ 下拉到地尤其在只做 USB 2.0 或纯供电的设备端这两颗电阻就是“身份证明”。我之前帮同事修过一台笔记本Type-C 口插移动硬盘没反应拆机量了一圈不是主控坏而是 CC 引脚附近的一颗 ESD 保护器件漏电导致 CC 电压掉出检测窗口系统一直认为没插设备。换掉那颗器件就恢复了。所以做 LDR6500 板子的时候CC 网络上的保护器件结电容不要选太大TVS 管的结电容尽量选 1pF 以下的。4.3 坑三D/D- 要不要串电阻网上经常有人问 CH340 这类 USB 转串口芯片接到 Type-C 座子上D/D- 需不需要串电阻。我的经验是如果 CH340 和 Type-C 座在同一块板上走线不超过几厘米可以不串如果通过线缆连接或者板子走线较长、又没有良好的阻抗控制那就在 D/D- 上各串一个 22Ω 到 33Ω 的电阻放在靠近芯片的一端。串电阻的作用不是限流而是抑制信号边沿反射、减少 EMI。更需要注意的是 D/D- 和 CC 走线不要平行太长。CC 上的 BMC 脉冲频率不低平行走线容易串扰进 D/D-导致 USB 枚举不稳定。如果只是 12Mbps 的 Full-Speed 设备问题不大如果跑 480Mbps High-Speed就不建议乱加对地电容保持走线短、参考地完整更有效。4.4 坑四切换瞬间 VBUS 打架IO 刚切到 Source 时如果对面正好也是一个 Source比如两台适配器对插两个 Rp 各自上拉谁也不会先输CC 电压会处在一个异常区间。更危险的是如果两边都开了 VBUS正极对正极电流会从一个电源灌进另一个电源。我的处理方式是IO 切到 Source 后延迟 20ms 再开 VBUS。这 20ms 内先用 ADC 读 CC 电压如果发现电压异常高或者持续抖动就认为对面也是 Source此时回退到 Sink 模式或者直接报错。这个检测逻辑不增加任何成本MCU 一个 ADC 通道就能搞定。热插拔的时候也一样VBUS 上不要瞬间硬切加一个软启动用小电流预充一下 Type-C 口的输出电容能明显减少打火和电压跌落。5. 从 Demo 到量产状态机、防倒灌和几种值得做的扩展玩法5.1 把切换逻辑写成状态机原型板调通之后不要停在“能跑就行”的状态。主从切换涉及到电源路径、协议协商、热插拔多种情况必须用状态机把行为固定下来。我的状态定义大致如下IDLE空载VBUS 无输出。SINK_ATTACH检测到对面 Source 的上拉LDR6500 开始工作。SINK_NEGOTIATELDR6500 正在和 Source 协商电压。SINK_READY协商完成VBUS 正常进入系统。SOURCE_ATTACHIO 切换为 Source断开 Rd等待对面 Sink 接入。SOURCE_READY检测到对面 SinkVBUS 主动输出。FAULT过压、过流、倒灌或协商超时。跳转条件主要依赖 IO 电平变化、CC 电压阈值和超时定时器。我习惯用一个 5ms 周期的轮询任务扫描这些状态任何跳转之前先执行“断开 VBUS”这个动作。这样做的好处是逻辑清晰每个状态都对应一组硬件行为出问题的时候看状态寄存器就知道卡在哪一步。5.2 功率路径可靠性设计主从切换产品的可靠性一大半在功率路径上。背靠背 MOSFET 是必须的防止两个 Source 互灌VBUS 入口和出口各放一颗 TVS吸收热插拔浪涌IO 电平控制线加一个 RC 滤波比如 1kΩ 电阻串联 100nF 电容到地防止干扰脉冲误切身份。量产测试阶段我建议在固件里加一条“身份回读”指令让上位机或测试治具读取当前 IO 状态和身份状态。很多虚焊、电阻贴错的问题靠这一条命令就能在生产线上筛掉。别小看这个细节Type-C 座子是手工焊接重灾区CC 电阻虚焊是“插上没反应”的第一大原因。5.3 扩展玩法这套“IO 电平控制主从切换”的思路换一下外围电路就能套到好几个项目上双向移动电源/户外电源LDR6500 做受电侧的 PD 协商IO 电平决定系统是给电池充电还是从电池放电外部配一颗双向 DC-DC。Type-C 调试器/串口工具LDR6500 负责从主机取电CH340 做串口再配合一颗 TS3USB221 模拟开关切换 D/D- 的数据通道IO 电平控制模拟开关的选通方向。开发板 Type-C 供电口一个 IO 决定请求 20V 还是 5V配合板上的 DC-DC 给主控供电避免上电时请求错误电压烧板。工业设备主从切换用光耦隔离的 IO 信号控制身份配合 PLC 的远程 IO 模块做角色切换这在现场调试中比软件改地址稳得多。5.4 什么时候别用 IO 电平硬切IO 硬切也不是万能的。如果产品需要在运行时频繁动态交换角色比如扩展坞在插拔不同设备时自动切换 Source/Sink或者需要根据电池电量和外接设备状态综合考虑身份这时候就需要换一颗支持完整 DRP/PR_Swap 的 PD 控制器比如 STUSB4500、FUSB302 配合 MCU 跑协议栈。LDR6500 加外部 MOS 的硬切方案适合“上电定身份”的场景不该拿去硬扛动态切换需求。我个人在实际操作中的体会是这套方案最大的优点就是“可预期”。IO 电平落下去身份就定下来不会因为协议栈状态混乱而出现两个口互相等对方的死局。第一次调切换时我总觉得协议芯片可以自己搞定一切结果发现硬件上 Rd 没有断开Source 模式一开5V 直接被拉到地适配器打嗝。后来老老实实按状态机做把身份切换理解成“先把手里的刀放下再决定自己是什么人”问题就顺了。给后来者一个建议画板之前先用 LDR6500 模块把 IO 行为摸清楚用示波器把 CC 波形存下来再动手设计功率路径。这比上来就画板、烧板后拿着万用表到处捅要省一个迭代周期。另外网上搜“IO”会出来一堆磁盘性能、PLC IO 之类完全不相关的内容搜 LDR6500 相关文章时注意别跑偏。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。