|
我在网上看到一个经典矩阵按键扫描如下: 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; } |