news 2026/7/17 5:40:28

USB协议介绍及使用(基于STM32)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
USB协议介绍及使用(基于STM32)

一、USB协议介绍

1、概述

(1)USB是“Universal Serial Bus Specification”的缩写,是一种主从协议,支持多个从机,所有传输都由主机发起。

(2)USB的硬件线数与串口一致(VCC、GND、D+、D-),USB将数据线作为差分线。

(3)不管是哪种通信协议,都有通用的要求,USB协议也是如此,具体要求如下:

①位数据的传输由时钟信号驱动。

②数据帧至少具有开始标识、数据段和结束标识三部分。

③如果要求可靠传输,则数据帧必须具备校验字段。

2、USB协议硬件电路

(1)USB设备分为低速、全速和高速三种。

①USB高速/全速设备标准原理图:

[1]主机/Hub端:D+、D-各内置15kΩ的下拉电阻到GND。

[2]设备端:D+内置1.5kΩ的上拉电阻到VCC;USB收发器为Full-speed USB Transceiver,斜率缓冲为标准速率(电平跳变边沿变化快)。

[3]线缆差分阻抗为90Ω。

[4]有USB设备接入主机时,D+被上拉到高电平,D-保持低电平,主机能够判断有设备接入,且是高速/全速设备。

②USB低速设备标准原理图:

[1]主机/Hub端:D+、D-各内置15kΩ的下拉电阻到GND。

[2]设备端:D-内置1.5kΩ的上拉电阻到VCC;USB收发器为Low-speed USB Transceiver,带低速斜率缓冲(电平跳变边沿变化平缓,能够降低EMI干扰)。

[3]线缆差分阻抗为90Ω。

[4]有USB设备接入主机时,D-被上拉到高电平,D+保持低电平,主机能够判断有设备接入,且是低速设备。

③USB收发器:

[1]USB收发器是MCU内部或外部芯片里处理D+/D-差分电平的模拟硬件模块,负责把内部数字比特流转换成USB差分J/K/SE0总线电平,输出到D+/D-,同时也负责采D+/D-差分电压,将总线上的比特信号还原给内核。

[2]USB收发器内置差分曼彻斯特编码/解码硬件,可以自动识别SOP/EOP时序。

(2)USB协议采用差分信号,即D+、D-两线电压差区分总线状态,一共有4种静态组合:

总线状态

指示

差分1

D+为高电平,D-为低电平

差分0

D+为低电平,D-为高电平

单端0(SE0)

D+和D-为低电平

单端1(SE1)

D+和D-为高电平

(3)USB协议定义了J状态和K状态,用于屏蔽不同速度模式的区别,为免异义,下面如无特殊说明,都以高速USB2.0为标准进行介绍。

速度模式

J状态

K状态

低速USB1.1

差分0

差分1

全速USB1.1

差分1

差分0

高速USB2.0

差分1

差分0

①总线长期保持J状态,代表没有数据传输。

②总线长时间(超过10ms)处于SE0状态,主机将下发复位指令,设备重启USB控制器。

③总线保持K状态一段时间(也称为恢复状态),将唤醒休眠的USB设备。

④总线如果处于SE1状态,说明发生硬件故障。

(4)USB的比特传输:

①USB采用差分曼彻斯特编码:传输比特0,比特中间位置发生J→K状态翻转,传输结束后发送K→J状态翻转;传输比特1,比特中间位置发生不发生J/K状态翻转,保持J状态。

②接收方可以从比特0的跳变处提取时钟信号,不用单独拉时钟线,实现自同步。

②与CAN协议类似,USB协议也有位填充机制,如果连续发送6个比特1,硬件会强制插入一个比特0,制造一次跳变,以同步时钟,另外USB收发器会自动识别这个填充位并剔除,上层数据帧格式无需关注。

3、USB协议的帧格式

(1)数据帧第一层传输格式封装:

①SOP:数据帧的起始标志。总线空闲时处于J状态,当要传输数据时,总线先切换到K状态,这个J→K的跳变就是SOP,接收方识别到这段时序,判定数据帧传输开始。

②DATA:USB不硬性规定数据包的长度,数据包格式将在下一层封装中展开。

③EOP:数据帧的结束标志。数据包传输完成后,总线保持两个bit时长的SE0状态,然后切换到J状态保持一个bit的时长,接收方识别到这段时序,判定数据帧传输完毕。

(2)数据帧第二层传输格式封装:

①PID(Packet ID):包类型标识,长度为8bit,低4位为高4位取反。

②Packet:根据PID的不同,数据帧格式会有差异,具体将在下一层封装中展开。

(3)数据帧第三层传输格式封装:

①令牌PID:只能由主机发送,是总线调度的核心,主要用于发起一次数据传输,并指定读或写。

IN:主机要求从设备上传数据,使用该令牌

OUT:主机要下发数据给从设备,使用该令牌

SETUP:控制传输专用,主机配置从设备的参数、枚举

ADDR:从机设备地址,长度为7bit

EP:端点,指明本次数据传输使用的端点通道,长度为4bit

CRC5:使用CRC5根据PID+ADDR+EP计算而得的校验码,长度为4bit,如果CRC校验不通过,接收端会丢弃数据帧

②特殊PID:主机定时广播(1ms发送一次),同步总线时序。

SOF:所有设备都会接收SOF

FRAME:帧计数器FrameNumber,长度为11bit(0~2047循环使用)

CRC5:使用CRC5根据PID+FRAME计算而得的校验码,长度为4bit,如果CRC校验不通过,接收端会丢弃数据帧

③握手PID:只能由从机回复主机时发送,从设备收到令牌或数据后,回复主机传输状态,用于传输应答。

ACK:从机回复积极响应,表示数据传输可继续进行

NAK:从机回复消极响应,表示暂时忙(无法处理数据)或无数据(主机请求的数据不存在),数据传输暂时无法进行,需要等待从机一段时间

STALL:从机回复端点出错,传输停止,需要主机重置

④数据PID:主机和从机都可发送,用于承载上层业务数据,紧跟在令牌包后面出现。

DATA0:上一个发送数据包的PID为DATA1,那么本次发送数据包的PID为DATA0,数据接收方根据数据PID判断是否存在丢包的情况

DATA1:上一个发送数据包的PID为DATA0,那么本次发送数据包的PID为DATA1,数据接收方根据数据PID判断是否存在丢包的情况

Payload:数据载荷,长度不定

CRC16:使用CRC16根据PID+Payload计算而得的校验码,长度为16bit,如果CRC校验不通过,接收端会丢弃数据帧

4、USB设备的通信方式

(1)端点EndPoint的概念:

①端点是USB设备内部独立的收发缓存通道,编号0~15,也就是说一个设备最多可用16个通道,主机根据设备地址和端点号,就能锁定总线上某设备的某一条专用数据通道。

②EP0是控制端点,只能用于控制传输,设备上电后,主机只通过EP0和设备通信,使用SETUP令牌包完成设备识别、参数配置等。

③EP1~EP15是自定义端点,每个端点可以绑定中断传输、批量传输、同步传输中的一种传输类型,用于传输业务数据。

④端点区分IN方向和OUT方向,一个端点编号同时存在IN、OUT两条独立通道,由令牌PID决定读写方向。主机读设备,设备通过IN端点上传数据;主机写设备,主机通过OUT端点下发数据。

(2)USB的四大传输类型:

①控制传输:唯一绑定EP0端点,用于设备枚举、配置、查询设备描述符、复位端点,所有USB设备强制支持,数据帧出错会自动重传。设备上电后,主机通过EP0端点发送SETUP令牌,设备回应后,主机可以读取设备的描述符,识别设备类型,加载对应的驱动。

②中断传输:主机按固定周期定时发IN令牌,设备有数据则回复ACK,并将数据上报主机,无数据则回复NAK,数据帧出错会自动重传。(适用于鼠标、键盘、按键这类周期性少量上报设备)

③批量传输:总线空闲时,主机持续发送IN令牌和OUT令牌,尽可能地占用总线带宽(带宽优先级低于同步传输和中断传输),设备有数据则回复ACK,并将数据上报主机,无数据则回复NAK,数据帧出错会自动重传。(适用于U盘、虚拟串口、固件下载等)

④同步传输:主机每隔1ms(发送一次SOF帧,设备有数据则上报主机,无数据则不回复。不同于中断传输的是,同步传输无ACK机制,允许少量丢包,数据帧出错不重传,并且带宽优先级高于批量传输和中断传输。(适用于音频、摄像头、喇叭这类可接受不可靠传输的设备)

(3)USB设备地址:

①USB是主从架构,只有1个主机,多个从设备共享一条总线,总线所有信号广播发送,主机靠ADDR区分目标设备,目标设备靠ADDR判断是否需要处理该信号。

②每个从设备上电枚举后,主机会为其分配唯一的地址(范围为1~127)。

(4)USB设备的描述符:

①下图是USB设备所有描述符的层级从属结构示例,主机在枚举时通过EP0控制传输逐级读取这套描述符,才能识别设备功能、分配驱动、打开对应端点通道。

②Device Descriptor设备描述符:

一个USB设备只有1个设备描述符,是主机需要读取的第一个描述符

设备描述符存放全局基础信息,如USB协议版本、厂商ID VID、产品ID PID、设备版本号,主机获取VID/PID以去系统匹配对应的驱动,另外全局基础信息还有设备EP0支持的最大包长度、设备支持的配置Configuration种数(上图所示的示例中,有两套配置)

③Configuration Descriptor配置描述符:

一个USB设备可以做多套硬件配置,主机上电后只能激活其中一套配置

每套配置包含的信息有配置的总功耗、是否能自供电、该套配置包含多少接口

④Interface Descriptor接口描述符:

接口描述符依附在配置下,一套配置里可以包含多个接口,对应不同的功能

接口描述符记录接口编号、备用设置号、设备的类及子类、使用的协议,以及接口下包含多少端点

⑤Endpoint Descriptor端点描述符:

端点描述符依附在接口下,每个业务端点对应一张端点描述符(EP0没有端点描述符)

端点描述符包含核心传输参数,如端点地址(EP号+IN/OUT方向)、传输类型(中断/批量/同步)、单次最大数据包长度、中断轮询间隔(中断传输专用),主机读取后就知道,访问这个端点该用哪种传输方式、一次最多传多少数据

二、STM32中的USB外设

1、USB外设简介

(1)STM32内置USB从控制器,支持USB全速通信,符合USB2.0技术规范。

(2)STM32F103的USB模块实现了标准USB接口的所有特性,它由串行接口控制器(SIE)、定时器、分组缓冲器接口、端点相关寄存器、控制寄存器和中断寄存器等部分组成。

(3)STM32F103C8T6的硬件USB资源只有USB1,本文基于STM32F103C8T6进行USB外设的介绍。

2、USB外设的数据传输

(1)USB数据传输通过一个专用的数据缓冲区来完成,它能被USB外设直接访问,其大小由所使用的端点数目和每个端点最大数据分组大小所决定。

(2)每个端点最大可使用512字节缓冲区(和CAN外设共用一个专用的512字节SARM存储器,也就是说USB外设和CAN外设不能同时使用),最多可用于16个单向端点或8个双向端点。

(3)USB模块同PC主机通信,根据USB规范实现了令牌分组的检测、数据发送/接收的处理、握手分组的处理,整个传输的格式由硬件完成,其中包括CRC的生成和校验、位填充机制等,程序只需关心报文数据,而无需关注总线的电平细节。

3、USB框图

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 5:39:16

零基础学 Python 第12章 | 文件读写:让数据持久保存

本章摘要 核心目标:掌握文件读取与写入,让程序的数据能保存到磁盘并重新加载核心知识点:open() 函数、r/w/a 三种模式、read/readline/readlines、write/writelines、with 上下文管理器、文件路径实操产出:日记本程序&#xff0c…

作者头像 李华
网站建设 2026/7/17 5:36:36

ModBus协议总结

ModBus协议总结ModBus协议总结RTU1 线圈设备读写2 读取离散值3 保持寄存器读写 通过功能码 03 06 16(0x10)功能码06功能码16读取输入寄存器数值TCPModBus协议总结 RTU 总结modbus协议的通信和处理,首先明确同种通信方式TCP和串口(RTU)的区别…

作者头像 李华
网站建设 2026/7/17 5:36:30

Python GUI实战:用Tkinter、PyQt5和Pygame分别实现五子棋游戏

1. 项目概述:为什么用Python做五子棋GUI是个好主意?如果你对Python编程已经入门,掌握了基础语法,想找一个能串联起多个知识点的综合实战项目,那用Python实现一个带图形界面的五子棋游戏,绝对是个绝佳的选择…

作者头像 李华
网站建设 2026/7/17 5:36:05

Windows 11第二任务栏功能解析与优化指南

1. Windows 11任务栏的进化与第二任务栏功能解析Windows 11的任务栏设计一直是用户关注的焦点。微软在最新更新中引入的第二任务栏功能,实际上是对用户多年需求的回应。这个功能并非简单的界面叠加,而是基于Windows Shell Experience Host的深度改造。传…

作者头像 李华
网站建设 2026/7/17 5:35:45

AI+菌株设计的“伪AI“识别清单:3个月量化验证红线

写在前面:一个老兵的观察 我做了30多年生物合成产业,从摇瓶做到千吨级发酵罐产线,从拍脑袋优化做到数字化控制。最近三四年,"AI菌株设计"的标签几乎贴满了每一个融资BP和展会海报。我见过真正改变游戏规则的AI工具&…

作者头像 李华
网站建设 2026/7/17 5:35:04

C++输出流格式化难题:从std::cout到声明式格式化工具的实现

1. 项目概述:从“凑合能用”到“精准优雅”的格式化之路在C的日常开发里,尤其是处理日志输出、数据报告或者调试信息时,std::cout是我们最熟悉的老朋友。但不知道你有没有过这样的体验:想输出一个浮点数,只保留两位小数…

作者头像 李华