关于STM32的USB设备库DIY机械键盘( 五 )


2:二极管的单向导电性 。如下图 。
因为按键冲突的实质原因是由于电路形成通路导致的,而二极管因为其特性而将上述可能出现的情况完全解决了,当然缺点就是成本增加了 。
3.2 关于六键无冲
网上查找键盘的数据格式,大多都是如下的一个说明 。
键盘发送给PC的数据每次8个字节
BYTE1 BYTE2 BYTE3 BYTE4 BYTE5 BYTE6 BYTE7 BYTE8
定义分别是:
BYTE1 –

关于STM32的USB设备库DIY机械键盘

文章插图
|–bit0: Left 是否按下,按下为1
|–bit1: Left Shift 是否按下,按下为1
|–bit2: Left Alt 是否按下,按下为1
|–bit3: Left GUI 是否按下,按下为1
|–bit4: Right 是否按下,按下为1
|–bit5: Right Shift 是否按下,按下为1
|–bit6: Right Alt 是否按下,按下为1
|–bit7: Right GUI 是否按下,按下为1
BYTE2 – 暂不清楚,有的地方说是保留位
BYTE3–BYTE8 – 这六个为普通按键
键盘经过测试 。
例如:键盘发送一帧数据 02 00 0x04 0x05 00 00 00 00
表示同时按下了Left Shift + ‘a’+‘b’三个键
这就误导我以为键盘就只能一次最多发送六个按键数据(除了Ctrl等控制按键外) 。这也就有了六键无冲的由来 。因为一次最多发送六个按键的数据 。后来网上找了很多的资料,也去看了看HID v1.11这个协议的部分内容 。
结果如下:为什么一次最多只能发送六个按键值,这是因为只有上述的这个格式的键盘在BIOS下才能有效 。至于在系统环境下,你想发送多少个按键值,随意,你开心就好 。因此,我完全可以将报告描述符更改为如下形势 。
0x05, 0x01, // USAGE_PAGE (Generic Desktop)0x09, 0x06, // USAGE (Keyboard)0xa1, 0x01, // COLLECTION (Application)0x05, 0x07, // USAGE_PAGE (Keyboard)0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0x01, // LOGICAL_MAXIMUM (1)0x75, 0x01, // REPORT_SIZE (1)0x95, 0x08, // REPORT_COUNT (8)0x81, 0x02, // INPUT (Data,Var,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x08, // REPORT_SIZE (8)0x81, 0x03, // INPUT (Cnst,Var,Abs)0x95, 0x05, // REPORT_COUNT (5)0x75, 0x01, // REPORT_SIZE (1)0x05, 0x08, // USAGE_PAGE (LEDs)0x19, 0x01, // USAGE_MINIMUM (Num Lock)0x29, 0x05, // USAGE_MAXIMUM (Kana)0x91, 0x02, // OUTPUT (Data,Var,Abs)0x95, 0x01, // REPORT_COUNT (1)0x75, 0x03, // REPORT_SIZE (3)0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0x95, 0x0D, // REPORT_COUNT (14)// 更改这一句0x75, 0x08, // REPORT_SIZE (8)0x15, 0x00, // LOGICAL_MINIMUM (0)0x25, 0xFF, // LOGICAL_MAXIMUM (255)0x05, 0x07, // USAGE_PAGE (Keyboard)0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)0x81, 0x00, // INPUT (Data,Ary,Abs)0xc0, // END_COLLECTION/* 63 */
这样六键无冲键盘一下子就成了14键无冲键盘,这个值是随意可以设置的 。当然,这里更改了,端点描述符也需要更改一下数据包的大小 。
如果你乐意,你想就这样把键盘设置为全键无冲键盘,比如104配列的键盘,除了8个控制按键外,完全可以把的值改为96 。
3.3 关于全键无冲与实现方式
上面其实已经讲了全键无冲,顾名思义就是所有按键按下都不会有冲突,电脑都可以响应我们所按下的所有按键 。
这里主要讲一下实现的方式 。实现方式有很多种,我讲一下我知道的几种 。
1:3.2节讲的方法,通过更改报告描述符的方式 。
2:复合设备,定义一个组合设备 。比如一个接口发送六个字节的数据 。那么我定义一个五个接口的组合设备,这样我是不是可以做到30键无冲了呢 。
3:最常用的方法就是,把每一个按键映射为一个字节的一个位,以前一个按键就需要一个字节,现在一个字节就可以表示8个按键,这样,只需要16个字节就能表示128个按键了,除开其中有几个bit位无意义之外,这样一个全键盘的104个按键就能通过一个16字节的USB数据包来表示了 。