文档库 最新最全的文档下载
当前位置:文档库 › c51矩阵键盘检测新思路

c51矩阵键盘检测新思路

#ifndef _METRIX_KEY_H_
#define _METRIX_KEY_H_


/*名称:unsigned char matrixScan()
* 参数:void,但是使用全局的键盘端口keyPort变量,对keyPort的要求是:低四位是
* 矩阵的行,高四位是矩阵列
* 功能:扫描4*4的矩阵键盘,检测按键按下,并将按键转换成对应的键值。
* 返回:unsigned char。若有键按下,返回键值[0,15] or [0x00,0x0F]。没有键按下
* 或者检测期间按键释放则返回 NO_KEY_DOWN(0xFF)
* 版署:汪涛涛 wangtaotao0829@https://www.wendangku.net/doc/03731574.html, 2012.3.9
* 优点:看的几乎所有的检测矩阵键盘的代码都是16个case分支,对每一个键都进行了
* “不折不扣”挨个检测,没有全局的思想,导致代码长、变量多(每个按键都得
* 定义,有的还得用编码数组来协助检测),时间复杂度和空间复杂度大打折扣!
* 而且代码的聚合度也很差,大量使用全局变量。
* 这个函数是在2012.3.9 21时诞生,于2012.3.10 9时做稍微优化调整。思想
* 是先所有列置零,锁定按键的行,再所有行置零,锁定列位置,再用二维数组计
* 算偏移的方法算出按键的值。只用两个字节的空间,分别记录行列位置;只需两
* 次两次扫描就能确定按键值;只需一个全局变量(键盘的端口)就能完成工作,
* 具有运行高效(代码中的延时部分有待改善)、空间节省、内聚度高、稳定性好
* ,通过了长达40分钟的胡乱按键测试,代码中还消除了检测异常的情况。
*/
unsigned char matrixScan()
{
unsigned char row; //按键的行位置
unsigned char column; //按键的列位置

keyPort = 0x0F;
//0.检测是否有按键按下,如果对应行端口没有变化,说明没有键按下,结束当前扫描
if(keyPort == 0x0F)
return NO_KEY_DOWN;

//1.延时10ms,软件消抖
delayms(10);

//2.列全部置零,锁定行信息
switch(keyPort){
case 0x0E: row = 0x00; break; //0000 1110b 第一行有按键按下
case 0x0D: row = 0x01; break; //0000 1101b 第二行有按键按下
case 0x0B: row = 0x02; break; //0000 1011b 第三行有按键按下
case 0x07: row = 0x03; break; //0000 0111b 第四行有按键按下
default : row = NO_KEY_DOWN; //防止检测期间按键释放
}

//3.行全部置零,锁定列信息
keyPort = 0xF0;
switch(keyPort){
case 0xE0: column = 0x00; break; //1110 0000b 第一列有按键按下
case 0xD0: column = 0x01; break; //1101 0000b 第二列有按键按下
case 0xB0: column = 0x02; break; //1011 0000b 第三列有按键按下
case 0x70: column = 0x03; break; //0111 0000b 第四列有按键按下
def

ault : column = NO_KEY_DOWN; //防止检测期间按键释放
}

//4.等待按键结束
keyPort = 0xF0;//or 0x0F
while(keyPort != 0xF0)
;
//5.折算出按键值,排除检测期间按键释放的情况
return (row!=NO_KEY_DOWN && column!=NO_KEY_DOWN) ? (row*4+column) : NO_KEY_DOWN;
}


#endif //End of #ifndef and End of file

相关文档
相关文档 最新文档