usb通讯——读《圈圈教你玩usb》

本文详细解读了USB协议中的IN和OUT数据传输、NRZI编码在同步问题上的解决方案,以及USB枚举过程中的控制传输、数据包结构和不同类型的USB事务(批量、中断、同步和控制)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 关键概念

1.1 IN和OUT

这两个参数的主对象都是主机。IN和OUT都是主机发起的(通过令牌包)。

IN:主机发送IN令牌包告诉设备要取数据。然后从机将发送数据放到IN缓冲区,主机从IN缓冲区接收数据;

OUT:主机发送OUT令牌包告诉设备要发送数据。然后主机将数据放到OUT缓冲区,从机在OUT缓冲区取数据;

1.2 NRZI编码

NRZI:No Return Zero-Inverse 非归零反相编码。

编码后电平只有正负电平之分,没有零电平,是不归零编码。

在传输中,同步头SYNC为00 01H,15个翻转信号。

但是当传输连续的逻辑1位时,NRZ-I编码后,将保持上一次翻转后的状态。这使得接收端无法从中得到同步信号。为此,USB协议规定:如果要发送的数据中出现有连续的6个1,则在进行NRZI编码前,在这6个连续的1后面会插入1个0,然后再进行NRZI编码。接收端收到连续6个1,将自动去掉后面的1个0。从而恢复原数据。包数据传送多个1的处理。这样就使得USB通信的接收同步更加可靠。

2. usb枚举过程

2.1 控制传输

枚举过程都是用的控制传输,可以保证数据的正确性。 控制传输可以分为三个步骤。

  • 建立过程:开始于一个SETUP令牌包,后面跟一个DATA0数据包,然后就是数据过程;
  • 数据过程:分为控制读传输(输入数据)和控制写过程(输出数据);建立过程指定数据长度为0则没有数据过程;
  • 状态过程:数据传输方向与数据过程相反;

2.2 枚举详细过程

  • 检测到设备插入,复位设备;然后主机往地址0的设备端点0请求设备描述符(标准是18个字节),如果设备的端点0不够18个字节,主机只获取第一包(至少8字节)数据即可;
  • 主机对设备再次复位,进入设置地址阶段;地址由主机管理,每个设备会有一个唯一的地址;
  • 主机再次获取设备描述符,这次使用设备地址访问设备,并且需要获取完整的设备描述符(即18个字节);
  • 主机获取配置描述符,配置描述符总共9个字节;配置描述符主要记录信息:配置所包含的接口数,配置的编号,供电方式,是否支持远程唤醒,电流需求量等;

3. USB包结构及传输过程

USB数据发送到总线上时,先经过位填充,再经过NRZI编码。

传输数据时:电平翻转表示0,电平不翻转表示1;

全速或低速设备的包结束符EOP——SE0,D+和D-都保持为低电平,用来表示特殊的意义(如包结束,复位信号等)。 包标识符PID表示一个包的类型。总共8位,后4位(PID4~7)是对前4位取反,用来校验前4位(PID0~PID3)。

3.1 令牌包(token packet,PID1~0为01)

用来启动一次usb传输。有4种。

  • 输出OUT——OUT包的结构:同步域-8位包标识PID-7位地址-4位端点号-5位CRC5校验-EOP。
  • 输入IN——IN包的结构与OUT包一样。
  • 建立SETUP——SETUP包结构与OUT包一样。
  • 帧起始包SOF(start of frame)——SOP的结构:同步域-8位包标识PID-11位帧号-5位CRC5校验-EOP。

3.2 数据包(data packet,PID1~0为11)

  • USB1.1协议中只有DATA0和DATA1两种包。
  • USB2.0增加了DATA2和MDATA包,主要用在高速分裂事务和高速高带宽同步传输中。
  • 数据包结构:同步域-8位包标识PID-字节0~字节N-16位CRC16校验值-EOP。
  • 不同的数据包(DATA0,DATA1...)用在当握手包出错时纠错。

3.3 握手包(handshake packet,PID1~0为10)

握手包用来表示一个传输是否被对方确认。

握手包结构:同步域-PID-EOP

握手包有4种。

  • ACK 表示正确接收数据,并且有足够的空间来容纳数据。主机和设备都可以用ACK来确认。 其它三个握手包只能只能设备返回。
  • NAK 表示没有数据需要返回。或者数据正确接收但没有足够空间容纳它们。 主机收到NAK,会在以后合适时机重试传输。
  • STALL 表示设备无法执行这个请求,或者端点已经被挂起,表示一种错误的状态。 设备返回STALL后,需要主机干预才能接触这种状态。
  • NYET 只在USB2.0高速设备输出事务中使用,表示设备本次数据成功接收,但没有足够空间接收下一次数据。 主机在下一次输出数据前,先用PING令牌包试探设备是否有足够空间,避免不必要的带宽浪费。

注意点返回NAK并不表示数据出错,只是说明设备暂时没有数据传输或者暂时没有能力接收数据。 当usb主机或者设备检测到数据出错时(如CRC错误,PID校验错误,位填充错误等),将什么都不返回。 这时等待接收握手包的一方就会收不到握手包从而等待超时

3.4 特殊包(special packet,PID1~0为00)

总共有4种。

  • PRE令牌包 通知集线器打开其低速端口的一种前导包。只使用在全速模式。 与握手包结构一样:同步域-PID-EOP
  • ERR握手包 在分裂事务中表示错误使用。
  • SPLIT令牌包 高速事务分裂令牌包。通知集线器将高速数据包转换为全速或低速数据包发送给下面的端口。 高速分裂事务属于集线器功能,在USB2.0协议中有描述。
  • PING令牌包 与OUT令牌包结构一样:同步域-8位包标识PID-7位地址-4位端点号-5位CRC5校验-EOP。 后面不发送数据。只是为了设备返回ACK或NAK,以确定设备是否能够传输数据。 USB2.0以后才加入PING包。 只用在批量传输和控制传输的输出事务中。 只在高速设备中使用。

4. USB的四种传输类型

USB的传输必须按照一定的关系组织成事务才能传输数据。

USB的事务由两个或三个包组成:令牌包、数据包和握手包。

4.1 批量传输

使用批量事务(bulk transaction)传输数据。分三个阶段:令牌包阶段,数据包阶段,握手包阶段。 批量传输通常用在数据量大,对数据实时性要求不高的的场合。如usb打印机、大容量存储设备。

 

4.2 中断传输

中断端点在端点描述符中要报告它的查询间隔,主机会保证在小于这个时间间隔的范围内安排一次传输。
这里说的中断与硬件的中断不一样,不是设备主动的发生一个中断请求,而是由主机保证不大于某个时间间隔内安排一次传输。

 

4.3 等时传输(又叫同步传输)

  • 通常用在数据量大,对实时性要求高的场合。如音视频数据。
  • 没有应答包,因为数据少量错误无所谓,也不需进行重传。

 

4.4 控制传输

目前所知的使用控制传输的场景就是枚举过程。

控制传输分三个过程:建立过程,可选的数据过程,状态过程。

建立过程使用了一个建立事务,流程图如下:

 

第一章 USB概述及协议基础 1 1.1 USB是什么 1 1.2 USB的特点 1 1.3 USB的拓扑结构 2 1.4 USB的电气特性 5 1.5 USB的线缆以及插头、插座 5 1.6 USB的插入检测机制 7 1.7 USB的描述符及其之间的关系 9 1.8 USB设备的枚举过程 10 1.9 USB的包结构及传输过程 11 1.9.1 USB包的结构及包的分类 11 1.9.2 令牌包 13 1.9.3 数据包 14 1.9.4 握手包 14 1.9.5 特殊包 15 1.9.6 如何处理数据包 15 1.10 USB的四种传输类型 16 1.10.1 USB事务 16 1.10.2 批量传输 16 1.10.3 中断传输 18 1.10.4 等时传输(同步传输) 19 1.10.5 控制传输 20 1.10.6 端点类型与传输类型的关系 21 1.10.7 传输类型与端点支持的最大包长 21 1.11 本章小结 21 第二章 硬件系统设计 1 2.1 方案以及芯片的选定 1 2.2 D12引脚功能说明 2 2.3 D12与89S52的连接 4 2.4 串口部分电路 6 2.5 按键部分 7 2.6 指示灯部分 7 2.7 IDE接口部分 8 2.8 单片机部分 8 2.9 元件安装 8 2.10 电路调试 11 2.11 测试程序的编写和调试 12 2.11.1 建立一个工程 12 2.11.2 为工程添加源文件 14 2.11.3 KEIL工具栏及仿真介绍 15 2.11.4 按键驱动的编写 18 2.11.5 串口驱动的编写 24 2.11.6 PDIUSBD12写函数及ID的实现 28 2.12 本章小结 33 第三章 USB鼠标的实现 1 3.1 USB鼠标工程的建立 1 3.2 USB的断开与连接 1 3.3 USB中断的处理 4 3.4 取从主机发送到端点0的数据 6 3.5 USB标准请求 12 3.5.1 USB标准设备请求的结构 13 3.5.2 GET_DESCRIPTOR请求 15 3.5.3 SET_ADDRESS请求 16 3.5.6 SET_CONFIGURATION请求 16 3.6 设备描述符的实现 17 3.7 设备描述符的返回 20 3.8 设置地址请求的处理 30 3.9 配置描述符集合的结构 32 3.9.1 配置描述符的结构 32 3.9.2 接口描述符的结构 33 3.9.3 端点描述符的结构 33 3.9.4 HID描述符的结构 34 3.10 配置描述符集合的实现以及返回 35 3.11 字符串及语言ID请求的实现 39 3.12 设置配置请求的实现 45 3.13 报告描述符的结构及实现 48 3.14 报告的返回 54 3.15 Bus Hound工具的简介 57 3.16 本章小结 59 第四章 USB键盘的实现 1 4.1 USB键盘工程的建立 1 4.2 设备描述符的实现 1 4.4 配置描述符集合的实现 2 4.4.1 配置描述符 3 4.4.2 接口描述符 3 4.4.3 HID描述符 3 4.4.4 端点描述 3 4.5 字符串描述符 6 4.6 报告描述符 6 4.7 输入和输出报告的实现 10 4.8 USB键盘实例的测试 13 4.9 再谈USB HID的报告描述符 14 4.10 带鼠标功能的USB键盘(方法一) 16 4.11 带鼠标功能的键盘(方法二) 22 4.12 多媒体USB键盘 29 4.13 本章小结 34 第五章 用户自定义的USB HID设备 1 5.1 MyUsbHid工程的建立 1 5.2 描述符的修改 1 5.3 报告的实现 3 5.4 对用户自定义的USB HID设备的访问 5 5.5 访问HID设备时所用到的相关函数 5 5.5.1 获取HID设备的接口类GUID的函数 5 5.5.2 获取指定类的所有设备信息集合的函数 6 5.5.3 从设备信息集合中获取一个设备接口信息的函数 6 5.5.4 获取指定设备接口详细信息的函数 7 5.5.5 打开设备的函数 8 5.5.6 获取HID设备属性的函数 8 5.5.7 从设备取数据的函数 9 5.5.8 往设备写数据的函数 9 5.5.9 通过控制端点0取报告的函数 10 5.5.10 通过控制端点0发送报告的函数 10 5.5.11 关闭设备的函数 10 5.5.12 需要包含的库文件 11 5.6 访问USB HID设备的上位机软件的实现 11 5
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值