|
我在網上看到一個經典矩陣按鍵掃描如下: unsigned char Check_key(void) { unsigned char row,col,temp1,temp2,keyvalue; temp1 = 0x01; for(row=0;row<4;row++) // 行掃 { P0 = 0xF0; // 先將P0.4~P0.7置高 P0 = ~temp1; // 使P0.1~P0.3中有一位為0 temp1 *= 2; // temp1左移一位 if((P0 & 0xF0) < 0xF0) // 當按鍵按下時,(P0 & 0xF0) 高四位不在是F,可能為7或B或D或E。 { // 這時可以確定按下的是(row+1)行 temp2 = 0x80; for(col=0;col<4;col++) // 列掃 { if((P0 & temp2)==0x00) // 當(P0 & temp2)等于0x00時,可以確定按下的位置是(col+1)列 { keyvalue = row*4+col; // 得到所按下按鍵的鍵值 return keyvalue; // 把得到的鍵值作為返回值 } temp2 /= 2; // temp2右移一位 } } } return 16; // 因為定義數碼管段選表中,16對應的是全滅,故無按鍵按下時返回16 } 但是,它存在一個弊端:當你使用一個按鍵,按一次按鍵,實現變量值加1,實際結果卻是按一次按鍵,變量值加了好多次1。 ![]() 我個人寫了一個矩陣按鍵掃描,可以解決上面那個弊端,按一次按鍵能實現變量只加一個1,長按的話,可以連續加1。 我寫的這個矩陣按鍵掃描,在不按的情況下返回的鍵值是16,當你按下去的瞬間鍵值才是0~15中的一個。這正是能實現連續加或減的前提條件。 代碼如下: #define GPIO_KEY P0 bit flag = 0; /************************************************* * 函數名:delay_ms * 描述 :延時函數 * 參數 :xms , xms是幾延時幾毫秒 * 返回值:無 * 調用 :內部調用 *************************************************/ void delay_ms(unsigned int xms) { unsigned char i, j; unsigned int x; for(x=xms;x>0;x--) { i = 16; j = 147; do { while (--j); } while (--i); } } /************************************************* * 函數名:key_scan * 描述 :把按下的矩陣按鍵的鍵值返回 * 參數 :無 * 返回值:按下的鍵值 * 調用 :外部調用 *************************************************/ unsigned char key_scan() { unsigned char keyvalue1,keyvalue2,a=0; if(flag==0) { keyvalue2=16; flag=1; } GPIO_KEY = 0xf0; // 高四位為1,低四位為0 if(GPIO_KEY != 0xf0) { delay_ms(10); // 延時消抖 if(GPIO_KEY != 0xf0) { GPIO_KEY=0xf0; switch(GPIO_KEY) { case 0xe0: keyvalue1 = 3;break; // 確定矩陣按鍵被按下的位置是第幾列 case 0xd0: keyvalue1 = 2;break; // 0、1、2、3 case 0xb0: keyvalue1 = 1;break; case 0x70: keyvalue1 = 0;break; } GPIO_KEY=0x0f; // 確定矩陣按鍵被按下位置的鍵值:列(或0或1或2或3) + 行(或0或4或8或12) if((GPIO_KEY != 0x0d)||(GPIO_KEY != 0x0b)||(GPIO_KEY != 0x07)) keyvalue2 = keyvalue1; if(GPIO_KEY == 0x0d) keyvalue2 = keyvalue1+4; if(GPIO_KEY == 0x0b) keyvalue2 = keyvalue1+8; if(GPIO_KEY == 0x07) keyvalue2 = keyvalue1+12; while((a<50)&&(GPIO_KEY!=0x0f)) { delay_ms(10); a++; } } } if(GPIO_KEY==0xF0) keyvalue2 = 16; return keyvalue2; } |