1. USB协议基础:总线架构、角色与电气特性

做嵌入式USB开发,第一件事不是翻数据手册,而是搞明白USB到底是怎么连的、谁说了算、信号长什么样。我见过不少工程师,上来就调端点、配描述符,结果枚举死活过不去——最后发现是D+、D-两根线焊反了。嗯,基础不牢,后面全是坑。

1.1 USB总线架构:树形拓扑与分层结构

USB总线是典型的树形拓扑。一个Host(主机)下面挂一个Root Hub,Root Hub下面可以接Hub,Hub再接设备。最多支持7层(包括Root Hub在内)。

核心要点:USB总线中,所有通信都由Host发起。设备从不主动说话。这一点和I2C、SPI都不一样。

我画了一张图,帮你快速建立整体认知:

USB 总线树形拓扑结构 USB Host(主机) Root Hub Hub 1 Hub 2 Hub 3 Device A Device B Device C Device D 说明: • 主机(Host)是唯一的主控者,所有事务由Host发起 • Hub用于扩展端口,最多支持7层级联(含Root Hub) • 设备(Device)是被动响应方,不能主动发送数据

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 枚举的起点:设备插入检测

把上面这些串起来,你就知道枚举的第一步发生了什么:

  1. 设备插入,VBUS上电
  2. 设备通过上拉电阻拉高D+(全速)或D-(低速)
  3. Host的Root Hub检测到D+/D-电平变化
  4. Host通知USB驱动程序:有新设备
  5. Host发送复位信号(SE0持续至少10ms)
  6. 设备在复位结束后进入默认地址0状态
  7. 枚举正式开始...

记住这个流程。枚举失败排查,90%的问题出在前三步:VBUS没电、上拉电阻没焊、D+/D-接反。我每次接手一个新板子,第一件事就是用示波器量这四根线。