51 线反转法 实现矩阵键盘检测
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语言判断是哪一列的按键被按下,将被按下按键的列赋值给结构体的列值,从而得到按键的列值。得到列值之后,将接矩阵键盘行和列引脚
51线反转法矩阵键盘检 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)