USB协议详解第10讲(USB描述符-报告描述符)

来自:https://hellocode.blog.youkuaiyun.com/article/details/112504129

一、报告描述符的概念和作用

  开门见山,报告描述符就是描述报告(HID接口上传输事务中的数据)的一组数据结构。

  首先大家可能会问,报告又是什么?我们前面讲过,USB主机一般是以中断的方式向HID设备发送或者索取数据, 也就是说USB主机发送一个请求,设备要根据硬件操作,向主机提交自己的状态变化,例如鼠标,当主机给鼠标设备发送请求后,鼠标需要把自己当前位置信息发送给主机。其实大概应该清楚了,报告就是我们说的传输事务中的原生数据,如果是鼠标的话,这份报告则为鼠标左移、鼠标右移、鼠标滑轮滚动、鼠标左键、鼠标右键的当前状态数据的集合。

  但是我们知道,我们看到的鼠标各各样,有很多鼠标是只有两个按键,有很多七八个按键,如下图,那么问题来了,这么多类型不一样的鼠标,主机是怎么知道鼠标设备发上来的一堆数据(报告)中哪个数据代表哪个按键,报告描述符来解决这个问题,这就是报告描述符的作用:就是描述HID设备数据的用途及属性。
在这里插入图片描述
在这里插入图片描述
  主机在对HID设备进行枚举的时候,会拿到报告描述符,之后给设备发送数据或者接收到设备数据会按照报告描述符对数据的每一位进行解析。

  报告描述符如果全面讲解可以单独成书(还真是两本书,书名为hid1_11.pdfhut1_21_0.pdf,大家可以关注一个早起的程序员,然后点击下载获取),本篇文章会抓重点讲解,教会大家报告描述符的数据结构并举例,大家可以在学习过程中举一反三。

二、报告描述符中的通用项(Item)

  我们知道了报告描述符的概念及作用之后,那么大家肯定想知道了报告描述符是怎么描述数据的,其实报告描述符是由一个一个通用项组成,每一个通用项可以描述一个或者多个相同功能的数据(比如同时描述8个按钮),包括数据的用途和各种属性。

三、通用项结构详解

  Item有两种类型,Short Item和Long Item,结构组成如下,一般我们接触到的都是Short Item,本篇博文也主要讲解Short Item。

3.1 Short Item

在这里插入图片描述

3.2 Long Item

在这里插入图片描述
  在 Short Item 中,起始的 1 Byte 代表了这个 Item 的大小和类型,如下:
在这里插入图片描述

3.3 Short Item组成详解

3.3.1 bSize

  代表后面的数据,最大 4 bytes。

3.3.2 bType

  代表了这个 Item 是什么类型的 Item,这里有三种大的类型:Main(0x00)、Global(0x01)、Local(0x02)。

3.3.3 bTag

  代表在对应的 Item 下的更加细的分类,也可以称之为标签。

Main(0x00)分为:Input、Output、Feature、Collection、End Collection。
Global(0x01)分为:Usage Page、 Logical Minimum、Logical Maximum、Physical Minimum、Physical Maximum、Report Size、Report ID等等。
Local(0x02)分为 :Usage 、Usage Minimum、Usage Maximum、String 等等。

  对于bSize + bType + bTag 的 1 Byte 的组合详见下表:在这里插入图片描述

四、Main、Global、Local标签功能

  非常核心的核心: 在阅读 Report 的时候,都是先用Global和Local标签说明数据项的各种相关属性,然后最后用一个Main标签进行输入输出说明,Main标签的出现就是一个数据项的结束。

  前面提到通用项主要分为Main、Global、Local, 大家肯定会问为什么要分类,他们三个到底是用来做什么的,下面一一讲解。

  Mian类标签:主要用来对数据项的描述(Input、Output、Feature)和管理(Collection、End Collection)。

  • 描述数据项:比如一个这个数据项到底是主机输入还是输出;
  • 管理数据项:比如把多个数据项组织到一起。

  Global类标签对数据项的描述,这个主要用来描述数据项的用途、数据逻辑范围、数据物理范围、数据大小、数据个数,它的用法和我们平时看到的全局变量特别像,当定义之后,之后的所有数据项都是使用定义的属性,除非再此定义,如下详细说明。
在这里插入图片描述
  Local类标签:对数据项的描述,和Global标签的作用类似,它的用法和我们平时看到的局部变量特别像,就是作用于不一样,只在本数据内项生效。
在这里插入图片描述

五、核心标签功能

5.1 Usage Page和Usage

  用于描述数据项的用途,这个标签非常复杂,当UsagePage变化时Usage子功能也会跟着变化,下面会详细讲解。​也可以阅读文档“HID Usage Tables”获得更多使用细节,大家可以关注我,然后点击下载获取本书电子版,也可以去USB IF官网下载。

5.2 Logical Maximum

  描述数据逻辑单元中的范围值。这是变量或数组项将要报告的最大值。例如设备报告的一个电压值读数是1V,而一个单位是 2mV ,则 Logical Maximum 值等于 500 。

5.3 Logical Minimum

  描述数据逻辑单元中的范围值。这是变量或数组项将要报告的最小值。

5.4 Physical Maximum

  描述数据真实的最大值,比如电压最大为2V,一个单位是 2mV ,则该值最大仍是2000mV,表示物理真实值。

5.5 Physical Minimum

  描述数据真实的最小值。

5.6 Report Size

  以位(bit)为单位指定数据的大小,无符号整数。

5.7 Report Count

  无符号整数,指定总共需要多少个同类型的数据。

5.8 Input

  此项数据为设备到主机的。

5.9 Output

  此项数据为主机到设备的。

5.10 Report ID

  报告的ID,一个报告描述符可以描述多个HID功能,主机通过报告的ID就知道是哪个HID功能硬件发送的数据。 举个例子,如果一个USB HID设备为键鼠一体的设备,就可以通过Report ID把键盘和鼠标的数据描述分开,这样可以实现面向对象管理,其实就是相当于实现了多个报告,设备在发送数据的时候,第一个字节永远是Report ID,如果是鼠标发送事务第一个字节(Report ID)为1,如果是键盘发送事务第一个字节(Report ID)则为2,这样分开描述数据其实也就是分开了事务功能本身,如果一个很复杂的HID设备在设计的思路上可以分治而行,可以大大减小设计难度。

5.11 Collection(集合)

  用于对数据描述项进行组织和管理,和End Collection一起使用

六、STM32某鼠标设备报告描述符详细说明

在这里插入图片描述
  上面的报告描述符实现一个鼠标设备,主要有3个数据描述项组成。 描述符总共描述了4个字节的报告(数据),数据描述项1描述了数据的第1个字节前3bit,代表鼠标的3个按钮,数据描述项2为了描述数据对齐操作,数据描述项3描述了数据的第2-4字节,代表鼠标的左右移动、上下移动、滚轮滚动的数据,这4个字节都是设备到主机的数据。其他的细节在注释里面讲解的很清楚。

  假设设备给主机发送了当前最新4个字节的数据(报告),先低字节后高字节:0x01 0x00 0x00 0x00,主机会解析到鼠标左键被按下,鼠标没有移动,滑轮也没滚动,就是这样子理解的。

七、报告描述符用途查询

  报告描述符Usage page和Usage可以通过hut1_21_0.pdf(HID Usage Tables )文档查询,首先每一个Usage Pages下面都包含多种Usage,下面会说明所有的Usage Pages,每一个Usage Pase下面的Usage大家可以直接点击查看。
在这里插入图片描述
  我们可以点击Generic Desktop Page (0x01)去查询下面更具体的Usage,如下:
在这里插入图片描述

八、报告描述符生成工具介绍

  我们可以用HID Descriptor Tool生成报告描述符,也可以直接打开(open file)一些标准设备的报告描述符进行学习,工具如下图,大家可以根据自己的硬件定义自己的报告描述符。
在这里插入图片描述
在这里插入图片描述

<think>嗯,用户想了解Excel中的VLOOKUP函数的用法和参数含义。首先,我需要回忆一下VLOOKUP的基本结构。VLOOKUP是垂直查找函数,用于在表格的首列查找指定的值,然后返回该行中指定列的数据。它的四个参数分别是查找值、表格范围、列索引号和匹配模式。 接下来,我得确认每个参数的具体作用。第一个参数是lookup_value,也就是用户要查找的值,比如产品ID或者姓名。第二个参数是table_array,即查找的范围,这里要注意的是,查找值必须位于这个范围的第一列,否则函数无法正确工作。第三个参数是col_index_num,也就是用户想要返回的数据在表格范围中的第几列,这个列数是从表格范围的第一列开始算起的,不是整个工作表的列。第四个参数是range_lookup,决定是精确匹配还是近似匹配,通常用FALSE或0来指定精确匹配,避免错误。 然后,用户可能需要一个具体的例子来理解如何使用。比如,假设有一个产品价格表,用户想根据产品ID查找对应的价格。这时候,VLOOKUP就可以在ID列查找,然后返回价格列的数据。同时,要提醒用户注意表格范围最好使用绝对引用,比如$A$2:$C$100,这样在拖动公式时范围不会变化。 可能遇到的问题也需要考虑。比如,如果查找值不在表格的第一列,或者列索引号超过了表格的列数,函数会返回错误。此外,数据格式不一致也可能导致问题,比如查找值是数字,而表格中是文本格式的数字,这时候需要统一格式。还有,当出现#N/A错误时,可能是查找值不存在,或者匹配模式设置不正确,需要检查参数是否正确。 用户可能还会问到如何避免常见的错误,比如部分数据匹配出错的情况。这时候需要检查是否有多余的空格,或者数据格式不一致,或者表格范围没有锁定导致拖动时偏移。此外,XLOOKUP作为VLOOKUP的升级版,可能在某些情况下更方便,比如可以向左查找或者返回多列数据,这也是可以提及的内容。 最后,整理步骤,从基础语法到参数说明,再到具体案例,逐步引导用户理解如何使用VLOOKUP函数。同时,提供常见错误和解决方法,帮助用户在实际应用中避免问题。如果有必要,还可以比较VLOOKUP和其他查找函数的区别,比如HLOOKUP或XLOOKUP,但根据用户的问题,主要集中在VLOOKUP本身即可。</think>### Excel VLOOKUP函数详解 #### 一、基础语法与参数说明 VLOOKUP函数的语法为: $$=VLOOKUP(lookup\_value, table\_array, col\_index\_num, [range\_lookup])$$ 包含4个参数: 1. **lookup_value**(必填):要查找的值(如单元格引用或具体值) 2. **table_array**(必填):包含数据的表格范围(必须包含查找列和返回列) 3. **col_index_num**(必填):返回值所在列的序号(从table_array第一列开始计数) 4. **range_lookup**(可选):匹配类型 - `TRUE`/`1`:近似匹配(默认值,需数据升序排列) - `FALSE`/`0`:精确匹配(常用选项) [^1][^2] #### 二、使用步骤演示(工资表查询案例) 假设需要根据员工编号查询工资: 1. 建立查询单元格(如`B12`) 2. 输入公式: ```excel =VLOOKUP(A12, $A$2:$D$100, 4, 0) ``` - `A12`:待查询的员工编号 - `$A$2:$D$100`:锁定数据区域(绝对引用) - `4`:返回第4列(工资列) - `0`:精确匹配 [^2][^3] #### 三、常见错误与解决方法 | 错误现象 | 原因 | 解决方案 | |---------|------|---------| | #N/A | 查找值不存在 | 检查数据源或改用`IFERROR`容错 | | #REF! | 列序号超出范围 | 确认col_index_num ≤ 表格列数 | | 部分匹配失败 | 数据格式不一致 | 统一数值/文本格式 | | 结果错位 | 表格未锁定 | 使用`$`符号固定区域引用 | [^3][^4] #### 四、进阶技巧 1. **多条件查询**: 使用辅助列合并多个条件字段 ```excel =VLOOKUP(A2&B2, $D$2:$F$100, 3, 0) ``` 2. **通配符匹配**: `"*"`匹配任意字符,`"?"`匹配单个字符 ```excel =VLOOKUP("张*", $A$2:$C$100, 3, 0) ``` 3. **跨表查询**: 引用其他工作表数据 ```excel =VLOOKUP(A2, Sheet2!$A$2:$D$100, 4, 0) ``` [^1][^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值