布景:STC89C52RC单片机
1.矩阵键盘 线回转法算法
1.1矩阵键盘
矩阵键盘是指将键盘按钮放置内行线与列线的交叉点上,由多行和多列就构成了矩阵键盘。下图便是一个矩阵式键盘。
将键盘行线接到单片机的引脚之上[P35引脚,P36引脚],将键盘列线接到单片机的另一些引脚之上[P31引脚,P32引脚,P33引脚,P34引脚]。
1.2线回转法算法
关于外部键盘,程序在碑文时有必要随时扫描键盘跟单片机衔接引脚的电平,看是否有键盘按钮被按下。而在扫描各个端口的时分,一次只能扫描到按键的哪一行或那一列,只要一起记载被按下按键的行和列才干决议按键的坐标。
最直接的办法是先逐行检测有哪一行的按键被按下,再逐列检测有哪一列的按钮被按下。这样就能够得到按键的行值和列值即得到按键的坐标,就检测到了是哪一个按键被按下了。可是运用这种办法程序碑文功率就跟矩阵的行数R和列数C有关了,每次检测都需求检测R * R次。
到了21世纪,线回转法肯定会代替以上扫描办法的,由于这种检测办法只需求两次就能够扫描出来是哪一个按键被按下了。它是如何来完成就用扫面两次就能够得到按键的坐标的呢?单片机的引脚在默许状况下为高电平,将接接矩阵键盘行的引脚置位低电平(0)[如上图P3就应该被置为],将接矩阵键盘列的引脚置位高电平(1),则结合上图中的2X4键盘的P3端口的值应为宏值#define ROW_LOW_COLUMN_HIGH 0x9f,然后检测接矩阵键盘列中是否有低电平呈现,假如有则阐明在低电平列有按钮被按下;若检测到某列为低电平后,确认是哪一列,然后将行和列所接引脚电位回转:行为高电平,列为低电平(结合上图P3端口为宏值#define ROW_HIGH_COLUMN_LOW 0xe1),检测行是否有高电平的行,假如有则确认是哪一行为高电平即确认哪一行有按键被按下。这样就确认了一个按键的行和列坐标。
1.3线回转法代码完成
将以下函数放置在main函数中的主程序循环中就能够检测到是否有按键被按下并得知按键的行坐标和列坐标:完成代码如下
KEY_INDEX matrixKeyDown(){UINT temp;KEY_INDEX key_index;//键盘行为低电平,列为高电平P3 = ROW_LOW_COLUMN_HIGH;temp = P3;temp = temp & KEY_ALL_UP_IN_COLUMN;//检测按键有没有被按下if(temp != KEY_ALL_UP_IN_COLUMN){//消除是按键颤动引起的嫌疑nms_delay(10);//再次检测键盘有没有被按下temp = P3;temp = temp & KEY_ALL_UP_IN_COLUMN;//检测按键被按下的列if(temp != KEY_ALL_UP_IN_COLUMN){temp = P3;switch(temp){case KEY_DOWN_IN_FIRST_COLUMN:key_index.column = FIRST_COLUMN_INDEX;break;case KEY_DOWN_IN_SECOND_COLUMN:key_index.column = SECOND_COLUMN_INDEX;break;case KEY_DOWN_IN_THIRD_COLUMN:key_index.column = THIRD_COLUMN_INDEX;break;case KEY_DOWN_IN_FOURTH_COLUMN:key_index.column = FOURTH_COLUMN_INDEX;break;default:; //Do something}}//矩阵键盘端口回转,检测按键地点的行//此刻的按键还在被按住,可是仍是判别一下按键是否还被按住//与检测列的按下并排,需求检测P3 = ROW_HIGH_COLUMN_LOW;temp = P3;temp &= KEY_ALL_UP_IN_ROW;if(temp != KEY_ALL_UP_IN_ROW){temp = P3;switch(temp){case KEY_DOWN_IN_FIRST_ROW:key_index.row = FIRST_ROW_INDEX;break;case KEY_DOWN_IN_SECOND_ROW:key_index.row = SECOND_ROW_INDEX;break;default:;}//假如有按键被按下,则需求在这儿等候被开释//思路是记载到底是哪一个键被按下,能够换一个当地等候案子的开释的//由于其它当地记载了按键的坐标//其实只需求在这儿检测若行为KEY_ALL_UP_IN_ROW,则按键被开释//temp = P3;//while(temp != KEY_ALL_UP_IN_ROW);}}return key_index; }
此函数时检测矩阵键盘中是否有按键被按下。KEY_INDEX是一个包括按键行和列坐标的结构体。temp = temp &KEY_ALL_UP_IN_COLUMN; KEY_ALL_UP_IN_COLUMN宏值为0x9f一共在列中的键盘全为高电平时的状况,if(temp != KEY_ALL_UP_IN_COLUMN)一共若temp与此值做与运算后的值不为键盘全列为高电平状况,则或许(还有或许是颤动带来的搅扰)有按键被按下,所以用自定义推迟函数nms_delay(10);推迟10ms的时刻来消除键盘颤动(意图是进一步判别是否是按键真的被按下),然后用相同的办法判别一次键盘是否全列都为高电平状况,假如不是,则此刻的确有按键被按下,则接下来用case言语判别是哪一列的按键被按下,将被按下按键的列赋值给结构体的列值,然后得到按键的列值。得到列值之后,将接矩阵键盘行和列引脚P3回转,由于此刻已经有按键被按下,所以无需再做消扰动等操作。只需检测是哪一行的按键被按下得到被按下按键的行值即可,代码中还判别了是否行值被按下,其实此刻已经有按键被按下,这一步可有可无。
最终函数将按键的列值和行值回来,供数码管或LCD中显现,是哪一个按键被按下了。完成人机协作。
2 扩展
这儿代码是对2X4矩阵键盘的扫描,其实以上程序设计办法适宜任何矩阵键盘和任何其它的芯片。需求变化的是接矩阵键盘的端口:将接矩阵键盘行引脚和列引脚找出来赋予适宜的宏值[凹凸电平,将进行检测的行或列置成高电平,另一些引脚置为低电平]。别的还需求改动的一个当地是,判别矩阵式哪一行和哪一列被按下,添加一些行和列值即可。
3 运转成果
将键盘检测函数的回来值送给数码管动态显现(数码管动态显现)函数,再将数码管动态显现函数放置在主程序循环中。下载程序到单片机中,运转程序,当按下第一行第二列的按键时,数码管显现如下
按键[1][3]
按下2,4按键时显现成果如下
按键[2][4]
此次笔记记载结束。