文档库 最新最全的文档下载
当前位置:文档库 › 矩阵键盘的三种扫描方法

矩阵键盘的三种扫描方法

都是经过实际验证的,可以直接使用,就是最后一个我在用的时候,读不出键值来,不知为什么,也懒得在看了,第一个,第二个绝对没问题的,个人感觉第二个更好用点,在转载的那个人看到的好像是要线反转法时,必须是双向口,51单片机什么口是双向口啊,求高人指点!


行反转法的基本概念是:
行列线的交叉位置布置按键。所有行和列加上拉电阻。
所有行作输出先送低电平,然后读入列值。 如果有任意键按下,那么一定对应列值有0出现,也就知道了按下的键所在列。
反过来驱动这一列为0,其他列为1。把行作输入。就可以判断按下的键所在行。

uchar keyscan()
{
uchar i=0,j=0,key;
P3=0xf0; // 高位拉高,低位拉低
if(((~P3)&0xf0)!=0)
{
delay(10);
if(((~P3)&0xf0)!=0)
{
P3=0xfe;
while(((~P3)&0x0f)!=0) // 此语句保证只扫描四行
{
if(((~P3)&0xf0)!=0)
{
switch((~P3)&0xf0)
{
case 0x10:
j=0;break;
case 0x20:
j=1;break;
case 0x40:
j=2;break;
case 0x80:
j=3;break;
}
return(4*i+j);
}
else
{
P3=P3<<1; //循环4次
i++;
}
}
}
}
return (key) ;
}

/**************************************************************
* 功能:P3外接4×4按键, 按照查表法读出键值
* 返回:按键值0~15/如无键按下, 返回16
***************************************************************/
/*uchar keyscan(void)
{
uchar code K_Tab[4][4] = {
0xee, 0xde, 0xbe, 0x7e, 0xed, 0xdd, 0xbd, 0x7d,
0xeb, 0xdb, 0xbb, 0x7b, 0xe7, 0xd7, 0xb7, 0x77};
uchar temp1 = 0xfe, temp2, i, j;
for(i = 0; i < 4; i++)
{ //扫描低四位
P3 = temp1; //输出一行0
temp2 = P3; //马上就读入
if((temp2 & 0xf0) != 0xf0) //如果有键按下
{
for(j = 0; j < 4; j++) //就扫描高四位
if(temp2 == K_Tab[i][j]) //查表
return i * 4 + j; //查到了就返回按键的数值
}
else temp1 = _crol_(temp1, 1);
}
return 16; //没有查到,返回按键松开的代码
} */ //呵呵,实质性的语句不过9行,就是这么简练!

/************************************************************

**
* 名称:KeyRvs()
* 功能:P1外接4×4按键, 按照反转法读出键值
* 输出:按键值0~15/如无键按下, 返回16
*按键的键值分布图:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
***************************************************************/
uchar keyscan(void)
{
uchar temH, temL;
uchar key_value;
P3 = 0xf0;
if(P3 != 0xf0)
{
delay(5); //消抖
if(P3 != 0xf0) //的确是有按键被按下
{
P3 = 0xf0; temH = P3; //低四位先输出0;读入,高四位含有按键信息
P3 = 0x0f; temL = P3; //然后反转输出0;读入,低四位含有按键信息
switch(temH) {
case 0xe0: key_value = 0; break;
case 0xd0: key_value = 1; break;
case 0xb0: key_value = 2; break;
case 0x70: key_value = 3; break;

default: return 16;//按下的不是上述按键,就当是没有按键
}

switch(temL)
{
case 0x0e: return key_value;
case 0x0d: return key_value + 4;
case 0x0b: return key_value + 8;
case 0x07: return key_value + 12;

default: return 16;//按下的不是上述按键,就当是没有按键
}
}
}
}//本程序虽然稍多几行,但是没有循环,还可以提前返回,所以执行的速度最快

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