ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

DIY蓝牙键盘(1) - 理解键盘报文

2021-09-12 16:02:48  阅读:213  来源: 互联网

标签:3Byte 报文 0Byte 0x00 键盘 DIY Byte 1Byte


1. 键盘报文体验

一个键盘对于用户的体验是,用户按按键A他能看到字母A会在主机上显示出来。那这是如何实现的?

其实很简单,只要键盘发送下面的两个报文给主机,字母A就能在主机上显示出来。

(1)表1:字母A按下的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x04 0x00 0x00 0x00

(2)表2:字母A松开的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

报文的原则很简单,就是它把字母A所以对应的usage发给主机,主机就能显示出字母A. 以上表1按下报文Byte 1的值就是字母A的usage, 这个在USB官网的HID usage table(https://usb.org/sites/default/files/hut1_22.pdf)里面有定义。因为这个是USB标准所定义的,现在所有的操作系统都会认识这个usage, 于是主机会把0x04翻译成字母A.

有人要问了,那看起来只要发一个报文就可以输出A了,为什么还要再发一个松开的报文?

大家在用键盘的时候应该有这个体验,我们要输入一个字母A, 会按下A键然后松开。如果你一直按着字母A, 那么在主机上会看到一直会有字母A输出,下到你松开按键A.

当键盘只给主机发送一个A键盘按下的报文(表1),那么主机会一直输出字母A,这自然不是我们想到的。因此我们在发送完按下的报文后,还要发送松开的报文告诉主机说按键已经松开了。表2中把Byte 1的值改为0x00就是告诉主机按键已松开。

 

2. 按键实验

我们有了之上的知识后,那么比如我现在想要输入其他的字母要怎么做?

第一步我们要找到HID usage table(https://usb.org/sites/default/files/hut1_22.pdf),然后找到其他字母对应的usage并发出去。

image-20210912112932516

上面我截取了一段键盘按键的usage, N的usage为0x11, i的usage为0x0C, c的usage为0x06, e的usage为0x08. 所以如果我要让主机输出单词Nice, 键盘必须要发出下面4组报文(report).

(1)发送N的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x11 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

(2)发送i的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x0C 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

(3)发送c的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x06 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

(4)发送e的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x08 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

以此类推,我们查找到26个字母对应的usage, 并让键盘发出去,就可以让主机输出26个字母出来。

3. 报文格式解析

细心的同学可能会有个疑问:我用一个字节就可以完成26个字母的发送,还要其他4个字节来做什么?

第一个字节Byte 0下面会讲到,这里先跳过。 第2到第5个字母的地位是等同的。也就是说发送按键A,下面的4种方式的效果是一样的。

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x04 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x04 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x04 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x04

可能大家还是蒙的,你说这么多还是没有解释原因呀。现在解释正式开始。

上面说的所有情况都是用户一个按键一个按键按住松开的情况,那如果我4个按键一起按住一起松开,那键盘该怎么发送报文?

还是以Nice这个单词为例,假如我同时按住Nice然后松开,键盘应该发送如下的报文。

(1) 4个按键按住的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x11 0x0C 0x06 0x08

(2) 4个按键松开的报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

可能有人要说了,如果我有同时按键10个按键的情况,那这4个字节不够用看呀,怎么办呢?其实也很简单,你只要把报文扩展为11个字节就可以了,下面两个报文就是同时输出: ABCDEFGHIJ的例子.

Byte 0Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6Byte 7Byte 8Byte 9Byte 10
0x00 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D
Byte 0Byte 1Byte 2Byte 3Byte 4Byte 5Byte 6Byte 7Byte 8Byte 9Byte 10
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

4. Qwerty Key vs Modifier Key

在继续往讲之前,先来认识一下qwerty key和modifier key这两个概念。

上面介绍的26个字母的按键,都属于qwerty key. 这个qwerty这个词,你看一下手头键盘的第一行字母的排列,是不是觉得创造这个词的人很偷懒。

那什么是modifier key呢?"Ctrl"、"Alt"、"Shift"、"Win"这些按键统称为modifier key. 除了这些按键,键盘上的其他按键都称为qwerty key.

5. Modifier报文格式

上面留了个悬念,就是没有解释byte 0的作用。其实byte 0就是用来表示modifier按键的。 我们希望的Modifier报文的格式如下:

bit 7bit 6bit 5bit 4bit 3bit 2bit 1bit 0
R Win R Shift R Alt R Ctrl L Win L Shift L Alt L Ctrl

对于一个全键盘会有左右边的modifier,因此我们定义byte 0的高4bit表示右边的modifier, 低4bit表示左边的modifier.

有了报文格式之后,我们就可以尝试来发一下modifier的报文。比如我们要发送左边的Ctrl,那应该发:

Byte 0Byte 1Byte 2Byte 3Byte 4
0x01 0x00 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

几个modifier的组合应该怎么发呢?比如: L Ctrl + L Alt + R Win

Byte 0Byte 1Byte 2Byte 3Byte 4
0x83 0x00 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

6. 组合按键报文

我们现在来看看,qwerty key和modifier key的组合。比如程序员经常使用的组合键:Ctrl + C, Ctrl + V.

(1) Ctrl + C 报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x01 0x06 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

(2) Ctrl + V 报文

Byte 0Byte 1Byte 2Byte 3Byte 4
0x01 0x19 0x00 0x00 0x00
Byte 0Byte 1Byte 2Byte 3Byte 4
0x00 0x00 0x00 0x00 0x00

7. 总结

这篇主要讲了键盘报文的分类与格式,以及如何根据要求发送相应的报文,让主机输出相应的qwerty key和modifier key.

大家应该会接着问,那主机为什么知道我这些报文的格式?那肯定是主机要提前知道我们发的报文的格式,那么问题就变成了:在发送报文前我们要怎么通知主机,让它知道我们报文的格式。

我们下次再继。。。。。。

标签:3Byte,报文,0Byte,0x00,键盘,DIY,Byte,1Byte
来源: https://www.cnblogs.com/jason-sharing/p/15258326.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有