外设天下 - 电脑外设发烧友聚集地

关于键盘冲突那点事(3键冲突/7键冲突/PS2/USB的各种原理)

查看数: 231731 | 评论数: 55 | 收藏 25
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2011-7-28 01:57

正文摘要:

本帖最后由 白金之星 于 2011-7-28 01:59 编辑 最近闲得无聊,正好看到有人发帖提问,于是就来详细说说所谓键位冲突和无冲突的各种原理——基本上这也是个老生常谈的话题了,但相关的技术帖比较零乱难找,而且充 ...

回复

luoweinc 发表于 2011-7-28 06:21
楼主很有才~
字数真多啊……
眼晕{:1_012:}
半熟蛋 发表于 2011-7-28 05:26
这个…初中文化估计看不懂…本人只看懂大概
TanKaFei 发表于 2011-7-28 03:45
强文帮顶...看守厕所的大叔亮了
白金之星 发表于 2011-7-28 01:59
再占一层,以便万一有补充。灌水的楼下请。
白金之星 发表于 2011-7-28 01:57
本帖最后由 白金之星 于 2011-7-28 02:17 编辑

【接上文】


——————三键冲突:矩阵的麻烦——————

如果你耐心地一行一行读到这里,我相信经过了两节的铺垫,你已经掌握了足以继续读下去的基础知识。那么废话到此为止,下面开始介绍本帖的重点问题:【键位冲突】。

在刚才的段落中,你已经知道了系统是如何判定单个键有没有按下的。但我们人类的双手上长了十个手指,谁也不能保证不会同时按下两个按键——甚至很多时候组合键是故意设计要用的。这样一来,就会有一个潜在的问题出现……

请回忆一下刚才用来举例的36格矩阵图,如果我们同时按下B、H、G键,在程序看来是什么样子呢?

像平时一样,它从(A1,B1)开始检测,现实中我们并没有按下A键,所以当A1=0,其他引脚=1的时候,B1的值应该是1,表示A键没有被按下才对。但是,请注意:

由于G键被按下,A1和B2是接通的,
由于H键被按下,B2和A2是接通的,
由于B键被按下,A2和B1也是接通的!
也就是说,现在的电路中,A1和B1其实是连在一起的!

还记得吗?不管多少个1相乘,只要中间有0,最后就会变成0。
换句话说,我们见A1和B1没有直接连通,就天真地以为B1的奶酪不会被吃掉——但有个致命的错误就在于我们根本不关注其它奶酪。瞬间,电流飞驰,经过3个按键,最终钻进地下。这只飞快的小老鼠沿着管线从A1出发,先是吃掉了B2的奶酪,然后又吃掉了A2,最后从B1钻出来大快朵颐。(注:严格来说,其实老鼠与电流方向是相反的,此处的比喻是为了更容易理解)

就这样,芯片以为A键也被按下了。
事实上,按下这4键中的任意3键,在电脑看来都是相同的,因为A1、A2、B1、B2这四点已经变成短路的状态。

任意两行两列所构成的4个交点,也即某长方形的四角所对应的4个键,同时按下3个时,都会出现这样的问题——在四通八达的管道中,剩余的那个键的状态到底是按下还是没按下,对于芯片来讲是一片茫然。怎么办呢?
扫描按键的程序是人写的,稍作改动也不是不可能。于是需要增加如下的处理方法:给它一个“小账本”,随时记录当前按下的所有按键。每当按下或抬起某个键时,就在账本中如实增加或抹除。但是,如果账本显示:某个“四角组合”其中已经有两个按键同时按下时,这个组合剩余的键就被逻辑锁定——即使你按了,程序也拒绝接受,除非之前的某个键抬起。

这样设计的理由很简单:宁可错杀一千,不能放过一个,不知道按没按的话,当成没按更保险。你能想象当你同时按下B键和G键以后,再按H键,屏幕上出现的却是A吗?太无厘头了,还不如什么反应都没有。

这也就是所谓的三键冲突的原型所在。

任何没做无冲处理的矩阵式键盘,都存在许多特定的三键组合不能同时按。举个著名的例子,黑寡妇的A、W、L。

你可能会说:“不会啊我的键盘可以七键一起按都没冲突的。”

是的,不同品牌型号的键盘走线设计可能有区别,因此它们存在冲突的键位也不一样。只要不构成四角组合关系,大部分键都是可以随便同按的,以打字为主要用途的普通键盘,即使有这样那样的冲突,也足够日常使用了。
但是四角组合数不胜数——比如上面例子中6×6的矩阵就存在多达55个四角组合,220种三键冲突,可想而知全尺寸键盘会有多少个键位冲突。虽然大部分冲突组合都是你平时不会按到的,但玩游戏的时候需要的键位总是千奇百怪各不相同,比如玩劲乐团可能需要SDF空格JKL不冲突,而BMIIDX则需要ZSXDCFV不冲突。如果你什么都玩,有很大几率会碰到那么一两个冲突键位郁闷你。即使对键盘最没要求的FPS游戏,还是有少数键盘的四角组合悲剧地包含QWA或者1WD之类经常需要一起按的键……
一个比较讨巧的办法就是把左侧常用十来个键位的走线全部串到一起,这样至少可以保证打CS情绪稳定。因为我们知道,会起冲突的按键是位于任意两行两列的4个交点中的3个,而全部处于同一列或同一行的键,不管怎么按也不会冲突。

当然,最完美的还是全键盘无冲突,也就是所谓的【NKRO】。这就要放在下一节讲了。


——————无冲突的技术本源——————

之前你已经意识到了,普通的矩阵键盘,都会存在成百上千的三键冲突组合。但是市面上却有那么几款键盘,号称全键无冲突,实际测试也是威武异常,整个手掌拍下去都能毫不犹豫地识别出来,这是为什么呢?

这里要介绍一个美妙的电气元件——【二极管】。

二极管是计算机逻辑电路最基本的元件之一(包括CPU芯片在内的各种集成电路芯片内部都有大量的二极管和三极管),大家津津乐道的LED就是二极管中能发光的一种。
一个典型的二极管会有两条腿,即阳极和阴极。它的特点就是——电流只能从它的阳极流向阴极,而反向则难以通过。
如果身为芯片的你捏着一个二极管的两端,你左手是1,右手是0时,只消一瞬间,左手的1就会变成0。但若调换成右手是1,左手是0,右手的1则不会受到影响。这二极管就相当于一个单向的小门,老鼠只可以从这边跑到那边,却不能从那边跑到这边。

那么这个特点对我们具体有什么帮助呢?

只要你回忆一下按键冲突的问题是如何产生的,就会恍然大悟了。

冲突,是为了防止当A1和B2、A2和B2、A2和B1分别连通时,程序误以为A1和B1也连通,因此当发现3个按键互相形成回路时,就屏蔽第三颗按键的设计。

现在,我们在每个按键的电路中增加一个二极管,让小老鼠只能从A端跑到B端,而不能从B跑向A。
回到之前的例子,同时按下B、H、G三个键。尽管H键接通了A2和B2,但由于二极管的限制,信息只能从A2到B2传导,而不能从B2到A2。
于是,虽然受G键按下的影响,当A1=0的时候,B2的值被修改为0,但这个0在这里就到此为止了。因为老鼠到达B2后,被门挡住,无法继续去吃A2的奶酪。既然A2不会跟着变成0,而是保持正确的1,B1的值当然也还是1。
由此,系统自然能够判断出,A键没有被按下,和事实一致。也就是说,二极管的防逆流特性,彻底消除了按键之间的干扰。

有了这些二极管做保障,自然根本不需要什么屏蔽第三颗按键的逻辑了。于是,每一颗按键可以独立自主反应,活动自如,成就了我们的无冲突键盘。

至于为什么无冲突键盘基本都是机械键盘,我想可能有两个原因:
1,机械键盘采取的电路板比较容易安装二极管。而薄膜键盘基本无解。
2,机械键盘本身的定位也比较高,相对这个售价水平来讲,增加一百颗二极管的成本并不显著。


——————USB永远的痛——————

讲了这么多,终于到最后一节了。前面已经把造成键盘冲突的原理和解决办法从头到尾介绍了一遍,但还没有讲过USB接口的键盘,即使硬件上是NKRO结构了,为什么还是只能做到6键无冲突。

这里所指的6键,是除去Ctrl、Shift、Alt、Win之外的键,同时按下任意6个都不会有冲突,但第7个键按下就没有反应——或者会直接抹掉第一个键,总之逻辑上同时只能有6个键处于按下的状态。

但是这样的键盘,使用PS2转接头连接电脑,又可以实现完美NKRO(除了部分键盘干脆不支持PS/2转接,例如poker)。
看来问题就出在USB接口上了。

事实上的确是这样,因为键盘输入设备在USB接口和PS/2接口的传输协议完全不同,也就是说,它们采取了完全不同的工作方式,也难怪效果不同。现在你能买到的大部分机械键盘,其主控芯片可以根据当前连接的端口,自动适应PS/2或USB协议。只有少量无法转接。

既然你已经坚持看到这里了,我相信你对它们的具体区别会比较感兴趣,别着急,这就慢慢道来。

(还是有些废话:如果你搞不清【字节】和【位】的概念请看本段)
位(bit,缩写为小写的b),就是二进制位,取值范围只有0和1两个值,是最小的单位。
字节(Byte,缩写为大写的B),为8个位的组合,取值范围是从0到255(2的8次方),也是常见的计算机数据量单位。
1字节=8位,所以如果你的网速标称10Mb,实际下载速度只有1.25MB。

PS/2协议下,键盘是每次发生按键/抬键动作,都会发送数据信号给主机。通常按下一个键这个动作所包含的数据(通码)为1或2个字节,抬起一个键(断码)则是2或3个字节。如果按住一个键不放,则会不停地向主机循环发送通码,直到抬起按键发送断码。根据10-20kHz的工作频率规范,每位数据的传输时间大约是40-80微秒,加上中间的保留延迟,每个字节会占用0.5-1ms的传输时间。不过在实际应用中,这个延迟完全可以接受——即使像铁拳那样以帧来计算的格斗游戏,对出招的严格度也不会低于16ms。

而USB协议下,键盘会以某个固定的回报率(每秒125-1000次),定期向主机发送当前按键的状态,每次发送8个字节,这8个字节的具体内容则是:
第一个字节:8位分别表示左右的Ctrl、Shift、Alt、Win各自是否被按下。这8个键统称为【modifer key】,因为规范已经事先定义好每一位的含义,从而得以能够只用一个字节就表示8个键的状态。
第二个字节:保留(无用)
其余6个字节:当前正按下的6个【普通按键】(如果按了7个以上,根据键盘主控芯片内置的程序,可能取最先按的6个,也可能取最后按的6个)。
即每1-8ms,可以发送最多14个按键的状态信息。

发现问题所在了吧?如果说按键是上厕所的人,传输协议是看守厕所的大叔……

PS/2大叔会一直盯着厕所门口,每次有人进去就向主机汇报,有人出来再汇报。
USB大叔呢,则是急急忙忙冲进厕所,看有哪些人在,记在小纸条上,然后跑出来一起汇报,之后再冲进去,如此循环。可惜他的小纸条地方太小,只够写下6个人的名字(另外还有8位闹肚子的熟客是事先打好招呼的,只要用暗号记载汇报就可以)。

所以说,USB协议下,包含两边的Ctrl、Shift、Alt、Win在内,单键盘最多只能同时识别14个键。如果只算普通键,则只能同时识别6个。

至于最近一年刚兴起的【USB无冲】技术,似乎是通过将一个物理键盘虚拟成多个逻辑键盘实现的,程序兼容性还有待提高,在此暂且不表。

关于键盘冲突那点事,差不多也说完了。感谢你耐心阅读本文,主要参考文献:

Adam Chapweske,《The PS/2 Mouse/Keyboard Protocol》(地址:www.computer-engineering.org/ps2protocol/
USB行业标准组织,《Device Class Definition for HID 1.11》(地址:www.usb.org/developers/devclass_docs/HID1_11.pdf

如果说有哪位依照版规,对我上面贴的两个外链有意见,那我宁愿整帖都一起删掉,保留文献链接是任何一位作者都应当遵守的最基本道德。望版主谅解。

——————完——————

以上,白金之星首发于pcwaishe.cn,次发哪还没想好。转载请注明。
qianxing 发表于 2021-3-17 14:57
讲得很好,学到了。
[发帖际遇]: qianxing水了一贴,然而并没什么卵用,被扣5 元 发烧值. 幸运榜 / 衰神榜
神鲸大虾 发表于 2020-12-9 09:21
楼主牛逼!
[发帖际遇]: 神鲸大虾去浴室洗澡居然没帮搓澡工捡起地上的肥皂,扣4 元 发烧值 幸运榜 / 衰神榜
leyuansugar 发表于 2018-2-7 05:39
学到了学到了 感谢楼主啊
钢琴节奏 发表于 2017-5-26 16:55
这帖子真**牛逼(如果楼主还看得到的话)
[发帖际遇]: 钢琴节奏 从蓝翔毕业,却不是挖掘机专业引起公愤。被扣4 元 发烧值. 幸运榜 / 衰神榜
这是一头熊 发表于 2015-11-25 15:45
这科普贴很赞,学习了
喵呜先森 发表于 2015-10-13 11:20
写的太棒了,学到好多东西~谢谢LZ
[发帖际遇]: 喵呜先森用红轴打出了青轴的音效,获年度最佳音乐制作人奖,奖励5 元 发烧值. 幸运榜 / 衰神榜
newlifesy 发表于 2014-11-23 09:55
PS/2大叔会一直盯着厕所门口,每次有人进去就向主机汇报,有人出来再汇报。
USB大叔呢,则是急急忙忙冲进厕所,看有哪些人在,记在小纸条上,然后跑出来一起汇报,之后再冲进去,如此循环。可惜他的小纸条地方太小,只够写下6个人的名字(另外还有8位闹肚子的熟客是事先打好招呼的,只要用暗号记载汇报就可以)。
看到这句,我瞬间就大彻大悟了~
要是把USB和PS/2的原理图配上来,绝版了~
athlon1400 发表于 2014-11-17 20:38
这帖子其实应该置顶~~

好多人问关于NK的问题,还有PS2&USB的问题
meiwenzhe 发表于 2014-1-11 16:24
感谢lz普及姿势,不过好像没说明为什么ps2口的可以做到全键无冲,而usb的不行