2、USB基础概念:USB总线拓扑结构、传输速率标准、电气特性与线序、供电与枚举流程概述
USB(Universal Serial Bus,通用串行总线)自1996年问世以来,已从最初替代串口/并口的低速外设接口,演变为涵盖存储、显示、供电、音视频传输乃至设备扩展坞的综合性总线标准。要真正掌握USB协议与HID/CDC设备开发,首先必须建立对USB物理世界与逻辑世界的整体认知。本章将围绕四大核心基础展开:总线拓扑结构(谁在控制谁)、传输速率标准(跑多快)、电气特性与线序(物理上怎么连)、供电与枚举流程(设备如何被识别与驱动)。这些内容不仅是后续章节(如端点配置、描述符编写、类协议实现)的基石,也是实际硬件调试中排查“设备无法识别”“供电不足”“速率异常”等问题的第一现场。
上图从宏观层面展示了USB系统的核心架构:主机(Host)通过根集线器(Root Hub)管理所有下行端口,外部集线器(Hub)允许设备以级联方式扩展连接,最终挂载各类功能设备(如HID鼠标、CDC串口、U盘)。同时,图中也标注了供电电压、电流限制以及枚举流程的七个关键步骤。接下来,我们将逐一深入这些基础概念。
2.1 USB总线拓扑结构:主从架构与层级扩展
核心原理:严格的主从控制模型
USB总线采用星型+级联的拓扑结构,与以太网的网状或I2C的多主总线有本质区别。整个总线系统中,唯一的主机(Host)负责发起所有事务(Transaction),所有设备(Device)只能被动响应主机的请求,设备之间无法直接通信。这种设计极大地简化了设备端的逻辑复杂度,但也意味着所有数据交换都必须经过主机调度。
拓扑结构的关键层级如下:
- 主机(Host):通常为PC、手机SoC或嵌入式MCU(如STM32、i.MX RT)。主机内部包含主机控制器(Host Controller)和根集线器(Root Hub)。主机控制器负责协议层处理,根集线器提供物理端口。
- 集线器(Hub):用于扩展端口数量。USB规范允许最多7层级联(含根集线器),但受限于信号衰减和延迟,实际工程中建议不超过5层。每个Hub的上行端口(Upstream Port)连接主机或上级Hub,下行端口(Downstream Port)连接设备或下级Hub。
- 功能设备(Function Device):即具体的USB外设,如键盘、鼠标、串口转换器、U盘等。每个设备在枚举后会被分配一个唯一的7位地址(地址0为默认地址,用于枚举阶段)。
判断方法:识别设备层级与地址分配
在实际调试中,通过主机端的设备管理器(Windows)或lsusb(Linux)可以清晰看到设备的拓扑层级。例如在Linux下执行:
# 查看USB设备树
$ lsusb -t
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/6p, 5000M
|__ Port 3: Dev 2, If 0, Class=Hub, Driver=hub/4p, 5000M
|__ Port 1: Dev 3, If 0, Class=Human Interface Device, Driver=usbhid, 12M
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/12p, 480M
|__ Port 5: Dev 4, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
上述输出中,Dev 1是根集线器,Dev 2是外部Hub,Dev 3和Dev 4是最终功能设备。注意12M表示该设备运行在全速模式(12Mbps),而5000M表示USB 3.0超速模式。通过该命令可以快速判断设备是否因Hub级联过深而无法识别。
案例拆解:多设备级联导致枚举失败
背景:某工业数据采集终端使用STM32H743(内置USB 2.0高速OTG)作为主机,需要同时挂载一个4G模块(CDC类)、一个条码扫描枪(HID类)和一个U盘(Mass Storage类)。工程师将三个设备直接通过一个4口Hub连接至MCU。
现象:上电后,U盘可以识别,但4G模块和扫描枪间歇性无法枚举,有时甚至导致整个USB总线挂死。
分析过程:
- 首先检查Hub供电:该Hub为总线供电,输入电流500mA,但4G模块瞬态发射时峰值电流可达800mA,导致VBUS电压跌落至4.2V,低于USB规范要求的4.75V最低值。
- 其次检查拓扑层级:MCU根端口→Hub→设备,仅2层,排除级联过深问题。
- 使用USB分析仪抓取枚举过程,发现设备在获取描述符阶段(Get Descriptor)时,主机返回
STALL或超时,原因是电压跌落导致设备内部逻辑复位。
解决方案:将Hub更换为自供电模式(外接5V/2A电源适配器),并在Hub的每个下行端口增加470μF的电解电容进行储能。修改后,所有设备稳定运行。
复盘经验:USB拓扑设计不仅仅是“插上就能用”,必须计算端到端功耗预算。对于总线供电的Hub,其下行端口总输出电流不能超过上行端口输入电流(通常为500mA)。在工业场景中,强烈建议使用自供电Hub,并预留至少20%的电流裕量。
2.2 传输速率标准:从1.5Mbps到40Gbps的演进
核心原理:速率等级与编码方式
USB标准经历了多个版本迭代,每个版本定义了不同的物理层速率和编码方案。理解速率等级是选择MCU型号和设计PCB的关键依据。
| USB版本 | 速率名称 | 信号速率 | 编码方式 | 典型应用 |
|---|---|---|---|---|
| USB 1.0/1.1 | 低速 (LS) | 1.5 Mbps | NRZI + 位填充 | 鼠标、键盘、游戏手柄 |
| USB 1.1 | 全速 (FS) | 12 Mbps | NRZI + 位填充 | 音频、CDC虚拟串口、HID |
| USB 2.0 | 高速 (HS) | 480 Mbps | NRZI + 位填充 + 扰码 | U盘、USB摄像头、移动硬盘 |
| USB 3.x | 超速 (SS/SS+/SSP) | 5/10/20 Gbps | 8b/10b (Gen1), 128b/132b (Gen2) | SSD、扩展坞、视频采集 |
值得注意的是,USB 2.0高速模式(480Mbps)与全速模式(12Mbps)在物理层信号特性上完全不同。高速模式引入了额外的 chirp 握手序列(K/J信号交替),用于在设备连接时协商速率。如果设备不支持高速,则回退到全速模式。对于HID和CDC类设备,绝大多数场景使用全速(12Mbps)即可满足需求,因为HID报表数据量小,CDC虚拟串口通常波特率不超过921600bps(约0.92Mbps)。
判断方法:通过设备描述符识别速率
在枚举过程中,主机通过读取设备描述符的bcdUSB字段(例如0x0200表示USB 2.0)和bMaxPacketSize0字段(端点0最大包大小)来初步判断设备能力。但更直接的速率判断依据是物理层握手结果:
- 设备上拉D+(全速/高速)或D-(低速)电阻(1.5kΩ至3.3V)。
- 主机检测到上拉后,开始复位(SE0状态)并发送 chirp 信号。
- 若设备在复位期间检测到 chirp K-J 序列,则进入高速模式;否则保持全速/低速。
在嵌入式开发中,可以通过读取MCU的USB控制器状态寄存器(如STM32的OTG_FS_HOST_PORT寄存器中的PSPD位)来确认当前连接速率。
案例拆解:CDC设备在高速Hub下枚举为全速
背景:某物联网网关使用USB 2.0高速Hub(TUSB8041)连接多个设备,其中一个CDC虚拟串口模块(基于FT232R)始终以全速(12Mbps)运行,而非高速(480Mbps)。
分析:FT232R芯片本身是全速USB 2.0设备,不支持高速模式。尽管Hub支持高速,但设备与Hub之间的链路速率由设备能力决定。这是正常现象,并非故障。
结论:对于CDC类设备,全速模式完全足够。若需要更高吞吐量(如超过1Mbps的串口数据),应选择支持高速的USB转串口芯片(如FT2232H、CH343),并确保MCU的USB控制器也支持高速。
2.3 电气特性与线序:物理层的硬约束
核心原理:差分信号与电平标准
USB 2.0及以下版本使用半双工差分信号传输数据,由D+和D-两根线组成差分对。差分信号具有抗共模干扰、减少电磁辐射(EMI)的优点。关键电气参数如下:
- 静态电平:空闲时,D+和D-均为低电平(0V)。设备通过上拉电阻(1.5kΩ)将D+(全速/高速)或D-(低速)拉高至3.3V,以向主机表明设备已连接及其速率等级。
- 差分信号摆幅:全速/低速模式下,差分信号幅度约为3.3V(高电平)和0V(低电平);高速模式下,信号摆幅降低至约400mV(差分),以减少功耗和EMI。
- 终端匹配:高速模式下,D+和D-对地各接45Ω电阻(等效90Ω差分阻抗);全速/低速模式下,主机端有15kΩ下拉电阻,设备端有1.5kΩ上拉电阻。
标准USB线序(A型连接器)如下:
| 引脚编号 | 信号名称 | 线缆颜色(典型) | 功能说明 |
|---|---|---|---|
| 1 | VBUS | 红色 | +5V电源,最大500mA(USB 2.0)/900mA(USB 3.0) |
| 2 | D- | 白色 | 差分数据负端 |
| 3 | D+ | 绿色 | 差分数据正端 |
| 4 | GND | 黑色 | 电源地 |
判断方法:用万用表/示波器检测线序与信号
在硬件调试中,经常需要确认线序是否正确。使用万用表二极管档测量VBUS对GND的电压应为5V左右;测量D+或D-对GND的电压,若设备已连接且为全速,D+应为3.3V左右(被上拉),D-应为0V。若使用示波器观察,在设备枚举期间,D+/D-上会出现约几百毫伏的差分信号脉冲。
对于USB 3.x,其线序更为复杂,包含一对超速发送(SSTX+/-)、一对超速接收(SSRX+/-)以及兼容USB 2.0的D+/D-。USB 3.0 Type-A连接器增加了5个引脚(共9个),引脚定义如下:
- Pin 1: VBUS
- Pin 2: D-
- Pin 3: D+
- Pin 4: GND
- Pin 5: SSTX-
- Pin 6: SSTX+
- Pin 7: GND_DRAIN
- Pin 8: SSRX-
- Pin 9: SSRX+
案例拆解:自制USB线导致设备无法识别
背景:某创客项目需要定制一根长度1.5米的USB线缆,用于连接自制的HID键盘(基于STM32F103)。工程师手工焊接了A型公头到Type-C公头的线缆。
现象:插入电脑后,系统提示“无法识别的USB设备”,且设备管理器中出现黄色感叹号。
排查过程:
- 用万用表测量VBUS和GND,电压正常5.0V。
- 测量D+和D-对GND电压,发现D+为0V,D-为0V,说明设备的上拉电阻未生效或线序接反。
- 拆开线缆检查,发现D+和D-两根线在焊接时交叉接反(D+接到了D-焊盘,反之亦然)。
解决:重新焊接,确保D+(绿色)连接到连接器的D+引脚,D-(白色)连接到D-引脚。重新插入后,设备正常枚举。
复盘:USB线序错误是DIY硬件中最常见的低级错误。建议在焊接前使用万用表蜂鸣档逐一验证连接器引脚与线缆另一端的导通关系,并做好标记。
2.4 供电与枚举流程概述:设备从插入到就绪的旅程
核心原理:供电机制与状态机
USB供电分为总线供电(Bus-Powered)和自供电(Self-Powered)两种模式。总线供电设备从VBUS获取电能,但必须遵守电流限制:
- 设备在枚举完成前,最多只能从VBUS抽取100mA(USB 2.0)或150mA(USB 3.0)。
- 枚举完成后,设备通过配置描述符中的
bMaxPower字段声明所需电流(以2mA为单位),主机根据Hub的供电能力决定是否批准。若请求超过Hub剩余供电能力,主机将拒绝配置。
枚举流程是USB设备开发中必须透彻理解的核心机制。它本质上是主机与设备之间的一系列标准控制传输(Control Transfer),通过端点0(默认控制端点)完成。完整流程如下:
- 设备插入与检测:设备上拉D+或D-,主机检测到电平变化,认为有新设备连接。
- 复位(Reset):主机向该端口发送复位信号(SE0,即D+和D-同时拉低至少10ms)。设备检测到复位后,恢复至默认状态(地址0,端点0可用)。
- 分配地址(Set Address):主机发送
SET_ADDRESS请求,设备收到后分配一个唯一地址(1~127),并返回状态阶段。 - 读取设备描述符(Get Descriptor):主机发送
GET_DESCRIPTOR请求,读取设备描述符(18字节),获取USB版本、设备类、端点0最大包大小等信息。 - 读取配置描述符(Get Configuration Descriptor):主机读取配置描述符及其关联的接口描述符、端点描述符。此过程可能分多次读取(第一次读取前9字节获取总长度,第二次读取完整描述符集)。
- 设置配置(Set Configuration):主机发送
SET_CONFIGURATION请求,设备根据配置值(通常为1)进入工作状态,此时设备可以开始正常数据传输。 - 加载驱动:主机根据接口描述符中的类代码(如0x03为HID,0x0A为CDC)加载相应驱动程序。对于CDC设备,通常需要安装虚拟串口驱动(如usbser.sys或VCP驱动)。
bMaxPacketSize0字段必须正确设置。全速设备通常为64字节,低速设备为8字节。如果该值错误,主机可能无法正确解析后续描述符,导致枚举失败。此外,设备必须在收到SET_CONFIGURATION请求后才允许在非控制端点上传输数据,否则主机将忽略或拒绝。
判断方法:通过USB分析仪抓取枚举过程
当设备无法被识别时,使用USB协议分析仪(如Beagle USB 480、Total Phase)或逻辑分析仪抓取D+/D-上的信号,可以精确定位故障环节。以下是一个典型的