USB BC1.2 充电检测协议详解:手机如何识别充电器类型
前言
你有没有好奇过:手机插上 USB 线后,是怎么知道对面是电脑还是充电头的?为什么插电脑上只能慢充,插充电头就能快充?
答案就藏在 USB BC1.2(Battery Charging 1.2) 规范里。这套协议定义了手机(PD)如何通过纯硬件方式,在不需要软件参与的情况下,快速判断对面是什么类型的充电端口,从而决定用多大电流充电。
一、核心术语:5 种端口类型
在深入检测流程之前,必须先搞清楚 BC1.2 定义的 5 种设备类型:
| 缩写 | 全称 | 通俗解释 | 关键特征 |
|---|---|---|---|
| SDP | Standard Downstream Port | 普通电脑 USB 口 | D+ 和 D- 各有 15kΩ 下拉电阻到地;电流分三档(2.5mA / 100mA / 500mA) |
| DCP | Dedicated Charging Port | 手机充电头 | D+ 与 D- 短接;必须能提供至少 1.5A 持续电流 |
| CDP | Charging Downstream Port | 能充电又传数据的口 | 空闲时在 D- 上输出约 0.5V~0.7V 监视 D+;握手完成后立即释放 D- 电压以免干扰数据 |
| PD | Portable Device | 手机、平板等便携设备 | 所有检测动作都由 PD 发起,不是充电端发起 |
| ACA | Accessory Charger Adapter | 一分二 OTG 充电转接头 | 普通学习可浅看,做 OTG 产品才需深挖 |
重点:整个 BC1.2 检测流程中,所有的检测动作(加电压、读电平)都是由 PD(手机)发起的,电脑和充电头是被动响应。
二、SDP 的”借电开机”机制
SDP 有一个非常巧妙的特例——当手机电池彻底没电(电压低于 2V)、系统还没启动时:
- 物理动作:PD 的充电芯片通过纯硬件逻辑,在 D+ 线上持续输出 0.5V~0.7V 的电压(VDP_SRC)
- 电脑反应:SDP 检测到 D+ 被拉高,误以为手机想”枚举通信”,于是把电流限制从 2.5mA 放宽到 100mA 甚至 500mA
- 实际效果:手机借到几百毫安的”救命电流”,启动 CPU 和屏幕,等系统跑起来后软件再接管充电逻辑
这是 SDP 唯一允许不用软件枚举就能输出大电流的特例,完全靠硬件完成。
三、CDP 的”握手与释放”
CDP 能充电又能传数据,它的行为更加精细:
- 监视阶段:CDP 空闲时在 D- 线上主动输出约 0.5V~0.7V 的电压,监视 D+ 的变化
- 检测阶段:当 CDP 检测到 D+ 上的电压升高(高于 0.25V 但低于 0.8V),立刻在 D- 线上输出 VDM_SRC 电压作为回应
- 释放阶段:握手完成后,CDP 内部电路瞬间切断 D- 上的 VDM_SRC 输出电压
为什么要释放?因为 D+ 和 D- 是 USB 数据传输的差分信号线。如果 CDP 一直强行在 D- 上施加电压,就会完全破坏 USB 数据波形,导致电脑无法识别手机。
四、充电器检测流程(核心部分)
这是 BC1.2 的灵魂——手机怎么判断插的是电脑还是充电头。整个流程分为 4 步:
4.1 VBUS 检测(物理触发开关)
1 | VBUS > 0.8V(典型值) → 比较器输出高电平 → 唤醒后续逻辑 |
这是整个检测流程的物理触发开关。低于阈值时,PD 不会启动任何检测,防止电池倒灌损坏充电芯片。
4.2 数据接触检测 DCD(可选)
DCD 使用一个电流源(IDP_SRC)来探测数据引脚在插入过程中是否已物理接触。
- 实现了 DCD 的设备:一旦检测到数据脚接触,立即启动主检测,不用傻等
- 未实现 DCD 的设备:必须在附着事件后等待 TDCD_TIMEOUT(几毫秒到几百毫秒)再开始主检测
PD 不强制要求实现 DCD,但实现它可以加速检测过程。
4.3 主检测 Primary Detection(必选)
这是 PD 必须实现的核心检测步骤:
1 | ┌─────────────────────────────────────────────┐ |
4.4 次检测 Secondary Detection(条件必选)
次检测用于区分 DCP 和 CDP:
1 | ┌─────────────────────────────────────────────┐ |
哪些 PD 必须实现次检测? 在检测到 VBUS 后 TSVLD_CON_PWD(约 100ms~300ms)内无法准备好被枚举的 PD。能快速启动的 PD 允许跳过。
五、完整检测流程图
把上面的步骤串起来,就是一棵完整的决策树:
1 | 插入 USB 线 |
六、弱电池 vs 好电池算法
BC1.2 针对手机电池状态不同,定义了两套算法:
6.1 弱电池算法(Good Battery = No,手机快没电了)
算法极简,是一个纯硬件决策树:
- VBUS 有电(插线了)
- 硬件在 D+ 上施加探测电压 VDP_SRC
- 看 D- 电压:
- D- > VDAT_REF(D+/D- 被短接,对面是 DCP 或 CDP)→ 直接拉 1.5A 大电流充电
- D- < VDAT_REF(对面是电脑 SDP,D- 有下拉电阻)→ 只敢抽 100mA(IUNIT)
- 额外判断 ID 脚:如果是 OTG 设备且插了特殊线缆(ID 非悬空),也可以破例拉大电流
6.2 好电池算法(Good Battery = Yes,系统已能启动)
好电池算法更加完整,增加了枚举和超时机制:
第一步:触发与 DCD
- 检测到 VBUS > VOTG_SESS_VLD
- 启动超时定时器 TDCD_TIMEOUT(几百毫秒)
- 支持 DCD 的设备:启用 IDP_SRC,监控 D+ 是否被拉低
第二步:主检测
- D- < VDAT_REF → SDP → 先抽 100mA,枚举成功后升到 500mA
- D- > VDAT_REF → 充电端口或 ACA
第三步:”提前枚举”分支
- 如果 PD 此时已准备好被枚举(系统已启动):
- 直接跳到 Connect 状态,尝试发送 USB 数据包
- 对方回应 → SDP 或 CDP → 按对应模式充电
- 对方不回应 → DCP → 按 1.5A 充电
- 如果还没准备好 → 必须老老实实进入次检测
第四步:次检测
- D+ > VDAT_REF → DCP → 1.5A 大电流充电
- D+ < VDAT_REF → CDP → 1.5A 充电 + 等待枚举
七、关键电压/电流参数速查表
| 参数 | 典型值 | 说明 |
|---|---|---|
| VDP_SRC | 0.5V ~ 0.7V | PD 在 D+ 上施加的探测电压 |
| VDM_SRC | 0.5V ~ 0.7V | 在 D- 上施加的探测电压 |
| VDAT_REF | 0.25V ~ 0.4V | 判断阈值,区分 SDP 和充电端口 |
| VOTG_SESS_VLD | ~0.8V | VBUS 有效检测阈值 |
| IDP_SRC | 几μA~几十μA | DCD 检测用电流源 |
| IUNIT | 100mA | SDP 基础电流单位 |
| DCP 充电电流 | ≥ 1.5A | DCP 必须提供的最小电流 |
| TDCD_TIMEOUT | 几ms~几百ms | DCD 超时等待时间 |
| TSVLD_CON_PWD | PD 准备枚举的宽限期 |
八、总结
BC1.2 的核心思想可以用一句话概括:
手机通过纯硬件方式,在 D+/D- 数据线上施加电压并读取响应,根据电压高低来判断对面是电脑(SDP)还是充电头(DCP/CDP),从而决定充电电流大小。
整个过程不需要任何软件参与,从插入到识别完成通常在几百毫秒内完成。这套精妙的协议让我们的手机能够智能地适配不同的充电环境,既保证了充电速度,又不会损坏设备。