距阵键盘
矩阵键盘是单片机编程中所使用的键盘.
1.矩阵式键盘的结构与工作原理
在键盘中按键数量较多时,为了减少 I/O 口的占用,通常将按键排列成矩阵形式,
如图 1 所示。在矩阵式键盘中,每条水平线和垂直线在交叉处不直接连通,而是通过
一个按键加以连接。这样,一个端口(如 P1 口)就可以构成 4*4=16 个按键,比之
直接将端口线用于键盘多出了一倍,而且线数越多,区别越明显,比如再多加一条线
就可以构成 20 键的键盘,而直接用端口线则只能多出一键(9 键)。由此可见,在
需要的键数比较多时,采用矩阵法来做键盘是合理的。
矩阵式结构的键盘显然比直接法要复杂一些,识别也要复杂一些,上图中,列线
通过电阻接正电源,并将行线所接的单片机的 I/O 口作为输出端,而列线所接的 I/O
口则作为输入。这样,当按键没有按下时,所有的输出端都是高电平,代表无键按下。
行线输出是低电平,一旦有键按下,则输入线就会被拉低,这样,通过读入输入线的
状态就可得知是否有键按下了。具体的识别及编程方法如下所述。
2、矩阵式键盘的按键识别方法
确定矩阵式键盘上何键被按下介绍一种“行扫描法”。
行扫描法 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别
方法,如上图所示键盘,介绍过程如下。
1、判断键盘中有无键按下 将全部行线 Y0-Y3 置低电平,然后检测列线的状态。
只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与 4
根行线相交叉的 4 个按键之中。若所有列线均为高电平,则键盘中无键按下。
2、判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。
其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。
在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该
列线与置为低电平的行线交叉处的按键就是闭合的按键。
下面给出一个具体的例子:
图仍如上所示。8031 单片机的 P1 口用作键盘 I/O 口,键盘的列线接到 P1 口的
低 4 位,键盘的行线接到 P1 口的高 4 位。列线 P1.0-P1.3 分别接有 4 个上拉电阻到
正电源+5V,并把列线 P1.0-P1.3 设置为输入线,行线 P1.4-P.17 设置为输出线。4
根行线和 4 根列线形成 16 个相交点。
1、检测当前是否有键被按下。检测的方法是 P1.4-P1.7 输出全“0”,读取 P1.0-
P1.3 的状态,若 P1.0-P1.3 为全“1”,则无键闭合,否则有键闭合。
2、去除键抖动。当检测到有键按下后,延时一段时间再做下一步的检测判断。
3、若有键被按下,应识别出是哪一个键闭合。方法是对键盘的行线进行扫描。P
1.4-P1.7 按下述 4 种组合依次输出:
P1.7 1 1 1 0
P1.6 1 1 0 1
P1.5 1 0 1 1
P1.4 0 1 1 1
在每组行输出时读取 P1.0-P1.3,若全为“1”,则表示为“0”这一行没有键闭合,否
则有键闭合。由此得到闭合键的行值和列值,然后可采用计算法或查表法将闭合键的
行值和列值转换成所定义的键值
4、为了保证键每闭合一次 CPU 仅作一次处理,必须却除键释放时的抖动。
键盘扫描程序:
从以上分析得到键盘扫描程序的流程图如图 2 所示。程序如下
SCAN: MOV P1,#0FH
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT1
SJMP NEXT3
NEXT1: ACALL D20MS
MOV A,#0EFH
NEXT2: MOV R1,A
MOV P1,A
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,KCODE;
MOV A,R1
SETB C
RLC A
JC NEXT2
NEXT3: MOV R0,#00H
RET
KCODE: MOV B,#0FBH
NEXT4: RRC A
INC B
JC NEXT4
MOV A,R1
SWAP A
NEXT5: RRC A
INC B
INC B
INC B
INC B
JC NEXT5
NEXT6: MOV A,P1
ANL A,#0FH
CJNE A,#0FH,NEXT6
MOV R0,#0FFH
RET
键盘处理程序就作这么一个简单的介绍,实际上,键盘、显示处理是很复杂的,
它往往占到一个应用程序的大部份代码,可见其重要性,但说到,这种复杂并不来自
于单片机的本身,而是来自于操作者的习惯等等问题,因此,在编写键盘处理程序之
前,最好先把它从逻辑上理清,然后用适当的算法表示出来,最后再去写代码,这样,
才能快速有效地写好代码。
键盘是由一组规则排列的按键组成,一个按键实际上是一个开关元件,也就是说
键盘是一组规则排列的开关。
键盘工作原理
1.按键的分类
按键按照结构原理可分为两类,一类是触点式开关按键,如机械式开关、导电橡
胶式开关等;另一类是无触点开关按键,如电气式按键,磁感应按键等。前者造价低,
后者寿命长。目前,微机系统中最常见的是触点式开关按键。
按键按照接口原理可分为编码键盘与非编码键盘两类,这两类键盘的主要区别是
识别键符及给出相应键码的方法。编码键盘主要是用硬件来实现对键的识别,非编码
键盘主要是由软件来实现键盘的定义与识别。
全编码键盘能够由硬件逻辑自动提供与键对应的编码,此外,一般还具有去抖动
和多键、窜键保护电路,这种键盘使用方便,但需要较多的硬件,价格较贵,一般的
单片机应用系统较少采用。非编码键盘只简单地提供行和列的矩阵,其它工作均由软
件完成。由于其经济实用,较多地应用于单片机系统中。下面将重点介绍非编码键盘
接口。
2.键输入原理
在单片机应用系统中,除了复位按键有专门的复位电路及专一的复位功能外,其
它按键都是以开关状态来设置控制功能或输入数据。当所设置的功能键或数字键按下
时,计算机应用系统应完成该按键所设定的功能,键信息输入是与软件结构密切相关
的过程。
对于一组键或一个键盘,总有一个接口电路与 CPU 相连。CPU 可以采用查询或
中断方式了解有无将键输入并检查是哪一个键按下,将该键号送入累加器 ACC,然
后通过跳转指令转入执行该键的功能程序,执行完后再返回主程序。
3.按键结构与特点
微机键盘通常使用机械触点式按键开关,其主要功能是把机械上的通断转换成为
电气上的逻辑关系。也就是说,它能提供标准的 TTL 逻辑电平,以便与通用数字系
统的逻辑电平相容。
机械式按键再按下或释放时,由于机械弹性作用的影响,通常伴随有一定时间的
触点机械抖动,然后其触点才稳定下来。其抖动过程如图 7.2 所示,抖动时间的长短
与开关的机械特性有关,一般为 5~10ms。
左图 按键触点的机械抖动
在触点抖动期间检测按键的通与断状态,可能导致判断出错。即按键一次按下或
释放被错误地认为是多次操作,这种情况是不允许出现的。为了克服按键触点机械抖
动所致的检测误判,必须采取去抖动措施,可从硬件、软件两方面予以考虑。在键数
较少时,可采用硬件去抖,而当键数较多时,采用软件去抖。
在硬件上可采用在键输出端加 R-S 触发器(双稳态触发器)或单稳态触发器构成去
抖动电路,图 7.3 是一种由 R-S 触发器构成的去抖动电路,当触发器一旦翻转,触点
抖动不会对其产生任何影响。
电路工作过程如下:按键未按下时,a = 0,b = 1,输出 Q = 1,按键按下时,
因按键的机械弹性作用的影响,使按键产生抖动,当开关没有稳定到达 b 端时,因与
非门 2 输出为 0 反馈到与非门 1 的输入端,封锁了与非门 1,双稳态电路的状态不会
改变,输出保持为 1,输出 Q 不会产生抖动的波形。当开关稳定到达 b 端时,因 a
= 1,b = 0,使 Q = 0,双稳态电路状态发生翻转。当释放按键时,在开关未稳定
到达 a 端时,因 Q = 0,封锁了与非门 2,双稳态电路的状态不变,输出 Q 保持不
变,消除了后沿的抖动波形。当开关稳定到达 b 端时,因 a = 0,b = 0,使 Q = 1,
双稳态电路状态发生翻转,输出 Q 重新返回原状态。由此 右图 双稳态去抖电路
可见,键盘输出经双稳态电路之后,输出已变为规范的矩形方波。
软件上采取的措施是:在检测到有按键按下时,执行一个 10ms 左右(具体时间
应视所使用的按键进行调整)的延时程序后,再确认该键电平是否仍保持闭合状态电
平,若仍保持闭合状态电平,则确认该键处于闭合状态;同理,在检测到该键释放后,
也应采用相同的步骤进行确认,从而可消除抖动的影响。
4.按键编码
一组按键或键盘都要通过 I/O 口线查询按键的开关状态。根据键盘结构的不同,
采用不同的编码。无论有无编码,以及采用什么编码,最后都要转换成为与累加器中
数值相对应的键值,以实现按键功能程序的跳转。
5.编制键盘程序
一个完善的键盘控制程序应具备以下功能:
(1)检测有无按键按下,并采取硬件或软件措施,消除键盘按键机械触点抖动
的影响。
(2)有可靠的逻辑处理办法。每次只处理一个按键,其间对任何按键的操作对
系统不产生影响,且无论一次按键时间有多长,系统仅执行一次按键功能程序。
(3)准确输出按键值(或键号),以满足跳转指令要求。
独立式按键
单片机控制系统中,往往只需要几个功能键,此时,可采用独立式按键结构。
1.独立式按键结构
独立式按键是直接用 I/O 口线构成的单个按键电路,其特点是每个按键单独占用
一根 I/O
左图 独立式按键电路
口线,每个按键的工作不会影响其它 I/O 口线的状态。独立式按键的典型应用如
图 7.4 所示。
独立式按键电路配置灵活,软件结构简单,但每个按键必须占用一根 I/O 口线,
因此,在按键较多时,I/O 口线浪费较大,不宜采用。
图 7.4 中按键输入均采用低电平有效,此外,上拉电阻保证了按键断开时,I/O
口线有确定的高电平。当 I/O 口线内部有上拉电阻时,外电路可不接上拉电阻。
2.独立式按键的软件结构
独立式按键软件常采用查询式结构。先逐位查询每根 I/O 口线的输入状态,如某
一根 I/O 口线输入为低电平,则可确认该 I/O 口线所对应的按键已按下,然后,再转
向该键的功能处理程序。图 7.4 中的 I/O 口采用 P1 口,请读者自行编制相应的软件。
7.1.3 矩阵式按键
单片机系统中,若使按键较多时,通常采用矩阵式(也称行列式)键盘。
1.矩阵式键盘的结构及原理
矩阵式键盘由行线和列线组成,按键位于行、列线的交叉点上,其结构如下图所
示。
由图可知,一个 4×4 的行、列结构可以构成一个含有 16 个按键的键盘,显然,
在按键数量较多时,矩阵式键盘较之独立式按键键盘要节省很多 I/O 口。
矩阵式键盘中,行、列线分别连接到按键开关的两端,行线通过上拉电阻接到+
5V 上。当无键按下时,行线处于高电平状态;当有键按下时,行、列线将导通,此
时,行线电平将由与此行线相连的列线电平决定。这是识别按键是否按下的关键。然
而,矩阵键盘中的行线、列线和多个键相连,各按键按下与否均影响该键所在行线和
列线的电平,各按键间将相互影响,因此,必须将行线、列线信号配合起来作适当处
理,才能确定闭合键的位置。
2.矩阵式键盘按键的识别
识别按键的方法很多,其中,最常见的方法是扫描法。下面以图 7.5 中 8 号键的
识别为例来说明扫描法识别按键的过程。
按键按下时,与此键相连的行线与列线导通,行线在无键按下时处在高电平,显
然,如果让所有的列线也处在高电平,那么,按键按下与否不会引起行线电平的变化,
因此,必须使所有列线处在低电平,只有这样,当有键按下时,该键所在的行电平才
会由高电平变为低电平。CPU 根据行电平的变化,便能判定相应的行有键按下。8 号
键按下时,第 2 行一定为低电平,然而,第 2 行为低电平时,能否肯定是 8 号键按下
呢?回答是否定的,因为 9、10、11 号键按下同样使第 2 行为低电平。为进一步确
定具体键,不能使所有列线在同一时刻都处在低电平,可在某一时刻只让一条列线处
于低电平,其余列线均处于高电平,另一时刻,让下一列处在低电平,依此循环,这
种依次轮流每次选通一列的工作方式称为键盘扫描。采用键盘扫描后,再来观察 8 号
键按下时的工作过程,当第 0 列处于低电平时,第 2 行处于低电平,而第 1、2、3
列处于低电平时,第 2 行却处在高电平,由此可判定按下的键应是第 2 行与第 0 列的
交叉点,即 8 号键。
3.键盘的编码
对于独立式按键键盘,因按键数量少,可根据实际需要灵活编码。对于矩阵式键
盘,按键的位置由行号和列号唯一确定,因此可分别对行号和列号进行二进制编码,
然后将两值合成一个字节,高 4 位是行号,低 4 位是列号。如图 7.5 中的 8 号键,它
位于第 2 行,第 0 列,因此,其键盘编码应为 20H。采用上述编码对于不同行的键离
散性较大,不利于散转指令对按键进行处理。因此,可采用依次排列键号的方式对安
排进行编码。以图 7.5 中的 4×4 键盘为例,可将键号编码为:01H、02H、03H…0E
H、0FH、10H 等 16 个键号。编码相互转换可通过计算或查表的方法实现。
4.键盘的工作方式
在单片机应用系统中,键盘扫描只是 CPU 的工作内容之一。CPU 对键盘的响应
取决于键盘的工作方式,键盘的工作方式应根据实际应用系统中 CPU 的工作状况而
定,其选取的原则是既要保证 CPU 能及时响应按键操作,又不要过多占用 CPU 的工
作时间。通常,键盘的工作方式有三种,即编程扫描、定时扫描和中断扫描。
1)编程扫描方式
编程扫描方式是利用 CPU 完成其它工作的空余调用键盘扫描子程序来响应键盘
输入的要求。在执行键功能程序时,CPU 不再响应键输入要求,直到 CPU 重新扫描
键盘为止。
键盘扫描程序一般应包括以下内容:
(1)判别有无键按下。
(2)键盘扫描取得闭合键的行、列值。
(3)用计算法或查表法得到键值。
(4)判断闭合键是否释放,如没释放则继续等待。
(5)将闭合键键号保存,同时转去执行该闭合键的功能。
图 7.6 8155 扩展 I/O 口组成的矩阵键盘
图 7.6 是一个 4×8 矩阵键盘电路,由图可知,其与单片机的接口采用 8155 扩展
I/O 芯片,键盘采用编程扫描方式工作,8155C 口的低 4 位输入行扫描信号,A 口输
出 8 位列扫描信号,二者均为低电平有效。8155 的 IO/ 与 P2.0 相连, 与 P2.1 相
连, 、 分别与单片机的 、 相连。由此可确定 8155 的口地址为:
命令/状态口:0100H(P2 未用口线规定为 0)
A 口:0101H
B 口:0102H
C 口:0103H
图 7.6 中,A 口为基本输出口,C 口为基本输入口,因此,方式命令控制字应设
置为 43H。在编程扫描方式下,键盘扫描子程序应完成如下几个功能:
(1)判断有无键按下。其方法为:A 口输出全为 0,读 C 口状态,若 PC0~PC
3 全为 1,则说明无键按下;若不全为 1,则说明有键按下。
(2)消除按键抖动的影响。其方法为:在判断有键按下后,用软件延时的方法
延时 10ms 后,再判断键盘状态,如果仍为有键按下状态,则认为有一个按键按下,
否则当作按键抖动来处理。
(3)求按键位置。根据前述键盘扫描法,进行逐列置 0 扫描。图 7.6 中,32 个
键的键值分布如下(键值由 4 位 16 进制数码组成,前两位是列的值,即 A 口数据,
后两位是行的值,即 C 口数据,X 为任意值):
FEXE FDXE FBXE F7XE EFXE DFXE BFXE 7FXE
FEXD FDXD FBXD F7XD EFXD DFXD BFXD 7FXD
FEXB FDXB FBXB F7XB EFXB DFXB BFXB 7FXB
FEX7 FDX7 FBX7 F7X7 EFX7 DFX7 BFX7 7FX7
按键键值确定后,即可确定按键位置。相应的键号可根据下述公式进行计算:键
号=行首键号+列号。图 7.6 中,每行的行首可给以固定的编号 0(00H),8(08H),
16(10H),24(18H),列号依列线顺序为 0~7。
(4)判别闭合的键是否释放。按键闭合一次只能进行一次功能操作,因此,等
按键释放后才能根据键号执行相应的功能键操作。
键盘扫描程序流程图请参阅实训 7 图 7.1 中的主程序流程图。
键盘扫描程序请参阅实训 7 源程序中的键盘查询程序、键盘扫描程序和按键查询
子程序三部分。
实训 7 是矩阵式键盘的一种典型应用,与图 7.6 相比,8155 入口地址不同,矩
阵键盘列数不同,再就是为兼顾键盘和显示,防抖所用的延时子程序由显示子程序替
代。
2)定时扫描方式:
定时扫描方式就是每隔一段时间对键盘扫描一次,它利用单片机内部的定时器产
生一定时间(例如 10ms)的定时,当定时时间到就产生定时器溢出中断,CPU 响应
中断后对键盘进行扫描,并在有键按下时识别出该键,再执行该键的功能程序。定时
扫描方式的硬件电路与编程扫描方式相同,程序流程图如下图所示。
图中,标志 1 和标志 2 是在单片机内部 RAM 的位寻址区设置的两个标志位,标
志 1 为去抖动标志位,标志 2 为识别完按键的标志位。初始化时将这两个标志位设置
为 0,执行中断服务程序时,首先判别有无键闭合,若无键闭合,将标志 1 和标志 2
置 0 后返回;若有键闭合,先检查标志 1,当标志 1 为 0 时,说明还未进行去抖动处
理,此时置位标志 1,并中断返回。由于中断返回后要经过 10ms 后才会再次中断,
相当于延时了 10ms,因此,程序无须再延时。下次中断时,因标志 1 为 1,CPU 再
检查标志 2,如标志 2 为 0 说明还未进行按键的识别处理,这时,CPU 先置位标志 2,
然后进行按键识别处理,再执行相应的按键功能子程序,最后,中断返回。如标志 2
已经为 1,则说明此次按键已做过识别处理,只是还未释放按键,当按键释放后,在
下一次中断服务程序中,标志 1 和标志 2 又重新置 0,等待下一次按键。
3)中断扫描方式
采用上述两种键盘扫描方式时,无论是否按键,CPU 都要定时扫描键盘,而单
片机应用系统工作时,并非经常需要键盘输入,因此,CPU 经常处于空扫描状态,
为提高 CPU 工作效率,可采用中断扫描工作方式。其工作过程如下:当无键按下时,
CPU 处理自己的工作,当有键按下时,产生中断请求,CPU 转去执行键盘扫描子程
序,并识别键号。
左图是一种简易键盘接口电路,该键盘是由 8051P1 口的高、低字节构成的 4×4
键盘。键盘的列线与 P1 口的高 4 位相连,键盘的行线与 P1 口的低 4 位相连,因此,
P1.4~P1.7 是键输出线,P1.0~P1.3 是扫描输入线。图中的 4 输入与门用于产生按键
中断,其输入端与各列线相连,再通过上拉电阻接至+5V 电源,输出端接至 8051 的
外部中断输入端 。具体工作如下:当键盘无键按下时,与门各输入端均为高电平,
保持输出端为高电平;当有键按下时,端为低电平,向 CPU 申请中断,若 CPU 开放
外部中断,则会响应中断请求,转去执行键盘扫描子程序。
这是初学时写的最简单、最详细、效率最高的矩阵键盘扫描程序,只用了四条常
用命令(MOV/送数、JB/高电平转移、JMP/直接转移、RET/子程序返回),保证初
学者一看就懂!本程序已经在本站电子实验板上验证通过,占用CPU时间少,效率
高,被选作单片机的测试程序!
矩阵按键扫描程序是一种节省 IO 口的方法,按键数目越多节省 IO 口就越可观,
本程序的思路跟书上一样:先判断某一列(行)是否有按键按下,再判断该行(列)
是那一只键按下。但是,在程序的写法上,站长采用了最简单的方法,使得程序效率
最高。
本程序中,如果检测到某键按下了,就不再检测其它的按键,这完全能满足绝大
多数需要,又能节省大量的 CPU 时间。另外,本人认为键盘用延时程序来消除抖动,
完全是浪费时间。试想,如果不用中断执行(用中断执行需要更多的硬件资源)的方
法来扫描键盘,每秒钟扫描20-100次,每次都要延时10-20MS的话,我
们的单片机还有多少时间做正事呢?
其实,延时的这段时间,CPU 可以做其它的事呀。所以,本键盘扫描程序的前
面后面都可以加入少少代码,既可以达到完美的消抖动效果,又可以扩展其它的功能
(例如按键封锁、按键长按等按键功能复用!)
本键盘扫描子程序名叫 key,每次要扫描时用 call key 调用即可。以下子程序内
容:
key:mov p0,#00001111b;上四位和下四位分别为行和列,所以送出高低电压检查
有没有按键按下
jmp k10;跳到 K10 处开始扫描,这里可以改成其它条件转移指令来决定本次扫
描是否要继续,例如减 1 为 0 转移或者位为 1 或 0 才转移,这主要用来增加功能,确
认上一按键功能是否完成?是否相当于经过了延时?是否要封锁键盘?
goend:jmp kend;如果上面判断本次不执行键盘扫描程序,则立即转到程序尾部,
不要浪费 CPU 的时间