14.2 矩阵式键盘C51程序设计

在实际应用中,大多采用矩阵式键盘。在程序设计中,矩阵式键盘的扫描和检测有3种方法,即扫描法、线反转法和中断法。

14.2.1 扫描法及C51程序设计

扫描法是在程序中逐行或者逐列扫描查询键盘接口,根据端口的输入情况,判断是哪一个按键被按下,然后分别调用不同的按键处理子程序。这里以4×4矩阵式键盘为例介绍列扫描法。

在使用列扫描时,矩阵式键盘的电路结构如图14.3所示,其中应将矩阵式键盘的行

14.2 矩阵式键盘C51程序设计 - 图1

图 14.3 扫描法的电路结构

线通过上拉电阻接正电源。此时,如果没有按键按下,则对应的行线为高电平;如果有按键按下,对应交叉点的行线和列线短路,行线的输出依赖于与此行连

接的列的电平状态。由此逐列扫描键盘,便可以实现矩阵式键盘的检测。

1.扫描法的流程

键盘扫描法的流程图如图14.4所示。键盘扫描的一般步骤如下。

(1)判断按键是否按下。在程序中将列线(Y0~Y3)全部输出为“0”,此时读行线(X0~X3)的状态。如果行线全为“1”,则表示此时没有任何按键按下;如果行线不全为“1”,表示有按键按下。进而继续执行下面的步骤。

(2)按键去抖动。当判断有按键按下之后,程序中延时10ms左右的时间,然后再次判断键盘的状态。如果仍然处于按键按下的状态,则便可以肯定有按键按下,否则将当做按键的机械抖动。

14.2 矩阵式键盘C51程序设计 - 图2

图 14.4 键盘扫描法的流程图

(3)扫描按键的位置,这是扫描法的主要步骤。程序中,首先先令列线Y0输出“0”,其余3根列线均输出“1”。然后读取行线的状态,如果行线(X0~X3)均为高电平,则Y0这一列上没有按键按下,如果行线(X0~X3)不全为高电平,则表示其中为低电平的行线与Y0相交的按键被按下。如果列Y0没有按键按下,然后按照同样的方法依次检查Y1、Y2和Y3列有没有按键按下。这样通过逐列扫描,便可以找到按键的坐标位置(X,Y),也就是键值。

(4)按键程序处理。根据按键的键值,执行相应的程序处理子程序。有时候,为了保证一次按键只执行一次程序处理,可以判断按键是否释放,如果按键释放则再次开始按键扫描操作。

2.扫描法C51程序设计

这里假定8051单片机P1端口外接矩阵式键盘,矩阵式键盘的列线(Y0~Y3)接单片机P1.0~P1.3,而行线(X0~X3)接P1.4~P1.7。C51语言中,键盘列扫描子程序示例如下。


int KeyScan()

{

unsigned char k,k_temp;

P1=0xF0;//低位置0,准备查询按键

k=P1;//取得当前P1口的状态

if(k!=0xF0)

{//如果有变化则表示有键按下

delay();//延时,进行去抖动

k_temp=P1;

if(k==k_temp)//确实有按键按下

{

k=0xFE;

do//循环扫描每一列

{

P1=k;

if(k!=P1)

{

switch(P1)//判断按键,并返回键值

{

//第1列

case 0x7e:{return 0;break;}//返回键值0

case 0xbe:{return 1;break;}//返回键值1

case 0xde:{return 2;break;}//返回键值2

case 0xee:{return 3;break;}//返回键值3

//第2列

case 0x7d:{return 4;break;}//返回键值4

case 0xbd:{return 5;break;}//返回键值5

case 0xdd:{return 6;break;}//返回键值6

case 0xed:{return 7;break;}//返回键值7

//第3列

case 0x7b:{return 8;break;}//返回键值8

case 0xbb:{return 9;break;}//返回键值9

case 0xdb:{return 10;break;}//返回键值10

case 0xeb:{return 11;break;}//返回键值11

//第4列

case 0x77:{return 12;break;}//返回键值12

case 0xb7:{return 13;break;}//返回键值13

case 0xd7:{return 14;break;}//返回键值14

case 0xe7:{return 15;break;}//返回键值15

}

}

k=crol(k,1);//移位,进入下一列扫描

}while(k!=0xEF);//超过范围,退出列扫描

}

}

}


在该程序中,首先置行全为0,然后读端口P1。如果P1端口不为0xF0,则表示有按键动作,然后执行延时程序delay()后,再次判断以确定按键按下。接着,通过do-while循环以及移位操作,来逐列扫描以确定按键的位置并返回键值。

在程序中可以循环调用该子程序来扫描按键的输入,进而根据返回的键值来执行相应的程序处理。由于在执行按键处理子程序的时候,单片机不能再次响应按键请求。因此,单片机的按键处理子程序应该尽可能执行少的任务,占用少的CPU运行时间。并且尽可能将键盘扫描安排在程序空余的时候,以满足实时准确响应按键请求的目的。