那曲檬骨新材料有限公司

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子元器件>接口定義>

USB HID報(bào)告及報(bào)告描述符簡(jiǎn)介

2009年04月12日 11:13 電子設(shè)計(jì)系統(tǒng) 作者:佚名 用戶評(píng)論(0
關(guān)鍵字:usb(265184)HID(46646)

USB中,USB HOST是通過各種描述符來識(shí)別設(shè)備的,有設(shè)備描述符,配置描述符,接口描述符,端點(diǎn)描述符,字符串描述符,報(bào)告描述符等等。USB報(bào)告描述符(Report Descriptor)是HID設(shè)備中的一個(gè)描述符,它是比較復(fù)雜的一個(gè)描述符。

??? USB HID設(shè)備是通過報(bào)告來給傳送數(shù)據(jù)的,報(bào)告有輸入報(bào)告和輸出報(bào)告。輸入報(bào)告是USB設(shè)備發(fā)送給主機(jī)的,例如USB鼠標(biāo)將鼠標(biāo)移動(dòng)和鼠標(biāo)點(diǎn)擊等信息返回給電腦,鍵盤將按鍵數(shù)據(jù)數(shù)據(jù)返回給電腦等;輸出報(bào)告是主機(jī)發(fā)送給USB設(shè)備的,例如鍵盤上的數(shù)字鍵盤鎖定燈和大寫字母鎖定燈等。報(bào)告是一個(gè)數(shù)據(jù)包,里面包含的是所要傳送的數(shù)據(jù)。輸入報(bào)告是通過中斷輸入端點(diǎn)輸入的,而輸出報(bào)告有點(diǎn)區(qū)別,當(dāng)沒有中斷輸出端點(diǎn)時(shí),可以通過控制輸出端點(diǎn)0發(fā)送,當(dāng)有中斷輸出端點(diǎn)時(shí),通過中斷輸出端點(diǎn)發(fā)出。

??? 而報(bào)告描述符,是描述一個(gè)報(bào)告以及報(bào)告里面的數(shù)據(jù)是用來干什么用的。通過它,USB HOST可以分析出報(bào)告里面的數(shù)據(jù)所表示的意思。它通過控制輸入端點(diǎn)0返回,主機(jī)使用獲取報(bào)告描述符命令來獲取報(bào)告描述符,注意這個(gè)請(qǐng)求是發(fā)送到接口的,而不是到設(shè)備。一個(gè)報(bào)告描述符可以描述多個(gè)報(bào)告,不同的報(bào)告通過報(bào)告ID來識(shí)別,報(bào)告ID在報(bào)告最前面,即第一個(gè)字節(jié)。當(dāng)報(bào)告描述符中沒有規(guī)定報(bào)告ID時(shí),報(bào)告中就沒有ID字段,開始就是數(shù)據(jù)。

??? USB報(bào)告描述符可以通過使用HID Descriptor tool來生成。點(diǎn)擊加粗部分可以下載此工具。


??? 下面通過由HID Descriptor tool生成的USB鼠標(biāo)和USB鍵盤來說明一下報(bào)告描述符和報(bào)告。

code char KeyBoardReportDescriptor[63] = {
??? //表示用途頁(yè)為通用桌面設(shè)備
??? 0x05, 0x01,??????????????????? // USAGE_PAGE (Generic Desktop)

??? //表示用途為鍵盤
??? 0x09, 0x06,??????????????????? // USAGE (Keyboard)
???
??? //表示應(yīng)用集合,必須要以END_COLLECTION來結(jié)束它,見最后的END_COLLECTION
??? 0xa1, 0x01,??????????????????? // COLLECTION (Application)
???
??? //表示用途頁(yè)為按鍵
??? 0x05, 0x07,??????????????????? //?? USAGE_PAGE (Keyboard)

??? //用途最小值,這里為左ctrl鍵
??? 0x19, 0xe0,??????????????????? //?? USAGE_MINIMUM (Keyboard LeftControl)
??? //用途最大值,這里為右GUI鍵,即window鍵
??? 0x29, 0xe7,??????????????????? //?? USAGE_MAXIMUM (Keyboard Right GUI)
??? //邏輯最小值為0
??? 0x15, 0x00,??????????????????? //?? LOGICAL_MINIMUM (0)
??? //邏輯最大值為1
??? 0x25, 0x01,??????????????????? //?? LOGICAL_MAXIMUM (1)
??? //報(bào)告大小(即這個(gè)字段的寬度)為1bit,所以前面的邏輯最小值為0,邏輯最大值為1
??? 0x75, 0x01,??????????????????? //?? REPORT_SIZE (1)
??? //報(bào)告的個(gè)數(shù)為8,即總共有8個(gè)bits
??? 0x95, 0x08,??????????????????? //?? REPORT_COUNT (8)
??? //輸入用,變量,值,絕對(duì)值。像鍵盤這類一般報(bào)告絕對(duì)值,
??? //而鼠標(biāo)移動(dòng)這樣的則報(bào)告相對(duì)值,表示鼠標(biāo)移動(dòng)多少
??? 0x81, 0x02,??????????????????? //?? INPUT (Data,Var,Abs)
??? //上面這這幾項(xiàng)描述了一個(gè)輸入用的字段,總共為8個(gè)bits,每個(gè)bit表示一個(gè)按鍵
??? //分別從左ctrl鍵到右GUI鍵。這8個(gè)bits剛好構(gòu)成一個(gè)字節(jié),它位于報(bào)告的第一個(gè)字節(jié)。
??? //它的最低位,即bit-0對(duì)應(yīng)著左ctrl鍵,如果返回的數(shù)據(jù)該位為1,則表示左ctrl鍵被按下,
??? //否則,左ctrl鍵沒有按下。最高位,即bit-7表示右GUI鍵的按下情況。中間的幾個(gè)位,
??? //需要根據(jù)HID協(xié)議中規(guī)定的用途頁(yè)表(HID Usage Tables)來確定。這里通常用來表示
??? //特殊鍵,例如ctrl,shift,del鍵等

??? //這樣的數(shù)據(jù)段個(gè)數(shù)為1
??? 0x95, 0x01,??????????????????? //?? REPORT_COUNT (1)
??? //每個(gè)段長(zhǎng)度為8bits
??? 0x75, 0x08,??????????????????? //?? REPORT_SIZE (8)
??? //輸入用,常量,值,絕對(duì)值
??? 0x81, 0x03,??????????????????? //?? INPUT (Cnst,Var,Abs)
???
??? //上面這8個(gè)bit是常量,設(shè)備必須返回0


??? //這樣的數(shù)據(jù)段個(gè)數(shù)為5
??? 0x95, 0x05,??????????????????? //?? REPORT_COUNT (5)
??? //每個(gè)段大小為1bit
??? 0x75, 0x01,??????????????????? //?? REPORT_SIZE (1)
??? //用途是LED,即用來控制鍵盤上的LED用的,因此下面會(huì)說明它是輸出用
??? 0x05, 0x08,??????????????????? //?? USAGE_PAGE (LEDs)
??? //用途最小值是Num Lock,即數(shù)字鍵鎖定燈
??? 0x19, 0x01,??????????????????? //?? USAGE_MINIMUM (Num Lock)
??? //用途最大值是Kana,這個(gè)是什么燈我也不清楚^_^
??? 0x29, 0x05,??????????????????? //?? USAGE_MAXIMUM (Kana)
??? //如前面所說,這個(gè)字段是輸出用的,用來控制LED。變量,值,絕對(duì)值。
??? //1表示燈亮,0表示燈滅
??? 0x91, 0x02,??????????????????? //?? OUTPUT (Data,Var,Abs)

??? //這樣的數(shù)據(jù)段個(gè)數(shù)為1
??? 0x95, 0x01,??????????????????? //?? REPORT_COUNT (1)
??? //每個(gè)段大小為3bits
??? 0x75, 0x03,??????????????????? //?? REPORT_SIZE (3)
??? //輸出用,常量,值,絕對(duì)
??? 0x91, 0x03,??????????????????? //?? OUTPUT (Cnst,Var,Abs)???
??? //由于要按字節(jié)對(duì)齊,而前面控制LED的只用了5個(gè)bit,
??? //所以后面需要附加3個(gè)不用bit,設(shè)置為常量。

??? //報(bào)告?zhèn)€數(shù)為6
??? 0x95, 0x06,??????????????????? //?? REPORT_COUNT (6)
??? //每個(gè)段大小為8bits
??? 0x75, 0x08,??????????????????? //?? REPORT_SIZE (8)
??? //邏輯最小值0
??? 0x15, 0x00,??????????????????? //?? LOGICAL_MINIMUM (0)
??? //邏輯最大值255
??? 0x25, 0xFF,??????????????????? //?? LOGICAL_MAXIMUM (255)
??? //用途頁(yè)為按鍵
??? 0x05, 0x07,??????????????????? //?? USAGE_PAGE (Keyboard)
??? //使用最小值為0
??? 0x19, 0x00,??????????????????? //?? USAGE_MINIMUM (Reserved (no event indicated))
??? //使用最大值為0x65
??? 0x29, 0x65,??????????????????? //?? USAGE_MAXIMUM (Keyboard Application)
??? //輸入用,變量,數(shù)組,絕對(duì)值
??? 0x81, 0x00,??????????????????? //?? INPUT (Data,Ary,Abs)
??? //以上定義了6個(gè)8bit寬的數(shù)組,每個(gè)8bit(即一個(gè)字節(jié))用來表示一個(gè)按鍵,所以可以同時(shí)
??? //有6個(gè)按鍵按下。沒有按鍵按下時(shí),全部返回0。如果按下的鍵太多,導(dǎo)致鍵盤掃描系統(tǒng)
??? //無法區(qū)分按鍵時(shí),則全部返回0x01,即6個(gè)0x01。如果有一個(gè)鍵按下,則這6個(gè)字節(jié)中的第一
??? //個(gè)字節(jié)為相應(yīng)的鍵值(具體的值參看HID Usage Tables),如果兩個(gè)鍵按下,則第1、2兩個(gè)
??? //字節(jié)分別為相應(yīng)的鍵值,以次類推。


??? //關(guān)集合,跟上面的對(duì)應(yīng)
??? 0xc0?????????????????????????? // END_COLLECTION
};

???? 通過上面的分析,我們知道這個(gè)報(bào)告中只有一個(gè)報(bào)告,所以沒有報(bào)告ID,
因此返回的都是實(shí)際使用的數(shù)據(jù)。總共有8字節(jié)輸入,1字節(jié)輸出。其中輸入的
第一字節(jié)用來表示特殊按鍵,第二字節(jié)保留,后面的六字節(jié)為普通按鍵。如果
只有左ctrl鍵按下,則返回01 00 00 00 00 00 00 00(十六進(jìn)制),如果
只有數(shù)字鍵1 按下,則返回00 00 59 00 00 00 00 00,如果數(shù)字
鍵1 和2 同時(shí)按下,則返回00 00 59 5A 00 00 00 00,如果
再按下左shift 鍵,則返回02 00 59 5A 00 00 00 00,
然后再釋放1?? 鍵,則返回02 00 5A 00 00 00 00 00,
然后全部按鍵釋放,則返回00 00 00 00 00 00 00 00。
這些數(shù)據(jù)(即報(bào)告)都是通過中斷端點(diǎn)返回的。當(dāng)按下Num Lock鍵時(shí),PC會(huì)發(fā)送
輸出報(bào)告,從報(bào)告描述符中我們知道,Num Lock的LED對(duì)應(yīng)著輸出報(bào)告的最低位,
當(dāng)數(shù)字小鍵盤打開時(shí),輸出xxxxxxx1(二進(jìn)制,打x的由其它的LED狀態(tài)決定);
當(dāng)數(shù)字小鍵盤關(guān)閉時(shí),輸出xxxxxxx0(同前)。取出最低位就可以控制數(shù)字鍵鎖定LED了。
下面這個(gè)報(bào)告描述符是USB鼠標(biāo)報(bào)告描述符,比起鍵盤的來說要簡(jiǎn)單些。
它描述了4個(gè)字節(jié),第一個(gè)字節(jié)表示按鍵,第二個(gè)字節(jié)表示x軸(即鼠標(biāo)左右移動(dòng),
0表示不動(dòng),正值表示往右移,負(fù)值表示往左移),第三個(gè)字節(jié)表示y軸(即鼠標(biāo)
上下移動(dòng),0表示不動(dòng),正值表示往下移動(dòng),負(fù)值表示往上移動(dòng)),第四個(gè)字節(jié)
表示鼠標(biāo)滾輪(正值為往上滾動(dòng),負(fù)值為往下滾動(dòng))。

code char MouseReportDescriptor[52] = {
??? //通用桌面設(shè)備
??? 0x05, 0x01,??????????????????? // USAGE_PAGE (Generic Desktop)
??? //鼠標(biāo)
??? 0x09, 0x02,??????????????????? // USAGE (Mouse)
??? //集合
??? 0xa1, 0x01,??????????????????? // COLLECTION (Application)
??? //指針設(shè)備
??? 0x09, 0x01,??????????????????? //?? USAGE (Pointer)
??? //集合
??? 0xa1, 0x00,??????????????????? //?? COLLECTION (Physical)
??? //按鍵
??? 0x05, 0x09,??????????????????? //???? USAGE_PAGE (Button)
??? //使用最小值1
??? 0x19, 0x01,??????????????????? //???? USAGE_MINIMUM (Button 1)
??? //使用最大值3。1表示左鍵,2表示右鍵,3表示中鍵
??? 0x29, 0x03,??????????????????? //???? USAGE_MAXIMUM (Button 3)
??? //邏輯最小值0
??? 0x15, 0x00,??????????????????? //???? LOGICAL_MINIMUM (0)
??? //邏輯最大值1
??? 0x25, 0x01,??????????????????? //???? LOGICAL_MAXIMUM (1)
??? //數(shù)量為3
??? 0x95, 0x03,??????????????????? //???? REPORT_COUNT (3)
??? //大小為1bit
??? 0x75, 0x01,??????????????????? //???? REPORT_SIZE (1)
??? //輸入,變量,數(shù)值,絕對(duì)值
??? //以上3個(gè)bit分別表示鼠標(biāo)的三個(gè)按鍵情況,最低位(bit-0)為左鍵
??? //bit-1為右鍵,bit-2為中鍵,按下時(shí)對(duì)應(yīng)的位值為1,釋放時(shí)對(duì)應(yīng)的值為0
??? 0x81, 0x02,??????????????????? //???? INPUT (Data,Var,Abs)

??? //填充5個(gè)bit,補(bǔ)足一個(gè)字節(jié)
??? 0x95, 0x01,??????????????????? //???? REPORT_COUNT (1)
??? 0x75, 0x05,??????????????????? //???? REPORT_SIZE (5)
??? 0x81, 0x03,??????????????????? //???? INPUT (Cnst,Var,Abs)

??? //用途頁(yè)為通用桌面
??? 0x05, 0x01,??????????????????? //???? USAGE_PAGE (Generic Desktop)
??? //用途為X
??? 0x09, 0x30,??????????????????? //???? USAGE (X)
??? //用途為Y
??? 0x09, 0x31,??????????????????? //???? USAGE (Y)
??? //用途為滾輪
??? 0x09, 0x38,??????????????????? //???? USAGE (Wheel)
??? //邏輯最小值為-127
??? 0x15, 0x81,??????????????????? //???? LOGICAL_MINIMUM (-127)
??? //邏輯最大值為+127
??? 0x25, 0x7f,??????????????????? //???? LOGICAL_MAXIMUM (127)
??? //大小為8個(gè)bits
??? 0x75, 0x08,??????????????????? //???? REPORT_SIZE (8)
??? //數(shù)量為3個(gè),即分別代表x,y,滾輪
??? 0x95, 0x03,??????????????????? //???? REPORT_COUNT (3)
??? //輸入,變量,值,相對(duì)值
??? 0x81, 0x06,??????????????????? //???? INPUT (Data,Var,Rel)

??? //關(guān)集合
??? 0xc0,????????????????????????? //?? END_COLLECTION
??? 0xc0?????????????????????????? // END_COLLECTION
};

通過對(duì)上面的報(bào)告分析,我們知道報(bào)告返回4個(gè)字節(jié),沒有報(bào)告ID。如果鼠標(biāo)左鍵按下,
則返回01 00 00 00(十六進(jìn)制值),如果右鍵按下,則返回02 00 00 00,如果中鍵按下,
則返回04 00 00 00,如果三個(gè)鍵同時(shí)按下,則返回07 00 00 00。如果鼠標(biāo)往右移動(dòng)則
第二字節(jié)返回正值,值越大移動(dòng)速度越快。其它的類推。

非常好我支持^.^

(21) 100%

不好我反對(duì)

(0) 0%

( 發(fā)表人:admin )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?
      游戏机百家乐官网的玩法技巧和规则| 百家乐官网平玩法官方网址| 赌博百家乐的路单| 财神百家乐的玩法技巧和规则| 老k百家乐游戏| 大发888官方sscptdf88yb| 泽州县| 百家乐官网伴侣破解版| 最新百家乐双面数字筹码| ,瑞丰国际娱乐场| 粤港澳百家乐官网娱乐网| 温州市百家乐鞋业有限公司| 皇冠现金网哪个最好| 百家乐官网闲9点| 波音百家乐自动投注| 爱玩棋牌官方下载| 百家乐官网作弊视频| 百家乐补牌规律| 大发888赌博违法吗| 澳门百家乐官网现场游戏| 百家乐一柱擎天| 皇冠开户正网 | 大地百家乐官网的玩法技巧和规则| 百家乐喜牛| 彰化市| 乐宝百家乐游戏| 亚洲顶级赌场手机版| 百家乐官网大转轮真人视讯| 金龍百家乐的玩法技巧和规则| 枞阳县| 百家乐9人桌布| 新利88国际娱乐网| 博网百家乐现金网| 博发| 金沙百家乐现金网| 封丘县| 太阳城百家乐赌场| 西安市| 百家乐官网一年诈骗多少钱| 大发888娱乐亚洲| tt百家乐官网的玩法技巧和规则 |