1. USB协议基础:总线架构、角色与电气特性
做嵌入式USB开发,第一件事不是翻数据手册,而是搞明白USB到底是怎么连的、谁说了算、信号长什么样。我见过不少工程师,上来就调端点、配描述符,结果枚举死活过不去——最后发现是D+、D-两根线焊反了。嗯,基础不牢,后面全是坑。
1.1 USB总线架构:树形拓扑与分层结构
USB总线是典型的树形拓扑。一个Host(主机)下面挂一个Root Hub,Root Hub下面可以接Hub,Hub再接设备。最多支持7层(包括Root Hub在内)。
核心要点:USB总线中,所有通信都由Host发起。设备从不主动说话。这一点和I2C、SPI都不一样。
我画了一张图,帮你快速建立整体认知:
1.2 USB主机与设备角色
USB系统里只有两种角色:Host(主机)和Device(设备)。没有对等通信,没有主从切换。Host永远是老大。
1.2.1 主机(Host)
- 谁当Host?PC、笔记本电脑、手机(OTG模式下)、开发板(如i.MX、STM32MP1)
- Host干什么?检测设备插入/拔出、管理总线供电、分配地址、发送请求、调度传输
- Host的核心硬件:Host Controller(如EHCI、xHCI),负责把软件请求转成USB总线信号
我的经验:调试枚举失败时,第一步永远是确认Host侧是否检测到了设备插入。用逻辑分析仪抓D+、D-电平变化,比看软件日志靠谱得多。
1.2.2 设备(Device)
- 谁当Device?U盘、鼠标、键盘、传感器、嵌入式从设备
- 设备干什么?响应Host的请求、报告自身能力(通过描述符)、传输数据
- 设备的核心硬件:USB Device Controller(如STM32的USB IP、Cypress FX2)
| 对比项 | Host(主机) | Device(设备) |
|---|---|---|
| 通信发起 | 主动发起所有事务 | 被动响应 |
| 供电角色 | 提供VBUS电源(5V) | 从VBUS取电 |
| 地址分配 | 分配唯一地址(1-127) | 接收地址 |
| 时钟源 | 提供SOF(帧起始)包 | 同步SOF |
| 典型硬件 | EHCI/xHCI控制器 | USB Device IP核 |
1.3 USB物理层信号与电气特性
搞懂物理层,你才能看懂示波器上的波形。USB用一对差分信号线(D+和D-)传输数据,再加上VBUS(5V电源)和GND。
1.3.1 信号线定义
- VBUS:5V电源线,Host提供,设备取电。最大电流:USB 2.0为500mA,USB 3.0为900mA
- D+:差分数据正极
- D-:差分数据负极
- GND:地线
1.3.2 差分信号与电平标准
USB用差分信号传输,抗干扰能力强。说白了,就是看D+和D-的电压差来判断是1还是0。
| 信号状态 | D+电平 | D-电平 | 说明 |
|---|---|---|---|
| J状态(Idle) | 高(>2.8V) | 低(<0.3V) | 全速/高速设备空闲时 |
| K状态 | 低 | 高 | 与J状态相反 |
| SE0 | 低 | 低 | 复位信号、包结束(EOP) |
| SE1 | 高 | 高 | 非法状态,不应出现 |
我曾经踩过的坑:有一次设备枚举总是失败,抓波形发现D+和D-在复位后一直保持SE0。查了半天,原来是Device端的上拉电阻没焊好。Host检测不到设备插入,自然不会继续枚举。记住:全速设备在D+上拉1.5kΩ,低速设备在D-上拉1.5kΩ。
1.3.3 速度识别机制
USB设备插入后,Host怎么知道它是什么速度?靠的就是D+或D-上的上拉电阻。
- 低速(1.5 Mbps):设备在D-线上拉1.5kΩ到3.3V
- 全速(12 Mbps):设备在D+线上拉1.5kΩ到3.3V
- 高速(480 Mbps):设备先以全速模式上拉D+,然后通过Chirp握手协商切换到高速
你想想看,Host检测到D+或D-被拉高,就知道有设备插入了。然后开始复位总线、分配地址、读取描述符——这就是枚举的起点。
1.3.4 电气特性关键参数
| 参数 | 低速 | 全速 | 高速 |
|---|---|---|---|
| 数据速率 | 1.5 Mbps | 12 Mbps | 480 Mbps |
| 驱动电压 | 3.3V | 3.3V | 400mV(差分) |
| 终端电阻 | 无 | 无 | D+/D-各对地45Ω |
| 上拉电阻位置 | D- | D+ | D+(初始) |
| 电缆最大长度 | 3m | 5m | 5m |
1.4 枚举的起点:设备插入检测
把上面这些串起来,你就知道枚举的第一步发生了什么:
- 设备插入,VBUS上电
- 设备通过上拉电阻拉高D+(全速)或D-(低速)
- Host的Root Hub检测到D+/D-电平变化
- Host通知USB驱动程序:有新设备
- Host发送复位信号(SE0持续至少10ms)
- 设备在复位结束后进入默认地址0状态
- 枚举正式开始...
记住这个流程。枚举失败排查,90%的问题出在前三步:VBUS没电、上拉电阻没焊、D+/D-接反。我每次接手一个新板子,第一件事就是用示波器量这四根线。