14.2 矩阵式键盘C51程序设计
在实际应用中,大多采用矩阵式键盘。在程序设计中,矩阵式键盘的扫描和检测有3种方法,即扫描法、线反转法和中断法。
14.2.1 扫描法及C51程序设计
扫描法是在程序中逐行或者逐列扫描查询键盘接口,根据端口的输入情况,判断是哪一个按键被按下,然后分别调用不同的按键处理子程序。这里以4×4矩阵式键盘为例介绍列扫描法。
在使用列扫描时,矩阵式键盘的电路结构如图14.3所示,其中应将矩阵式键盘的行
图 14.3 扫描法的电路结构
线通过上拉电阻接正电源。此时,如果没有按键按下,则对应的行线为高电平;如果有按键按下,对应交叉点的行线和列线短路,行线的输出依赖于与此行连
接的列的电平状态。由此逐列扫描键盘,便可以实现矩阵式键盘的检测。
1.扫描法的流程
键盘扫描法的流程图如图14.4所示。键盘扫描的一般步骤如下。
(1)判断按键是否按下。在程序中将列线(Y0~Y3)全部输出为“0”,此时读行线(X0~X3)的状态。如果行线全为“1”,则表示此时没有任何按键按下;如果行线不全为“1”,表示有按键按下。进而继续执行下面的步骤。
(2)按键去抖动。当判断有按键按下之后,程序中延时10ms左右的时间,然后再次判断键盘的状态。如果仍然处于按键按下的状态,则便可以肯定有按键按下,否则将当做按键的机械抖动。
图 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运行时间。并且尽可能将键盘扫描安排在程序空余的时候,以满足实时准确响应按键请求的目的。