|
我在網(wǎng)上看到一個(gè)經(jīng)典矩陣按鍵掃描如下: 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) // 當(dāng)按鍵按下時(shí),(P0 & 0xF0) 高四位不在是F,可能為7或B或D或E。 { // 這時(shí)可以確定按下的是(row+1)行 temp2 = 0x80; for(col=0;col<4;col++) // 列掃 { if((P0 & temp2)==0x00) // 當(dāng)(P0 & temp2)等于0x00時(shí),可以確定按下的位置是(col+1)列 { keyvalue = row*4+col; // 得到所按下按鍵的鍵值 return keyvalue; // 把得到的鍵值作為返回值 } temp2 /= 2; // temp2右移一位 } } } return 16; // 因?yàn)槎x數(shù)碼管段選表中,16對(duì)應(yīng)的是全滅,故無(wú)按鍵按下時(shí)返回16 } 但是,它存在一個(gè)弊端:當(dāng)你使用一個(gè)按鍵,按一次按鍵,實(shí)現(xiàn)變量值加1,實(shí)際結(jié)果卻是按一次按鍵,變量值加了好多次1。 ![]() 我個(gè)人寫(xiě)了一個(gè)矩陣按鍵掃描,可以解決上面那個(gè)弊端,按一次按鍵能實(shí)現(xiàn)變量只加一個(gè)1,長(zhǎng)按的話,可以連續(xù)加1。 我寫(xiě)的這個(gè)矩陣按鍵掃描,在不按的情況下返回的鍵值是16,當(dāng)你按下去的瞬間鍵值才是0~15中的一個(gè)。這正是能實(shí)現(xiàn)連續(xù)加或減的前提條件。 代碼如下: #define GPIO_KEY P0 bit flag = 0; /************************************************* * 函數(shù)名:delay_ms * 描述 :延時(shí)函數(shù) * 參數(shù) :xms , xms是幾延時(shí)幾毫秒 * 返回值:無(wú) * 調(diào)用 :內(nèi)部調(diào)用 *************************************************/ 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); } } /************************************************* * 函數(shù)名:key_scan * 描述 :把按下的矩陣按鍵的鍵值返回 * 參數(shù) :無(wú) * 返回值:按下的鍵值 * 調(diào)用 :外部調(diào)用 *************************************************/ 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); // 延時(shí)消抖 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; } |
Powered by 單片機(jī)教程網(wǎng)