這里有兩段程序有關鍵盤掃描的,其中一段是正確的:針對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); } |