基本原理
矩阵键盘肯定是每一个单片机学习者都接触过的题目。
一般地 4*4 矩阵键盘线路如下图所示,A-D 输出端口,1-3 输入端口:
使用原理也简单,如下图。
当 B 端输出高电平,B3 键 pressed,即在 3 端可以检测到高电平。
如此就可以判断 B3 键按下。
实际使用
矩阵键盘实际使用时需要扫描,由 MCU 控制,如下图所示。
MCU 在 A-D 端口依次循环输出高电平,并依次检测 1-4 端口状态。
例如:当 C 端口输出高电平,依次检测 1-4 端口,此时若发现 3 端口
上检测到高电平,则认为 C3 键按下。
如此的过程称之为键盘扫描,扫描频率一般在 KHz 级别。
根据扫描原理,编写简单的程序即可分别识别 16 个按键。
也许在小项目中 4*4 的矩阵 16 个按键已经足够使用,也不需要组合按键。
但是总有一些项目需要组合按键,例如 PC 机的 8*16 矩阵键盘。
PC 机有许多组合按键,例如 Shift+a、Fn+Fx、Ctrl+Alt+Delete 等等。
组合按键可以被正确识别吗?
第一种情况:
如下图,B 组 3 个按键按下。当 B 端口输出高电平,分别在 1、2、3 端口检测到高电平。
此时 MCU 可以区分三个按键,即可以正常扫描。
第二种情况:
如下图,3 端口上的三个按键按下,当 A、B、C 端口分别输出高电平,都会在 3 端口上检测到高电平。
由于A、B、C 端口是分别输出的高电平,因此也可以正确识别三个按键。
第三种情况:
当 C 端口输出高,C2 和 B2 都按下,C 线上的电会传至 B 线,此时再按下 B3,3 端口也可检测到高电平。
但是此时只有 C 端口输出高电平,却在 3 端口检测到高电平。
按照第一种情况,MCU 会认为 C2、C3 键按下,实际上 C3 并没有按下。
此种情况称之为 Ghosting。PC 游戏中就有好多组合按键,因此这会导致按键识别错误。
当 C2、B2、B3 键按下,MCU 会认为 C2、C3 键按下,Ghosting 键产生。
如果紧接着按下 C3 键,对于 MCU 来说没有任何变化。然后再松开 C2 键,对于
MCU 来说仍然没有任何变化。因此 Ghosting 键会引起一系列错误。
Ghosting 键可以避免吗?
当然有办法避免此种错误。软件和硬件都有对应的解决方法。
硬件的方法最简单,如下图所示。
在每一个按键旁加一个二极管。这样就会防止 C2、B2 键按下后,电被传导至 B 端口。
如此就可以简单地避免 Ghosting 键。
由于扫描速度很快(KHz 级别),应当选择合适的二极管。一般地选择 1N4148 即可。
如果键盘矩阵比较大,需要更快的扫描,应当选择肖基特二极管。
嵌入式项目软硬件相辅相成,硬件的坑大部分可以用软件填补,软件的大部分缺陷也可以由硬件去弥补。
软件的方法比较复杂。
对于 8*16 矩阵,使用 16Byte
记录上一次扫描时 Input 的状态,
判断是否有多个按键按下(读取 Input 状态)。
如果是多按键按下,则判断除当前扫描列外其他扫描列是否有按键按下(根据记录的上一次扫描结果判断)。
然后判断是否构成类似于上述的 Ghosting 键。如果构成上述 Ghosting,则将最后一次的扫描作废。
扫描期间,软件要判断按键 Press Or Release,是否长按等情况。因此软件的实现方法很复杂。
还有一种方法就是在设计键盘矩阵时就尽量避免 Ghosting。但是很多时候都不能完全避免,因此还需要软件的辅助。
如下图,是笔记本 PS/2 键盘的矩阵。
8*16 的矩阵,最多放置 128 个按键,但是大部分键盘仅有不到 90 个按键,在矩阵中根据 PC 键盘按键习惯
合理的留空,也可避免 Ghosting 键的产生。