四个矩阵按键开关单片机检测程序及其应用特点的分析
2021-06-30长沙市电子工业学校刘国云
长沙市电子工业学校 刘国云
相对于独立按键,矩阵按键开关具有占用单片机端口资源少的优点,也有其教学难的缺点。有多种方法实现矩阵按键开关检测功能,作为经验交流,笔者介绍了四个不同的矩阵按键开关检测程序,并分析了它们的检测方法和应用特点,与职教同行共同开拓编程思路、提高编程能力和教学能力。
按键是单片机控制的重要的指令开关,相对于独立按键,矩阵按键开关具有占用单片机端口少的资源优势,同时也给使用者带来了难学、难记、难写、检测程序复杂的缺点。我在此介绍用四种不同方法编写的4×4矩阵开关检测程序,并对程序和它们优缺点进行分析,以加深大家对矩阵开关检测原理和编程方法的理解,开拓编程思路,掌握多个可以在不同场合应用的矩阵开关检测程序,以提高大家程序分析能力、编程能力和教学能力。
1 用switch-case语句编写矩阵按键开关检测程序
图1所示程序用P3总线控制方式和switch-case语句,对4*4矩阵按键开关进行检测,P3.4-P3.7和P3.3-P3.0分别为行线h0-h3和列线l0-l3的控制端口。其编程思路是用P3总线赋值方式,依次将4根行线电平拉低,每拉低一根行线电平,就依次对4根列线上的按键进行检,如果哪根列线被检测到低电平,就表示该行该列上的按键按下。现以拉低第一行电平、依次检测4列电平为例,来讲解该程序是如何使用switch-case语句捕捉到按键和获得键值的。
图1 switch-case语句矩阵按键开关检测程序
首先让P3=0xff,排除干扰电平,然后迅速让P3=0xef,拉低接在P3.4上的第一条行线h0的电平,并让局部变量i=P3=0xef,接着i与0xf0逐位与(i=0xe0&0xf0=0xe0!=0xf0),执行if(i!=0xf0)条件语句,程序指针指向由switch-case语句组成的4条列线检测程序。
因为按键按下会改变P3值,条件语句中i=P3的i值也会改变,通过switch(i){case 0xe7:jianzhi=1;break;case 0xeb:jianzhi=2;break;case 0xe7:jianzhi=1;break;case 0xeb:jianzhi=2;break;}来检测列线电平,捕获按下的按键开关和获取键值。
至于while(i!=0xf0){xianshi();xianshi();xianshi();xianshi();
xianshi();i=0xf0;}的作用是通过调用显示子程序起到延时作用,给按键提供释放时间,最后让i=0xf0,退出while循环。
该矩阵开关检测程序的特点是:端口8位总线控制,控制端口选用灵活性不强;程序代码多。
2 用数组检测码编写矩阵开关检测程序(图2)
图2 用数组检测码编写的矩阵按键开关检测程序
该检测程序的特点也是端口8位总线控制,检测端口选用不灵活,但程序代码少了很多。它的编程思路是:定义了拉低行线电平的数组hl3[4]、依次检测4条列线电平的二维数组hl1[4][4]及保存键值的二维数组hl2[4][4]。然后用两个嵌套的for循环语句实现按键检测,4次外循环是依次拉低4根行线电平(P3=0xff;P3=hl3[i];)。内循环是依次检测4根列线,如果检测到P3值等于检测码,就捕获按键,获取键值(if(P3==hl1[i][j])jianzhi=hl2[i][j];)。
语句while(P3==hl1[i][j]);是用来等待按键释放。
3 用循环移动功能函数编写矩阵按键开关检测程序(图3)
图3 用循环功能函数编写的矩阵开关检测程序
该检测程序的最大优点是代码少。它定义了一个键值二维数组ka[4][4],也用两级嵌套的for循环分别拉低行线电平和依次检测列线电平。这个程序比图2中用数组检测检测码编写的矩阵开关检测程序代码更少的原因就是利用了功能循环函数_crol_()来拉低行线电平和检测列线电平。
外循环的P3=_crol_(0xef,i),通过将0xef左移1、2、3、4位来实现拉低行线电平的。内循环的列线检测和获取键值是通过if((P3&__cror_(0x08,j))==0)jianzhi=ka[i][j]实现的。
4 用位控制指令编写矩阵按键开关检测程序
上面3个矩阵按键开关检测程序中的第三个程序最简单,第一个程序最复杂,但它们都有一个共同特点:采用8位总线控制方式,所以单片机检测端口选择的灵活性不强。现在介绍一个程序代码不是最少,但检测方法最直观、编程思路最清晰、端口选用最灵活,如图4所示的用位控制指令编写的矩阵按键开关检测程序。
图4 位控制指令矩阵按键开关检测程序
该程序的编程思路是:先声明4行和4列位控信号h0-h3和l0-l3(sbit h0=P3^4;sbit h1=P3^5;sbit h2=P3^6;sbit h3=P3^7;sbit l0=P3^0;sbit l1=P3^1;sbit l2=P3^2;sbit l3=P3^3;),然后在矩阵开按键关检测程序jzjc()中,首先让所有行列信号置1,去除干扰信号,再逐行拉低一行电平,用if-else if-else if-if语句逐列检测,并取出所检测到的键值k。
还有一个需要特别提醒的是:该矩阵按键开关检测程序不是空函数,而是带返回值k的子程序。
图4所示的矩阵按键开关检测程序由于是用位控指令来编写的,相较前面3个总线控制的矩阵按键开关检测程序,它的最大优点就是检测端口的选用非常灵活,美中不足就是程序代码比稍多点,有意使用该程序的话,可以用图5的形式来简化。
图5 图4程序的简化程序
结语:作为中职教师,在讲解同一个任务的控制程序时,应该具有多种解决方案,以方便学生在不同的应用场合使用,培养他们的开放思维能力和创新应用能力。笔者通过介绍四种不同矩阵按键开关检测程序,希望能与同行分享不同的编程方法,开阔编程视野,共同提高编程能力和教学能力。