矩阵键盘扫描程序的改进
改进前:
unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法
{
unsigned char Val;
KeyPort=0xf0;//高四位置高,低四位拉低
if(KeyPort!=0xf0)//表示有按键按下
{
DelayMs(10); //去抖
if(KeyPort!=0xf0)
{ //表示有按键按下
KeyPort=0xfe; //检测第一行
if(KeyPort!=0xfe)
{
Val=KeyPort&0xf0;
Val+=0x0e;
while(KeyPort!=0xfe);
DelayMs(10); //去抖
while(KeyPort!=0xfe);
return Val;
}
KeyPort=0xfd; //检测第二行
if(KeyPort!=0xfd)
{
Val=KeyPort&0xf0;
Val+=0x0d;
while(KeyPort!=0xfd);
DelayMs(10); //去抖
while(KeyPort!=0xfd);
return Val;
}
KeyPort=0xfb; //检测第三行
if(KeyPort!=0xfb)
{
Val=KeyPort&0xf0;
Val+=0x0b;
while(KeyPort!=0xfb);
DelayMs(10); //去抖
while(KeyPort!=0xfb);
return Val;
}
KeyPort=0xf7; //检测第四行
if(KeyPort!=0xf7)
{
Val=KeyPort&0xf0;
Val+=0x07;
while(KeyPort!=0xf7);
DelayMs(10); //去抖
while(KeyPort!=0xf7);
return Val;
}
}
}
return 0xff;
}
unsigned char KeyPro(void)
{
switch(KeyScan())
{
case 0x7e:return 0;break;//0 按下相应的键显示相对应的码值
case 0x7d:return 1;break;//1
case 0x7b:return 2;break;//2
case 0x77:return 3;break;//3
case 0xbe:return 4;break;//4
case 0xbd:return 5;break;//5
case 0xbb:return 6;break;//6
case 0xb7:return 7;break;//7
case 0xde:return 8;break;//8
case 0xdd:return 9;break;//9
case 0xdb:return 10;break;//a
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
改进后:
unsigned char pcf8574_key_number(void)
{
unsigned char key_number=0;
//key_board PCF8574 write byte
KeyPort=0xf0;
key_number=KeyPort;
if(key_number!= 0xf0)
{
delay_5us(2);//delay 10us
if(key_number!= 0xf0)
{
//key_board PCF8574 write byte
KeyPort=0x0f;
key_number |= KeyPort;//key_board PCF8574 read byte
}
}
//SendData(key_number);//test
return key_number;
}
unsigned char key_board_number(void)
{
unsigned char key_number=0;
switch(pcf8574_key_number())
{
case 0X7E:key_number=1;break;
case 0X7D:key_number=2;break;
case 0X7B:key_number=3;break;
case 0X77:key_number=4;break;
case 0XBE:key_number=5;break;
case 0XBD:key_number=6;break;
case 0XBB:key_number=7;break;
case 0XB7:key_number=8;break;
case 0XDE:key_number=9;break;
case 0XDD:key_number=10;break;
case 0XDB:key_number=11;break;
case 0XD7:key_number=12;break;
case 0XEE:key_number=13;break;
case 0XED:key_number=14;break;
case 0XEB:key_number=15;break;
case 0XE7:key_number=16;break;
default:break;
}
return key_number;
}
改进之后还得改进呢!
请把指点几条程序
case 0X7E:key_number=1;break;
case 0X7D:key_number=2;break;
case 0X7B:key_number=3;break;
case 0X77:key_number=4;break;
case 0XBE:key_number=5;break;
case 0XBD:key_number=6;break;
case 0XBB:key_number=7;break;
case 0XB7:key_number=8;break;
case 0XDE:key_number=9;break;
case 0XDD:key_number=10;break;
case 0XDB:key_number=11;break;
case 0XD7:key_number=12;break;
case 0XEE:key_number=13;break;
case 0XED:key_number=14;break;
case 0XEB:key_number=15;break;
case 0XE7:key_number=16;break;
其实这里可以做加法和乘法运算的。这样会更简洁。
能否写出完整程序,你说的不太理解
可以。
switch(KC_temp)
{
case 0x0e:
KC_key_temp=0+4*KC_row;
break;
case 0x0d:
KC_key_temp=1+4*KC_row;
break;
case 0x0b:
KC_key_temp=2+4*KC_row;
break;
case 0x07:
KC_key_temp=3+4*KC_row;
break;
}
你是列了16次,我是4次。当然这个东西只要在多的时候才能提现出来。
KC_row这个变量的数据传输来源是什么,因为在我改进后的程序里,不是一行一行扫描,而是全部扫描。改进后的程序的特点也在这里,缩短了扫描时间。提高了内寸的利用率
我想问下电路图不知道,为什么你写程序时知道检测第一行是0xfe呢?而不是0xef呢
这个FE和EF没有多大区别,主要看你是横着扫描,还是竖着扫描
