这里有两段程序有关键盘扫描的,其中一段是正确的:针对4x4键盘的,其中P1口的P1.0-P1.3做行线,P1.4-P1.7做列线,16个按键输出0 -F。另一段就是我修改后出问题的程序,修改的目的是将该4x4键盘拓展为5x4键盘,增加P3.0口为行线的第一行,P1.0-P1.3为第二至第五行, P1.4-P1.7做列线,前16个按键输出0-F,最后一行做其他功能键(在其他程序段中定义功能)。 键盘本来应是按相应的按键在数码管上显示相应的字型: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J 结果现在的现象是:现在只有第一列按键按下数码管显示,但显示的是最后一列的数,即第一列本应显示0 4 8 C G但却显示3 7 B F J,而 其余三列按下无反应,不显示。 另外,程序中按键编码是这样编出的:4x4键盘中,若“0”键按下,则P1.7-P1.0依次为1110 1110,所以“0”键编码为EE;5x4键盘中,“0” 我相应的编码成P1.7-P3.0依次为1110 11110,即“0”键编码为1DE,不知道这样的编码是不是也有问题。 另外,我使用的是MC14489显示驱动电路,所以不用进行字型(0-F)的编码。 不知道原因在哪里,麻烦各位了!谢谢
正确的4*4键盘扫描程序 code uchar keytab[16] = {0xEE,0xDE,0xBE,0x7E,0xED,0xDD,0xBD, 0x7D,0xEB,0xDB,0xBB,0x7B,0xE7,0xD7, 0xB7,0x77}; //键编码,0-F
uchar kbscan(void);
uchar kbscan(void) { uchar sccode,recode; P1 = 0xf0; //P1.0-P1.3发全0,P1.4-P1.7输入 if((P1&0xf0)!= 0xf0) { //如P1口高4位不全为1,有键按下 delay(20000); //延时去抖动 if((P1&0xf0)!=0xf0) { //重读输入值 sccode = 0xfe; //最低位置0 while((sccode&0x10)!=0) { //不到最后一行循环 P1 = sccode; //P1口输出扫描码 if((P1&0xf0)!= 0xf0) { //如P1.4-P1.7不全为1,该行有键按下 recode = P1&0xf0; sccode = sccode & 0x0f; //保留P1口高4位输入值,低4位变为全1,作为列值 return(sccode+recode); //行码+列码=键编码,返回主程序 } else { sccode = (sccode<<1)|0x01; //如该行无键按下,查下一行,行扫描值左移一位 delay(100); } } } } return(0); //无键按下,返回值为0
修改后出错的5*4键盘扫描程序 code uint keytab[20] = {0x1DE,0x1BE,0x17E,0x0FE,0x1DD,0x1BD,0x17D, 0x0FD,0x1DB,0x1BB,0x17B,0x0FB,0x1D7,0x1B7, 0x177,0x0F7,0x1CF,0x1AF,0x16F,0x0EF};
uint kbscan(void); uint kbscan(void) { uint sccode,recode; P1 = 0xf0; P3_0 = 0; if((P1&0xf0)!= 0xf0) { delay(20000); if((P1&0xf0)!=0xf0) { sccode = 0x1fe; while((sccode&0x020)!=0) { P1 = sccode/2; if((P1&0xf0)!= 0xf0) { recode = P1&0xf0; sccode = sccode & 0x01f; return(sccode+recode); } else { sccode = (sccode<<1)|0x01; delay(100); } } } } return(0); } |