USB2.0速度识别

2023-12-27 16:30
文章标签 速度 识别 usb2.0

本文主要是介绍USB2.0速度识别,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

  1312人阅读  评论(0)  收藏  举报

转载自:http://blog.csdn.net/cescf4/article/details/8601457

USB2.0是向下兼容USB1.X的,即USB2.0支持高速,全速,低速的USB设备(HIGH-SPEED,FULL-SPEED,LOW-SPEED),而USB1.X不支持高速设备。因此如果高速设备接在USB1.X的hub上,也只能工作在全速状态。因此对速度的识别是很重要的,否则没办法以想要的速度通信。

全速和低速区分

根据规范,全速和低速很好区分。因为在设备端有一个1.5K的上拉电阻,上电后,有上拉电阻的那根数据线会被拉高,根据 D+或D-的电平状态来检测是全速还是低速设备。如下图:

高速识别


全速,高速的识别比较简单,但是USB2.0,USB1.X只有一对数据线,就没办法有第三种状态来表示高速设备了,所以高速设备的识别稍微复杂。

高速设备是以一个全速设备的身份出现的,即和全速设备一样,高速设备也在D+端有一个1.5K的上拉电阻。USB2.0的HUB把设备当成一个全速设备,然后进行一系列的握手信号来确认双方的身份,一方面HUB要检测设备是高速还是全速,另一方面设备也要检测HUB是USB2.0还是USB1.X的,如果HUB是USB2.0,设备也是高速的 就工作在高速模式,否则只能工作在全速模式。

下图展示了一个高速设备连到USB2.0 hub上的情形:

HUB连接到设备或上电时,向主机报告,主机通过发送Set_port_feature请求让hub复位新插入的设备。设备复位操作是驱动数据线到复位SE0(D+,D-都为低电平),并持续至少10MS。

高速设备复位后,通过内部的电流源向D-持续灌17.78MA大小的电流。因为此时D+端的1.5K上拉电阻还没撤销,在hub端,全速/低速驱动器形成一个45欧姆的终端电阻,两电阻并联约形成45欧姆的阻抗,所以在HUB端可以看到一个 800ma(17.78*45)的电压,这个就是Chirp K信号。Chirp K 的持续时间是 1ms -  7ms.

在HUB端,虽然下达了复位信号,并一直驱动着SE0,但usb2.0的高速接收器一直在检测 Chirp  K信号,如果没有检测到,就继续复位操作,知道复位结束,然后就工作在全速状态。如果只是一个全速的hub,不支持高速设备,那么hub也不会理会Chirp k信号,之后设备也不会切换到高速模式。

如果是高速 HUB,设备在发送的Chirp k信号结束后的100us内,HUB必须回复一连串的KJKJKJ........序列,向设备表明这是一个usb2.0的hub,这里的kj序列式连续的,且不能中断,每个K或J的持续时间是 40us--60us.

再回到设备端,设备检测到6个hub发送的 Chirp信号(3对KJ)后,它必须在500us内切换到高速模式。切换动作有:

 1.断开1.5K的上拉电阻

2. 连接D+/D-上的高速终端电阻(high-speed termination),其实就是全速/低速差分驱动器。

3.进入默认的高速状态

执行完 1,2两步后,USB信号线上看的到现象就发生变化了:HUB发动的 Chirp降到原来的一半,400mv。这是因为设备端挂载新的终端电阻后,并联原来的终端电阻,结果为22.5欧姆,17.78*22.5为 400mv,以后高速设备操作的 信号幅值就是 400mv而不是 全速/低速的 3.3V。

至此高速设备与usb2.0握手完毕,开始进行480Mbps的通信。

转帖,原帖出自: http://hi.baidu.com/doyanger/blog/item/af45d995dd64f419d31b704d.html


USB的描述符及各种描述符之间的依赖关系

USB是个通用的总线,端口都是统一的。但是USB设备却各种各样,例如USB鼠标,USB键盘,U盘等等,那么USB主机是如何识别出不同的设备的呢?这就要依赖于描述符了。

USB的描述符主要有设备描述符,配置描述符,接口描述符,端点描述符,字符串描述符,HID描述符,报告描述符等等。

关于报告描述符,请看:《USB HID报告及报告描述符简介 》

http://group.****.com/93/198.aspx。

 

一个USB设备有一个设备描述符,设备描述符里面决定了该设备有多少种配置,每种配置描述符对应着配置描述符;而在配置描述符中又定义了该配置里面有多少个接口,每个接口有对应的接口描述符;在接口描述符里面又定义了该接口有多少个端点,每个端点对应一个端点描述符;端点描述符定义了端点的大小,类型等等。

 

由此我们可以看出,USB的描述符之间的关系是一层一层的,最上一层是设备描述符,下面是配置描述符,再下面是接口描述符,再下面是端点描述符。在获取描述符时,先获取设备描述符,然后再获取配置描述符,根据配置描述符中的配置集合长度,一次将配置描述符、接口描述符、端点描述符一起一次读回。其中可能还会有获取设备序列号,厂商字符串,产品字符串等。

 

 

每种描述符都有自己独立的编号,如下:

 

#define DEVICE_DESCRIPTOR               0x01 //设备描述符

#define CONFIGURATION_DESCRIPTOR        0x02 //配置描述符

#define STRING_DESCRIPTOR               0x03 //字符串描述符

#define INTERFACE_DESCRIPTOR            0x04 //接口描述符

#define ENDPOINT_DESCRIPTOR             0x05 //端点描述符

 

下面分别详细介绍一下各描述符。

 

1.设备描述符

 

//定义标准的设备描述符结构

 

typedef struct _DEVICE_DCESCRIPTOR_STRUCT

 

{

 

BYTE blength;                               //设备描述符的字节数大小

 

BYTE bDescriptorType;                      //设备描述符类型编号

 

WORD bcdUSB;                                //USB版本号

 

BYTE bDeviceClass;                          //USB分配的设备类代码

 

BYTE bDeviceSubClass;                       //USB分配的子类代码

 

BYTE bDeviceProtocol;                       //USB分配的设备协议代码

 

BYTE bMaxPacketSize0;                       //端点0的最大包大小

 

WORD idVendor;                              //厂商编号

 

WORD idProduct;                             //产品编号

 

WORD bcdDevice;                             //设备出厂编号

 

BYTE iManufacturer;                         //设备厂商字符串的索引

 

BYTE iProduct;                              //描述产品字符串的索引

 

BYTE iSerialNumber;                         //描述设备序列号字符串的索引

 

BYTE bNumConfigurations;                    //可能的配置数量

 

}

 

DEVICE_DESCRIPTOR_STRUCT, * pDEVICE_DESCRIPTOR_STRUCT;

 

//实际的设备描述符示例

 

code DEVICE_DESCRIPTOR_STRUCT device_descriptor=   //设备描述符

 

{

 

sizeof(DEVICE_DESCRIPTOR_STRUCT),                   //设备描述符的字节数大小,这里是18字节

 

DEVICE_DESCRIPTOR,                              //设备描述符类型编号,设备描述符是01

 

0x1001,   //USB版本号,这里是USB01.10,即USB1.1。由于51是大端模式,所以高低字节交换

 

0x00,                                 //USB分配的设备类代码,0表示类型在接口描述符中定义

 

0x00,                                 //USB分配的子类代码,上面一项为0时,本项也要设置为0

 

0x00,                                //USB分配的设备协议代码,上面一项为0时,本项也要设置为0

 

0x10,                                //端点0的最大包大小,这里为16字节

 

0x7104,                             //厂商编号,这个是需要跟USB组织申请的ID号,表示厂商代号。

 

0xf0ff,        //该产品的编号,跟厂商编号一起配合使用,让主机注册该设备并加载相应的驱动程序

 

0x0100,       //设备出厂编号

 

0x01,        //设备厂商字符串的索引,在获取字符串描述符时,使用该索引号来识别不同的字符串

 

0x02,        //描述产品字符串的索引,同上

 

0x03,         //描述设备序列号字符串的索引,同上

 

0x01                        //可能的配置数为1,即该设备只有一个配置

 

};

 

2.配置描述符

 

//定义标准的配置描述符结构

 

typedef struct _CONFIGURATION_DESCRIPTOR_STRUCT

 

{

 

BYTE bLength;                               //配置描述符的字节数大小

 

BYTE bDescriptorType;                       //配置描述符类型编号

 

WORD wTotalLength;                          //此配置返回的所有数据大小

 

BYTE bNumInterfaces;                        //此配置所支持的接口数量

 

BYTE bConfigurationValue;                   //Set_Configuration命令所需要的参数值

 

BYTE iConfiguration;                        //描述该配置的字符串的索引值

 

BYTE bmAttributes;                          //供电模式的选择

 

BYTE MaxPower;                              //设备从总线提取的最大电流

 

}

 

CONFIGURATION_DESCRIPTOR_STRUCT, * pCONFIGURATION_DESCRIPTOR_STRUCT;

 

2.接口描述符

 

//定义标准的接口描述符结构

 

typedef struct _INTERFACE_DESCRIPTOR_STRUCT

 

{

 

BYTE bLength;                               //接口描述符的字节数大小

 

BYTE bDescriptorType;                       //接口描述符的类型编号

 

BYTE bInterfaceNumber;                      //该接口的编号

 

BYTE bAlternateSetting;                     //备用的接口描述符编号

 

BYTE bNumEndpoints;                         //该接口使用的端点数,不包括端点0

 

BYTE bInterfaceClass;                       //接口类型

 

BYTE bInterfaceSubClass;                    //接口子类型

 

BYTE bInterfaceProtocol;                    //接口遵循的协议

 

BYTE iInterface;                            //描述该接口的字符串索引值

 

}

 

INTERFACE_DESCRIPTOR_STRUCT, * pINTERFACE_DESCRIPTOR_STRUCT;

 

4.端点描述符

 

//定义标准的端点描述符结构

 

typedef struct _ENDPOINT_DESCRIPTOR_STRUCT

 

{

 

BYTE bLegth;                                //端点描述符字节数大小

 

BYTE bDescriptorType;                       //端点描述符类型编号

 

BYTE bEndpointAddress;                      //端点地址及输入输出属性

 

BYTE bmAttributes;                          //端点的传输类型属性

 

WORD wMaxPacketSize;                        //端点收、发的最大包大小

 

BYTE bInterval;                             //主机查询端点的时间间隔

 

}

 

ENDPOINT_DESCRIPTOR_STRUCT, * pENDPOINT_DESCRIPTOR_STRUCT;

 

下面是一个配置描述符集合的定义

 

typedef struct _CON_INT_ENDP_DESCRIPTOR_STRUCT

 

{

 

CONFIGURATION_DESCRIPTOR_STRUCT configuration_descriptor;

 

INTERFACE_DESCRIPTOR_STRUCT interface_descritor;

 

ENDPOINT_DESCRIPTOR_STRUCT endpoint_descriptor[ENDPOINT_NUMBER];

 

}CON_INT_ENDP_DESCRIPTOR_STRUCT;

 

配置描述符集合的示例

 

code CON_INT_ENDP_DESCRIPTOR_STRUCT con_int_endp_descriptor= //配置描述符集合

 

{

 

//configuration_descriptor                     //配置描述符

 

{

 

sizeof(CONFIGURATION_DESCRIPTOR_STRUCT),      //配置描述符的字节数大小,这里为9

 

CONFIGURATION_DESCRIPTOR,                     //配置描述符类型编号,配置描述符为2

 

(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT)+

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)*256+

 

(sizeof(CONFIGURATION_DESCRIPTOR_STRUCT)+

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT)+

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT)*ENDPOINT_NUMBER)/256,   //配置描述符集合的总大小

 

0x01,                                  //只包含一个接口

 

0x01,                                  //该配置的编号

 

0x00,                                  //iConfiguration字段

 

0x80,                                  //采用总线供电,不支持远程唤醒

 

0xC8                                   //从总线获取最大电流400mA

 

},

 

//interface_descritor                   //接口描述符

 

{

 

sizeof(INTERFACE_DESCRIPTOR_STRUCT),   //接口描述符的字节数大小,这里为9

 

INTERFACE_DESCRIPTOR,                  //接口描述符类型编号,接口描述符为3

 

0x00,                                  //接口编号为4

 

0x00,                                  //该接口描述符的编号为0

 

ENDPOINT_NUMBER,                       //非0端点数量为2,只使用端点主端点输入和输出

 

0x08,                                  //定义为USB大容量存储设备

 

0x06,                                  //使用的子类,为简化块命令

 

0x50,                                  //使用的协议,这里使用单批量传输协议

 

0x00                                   //接口描述符字符串索引,为0,表示没有字符串

 

},

 

//endpoint_descriptor[]

 

{

 

{                                     //主端点输入描述

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7

 

ENDPOINT_DESCRIPTOR,                 //端点描述符类型编号,端点描述符为5

 

MAIN_POINT_IN,                       //端点号,主输入端点

 

ENDPOINT_TYPE_BULK,                  //使用的传输类型,批量传输

 

0x4000,                              //该端点支持的最大包尺寸,64字节

 

0x00                                 //中断扫描时间,对批量传输无效

 

},

 

{                                     //主端点输出描述

 

sizeof(ENDPOINT_DESCRIPTOR_STRUCT), //端点描述符的字节数大小,这里为7

 

ENDPOINT_DESCRIPTOR,                 //端点描述符类型编号,端点描述符为5

 

MAIN_POINT_OUT,                      //端点号,主输出端点

 

ENDPOINT_TYPE_BULK,                  //使用的传输类型,批量传输

 

0x4000,                              //该端点支持的最大包尺寸,64字节

 

0x00                                 //中断扫描时间,对批量传输无效

 

}

 

}

 

};

 

其中关于端点的类型定义如下

 

//定义的端点类型

 

#define ENDPOINT_TYPE_CONTROL           0x00 //控制传输

 

#define ENDPOINT_TYPE_ISOCHRONOUS       0x01 //同步传输

 

#define ENDPOINT_TYPE_BULK              0x02 //批量传输

 

#define ENDPOINT_TYPE_INTERRUPT         0x03 //中断传输

 

端点号的定义如下

 

#define MAIN_POINT_OUT           0x02   //2号输出端点

 

#define MAIN_POINT_IN            0x82   //2号输入端点

这篇关于USB2.0速度识别的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/543733

相关文章

使用PyTorch实现手写数字识别功能

《使用PyTorch实现手写数字识别功能》在人工智能的世界里,计算机视觉是最具魅力的领域之一,通过PyTorch这一强大的深度学习框架,我们将在经典的MNIST数据集上,见证一个神经网络从零开始学会识... 目录当计算机学会“看”数字搭建开发环境MNIST数据集解析1. 认识手写数字数据库2. 数据预处理的

Pytorch微调BERT实现命名实体识别

《Pytorch微调BERT实现命名实体识别》命名实体识别(NER)是自然语言处理(NLP)中的一项关键任务,它涉及识别和分类文本中的关键实体,BERT是一种强大的语言表示模型,在各种NLP任务中显著... 目录环境准备加载预训练BERT模型准备数据集标记与对齐微调 BERT最后总结环境准备在继续之前,确

讯飞webapi语音识别接口调用示例代码(python)

《讯飞webapi语音识别接口调用示例代码(python)》:本文主要介绍如何使用Python3调用讯飞WebAPI语音识别接口,重点解决了在处理语音识别结果时判断是否为最后一帧的问题,通过运行代... 目录前言一、环境二、引入库三、代码实例四、运行结果五、总结前言基于python3 讯飞webAPI语音

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像

Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)

《Python爬虫selenium验证之中文识别点选+图片验证码案例(最新推荐)》本文介绍了如何使用Python和Selenium结合ddddocr库实现图片验证码的识别和点击功能,感兴趣的朋友一起看... 目录1.获取图片2.目标识别3.背景坐标识别3.1 ddddocr3.2 打码平台4.坐标点击5.图

如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解

《如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别详解》:本文主要介绍如何通过海康威视设备网络SDK进行Java二次开发摄像头车牌识别的相关资料,描述了如何使用海康威视设备网络SD... 目录前言开发流程问题和解决方案dll库加载不到的问题老旧版本sdk不兼容的问题关键实现流程总结前言作为

阿里开源语音识别SenseVoiceWindows环境部署

SenseVoice介绍 SenseVoice 专注于高精度多语言语音识别、情感辨识和音频事件检测多语言识别: 采用超过 40 万小时数据训练,支持超过 50 种语言,识别效果上优于 Whisper 模型。富文本识别:具备优秀的情感识别,能够在测试数据上达到和超过目前最佳情感识别模型的效果。支持声音事件检测能力,支持音乐、掌声、笑声、哭声、咳嗽、喷嚏等多种常见人机交互事件进行检测。高效推

Clion不识别C代码或者无法跳转C语言项目怎么办?

如果是中文会显示: 此时只需要右击项目,或者你的源代码目录,将这个项目或者源码目录标记为项目源和头文件即可。 英文如下:

使用WebP解决网站加载速度问题,这些细节你需要了解

说到网页的图片格式,大家最常想到的可能是JPEG、PNG,毕竟这些老牌格式陪伴我们这么多年。然而,近几年,有一个格式悄悄崭露头角,那就是WebP。很多人可能听说过,但到底它好在哪?你的网站或者项目是不是也应该用WebP呢?别着急,今天咱们就来好好聊聊WebP这个图片格式的前世今生,以及它值不值得你花时间去用。 为什么会有WebP? 你有没有遇到过这样的情况?网页加载特别慢,尤其是那

【QNX+Android虚拟化方案】120 - Android 侧 USB2.0 插拔过程

【QNX+Android虚拟化方案】120 - Android 侧 USB2.0 插拔过程 基于原生纯净代码,自学总结 纯技术分享,不会也不敢涉项目、不泄密、不传播代码文档!!! 本文禁止转载分享 !!! 汇总链接:《【QNX+Android虚拟化方案】00 - 系列文章链接汇总》 本文链接:《【QNX+Android虚拟化方案】120 - Android 侧 USB2.0