函数的主体
unsigned char GetKey() { unsigned char i,j,k; static unsigned char backup[4][4]={ {1,1,1,1},{1,1,1,1},{1,1,1,1},{1,1,1,1} }; EA=1; TMOD=0x01;//设置T0为模式1 TH0=0xF8; TL0=0xCD; ET0=1;//使能T0中断 TR0=1;//启动T0 while(1) { for(i=0;i<4;i++)//循环检测4×4的矩阵按键 { for(j=0;j<4;j++) { if(backup[i][j]!=KeySta[i][j])//检测按键动作 { if(backup[i][j]!=0)//检测按键按下时执行动作 { k=i*4+j; return k;//返回矩阵按键的编号 } backup[i][j]=KeySta[i][j];//更新前一次的备份值 } } } } }
下面是中断函数
/*T0中断服务函数,扫描矩阵按键状态并消抖*/ void InterruptTimer0() interrupt 1 { unsigned char m; static unsigned char keyout=0;//矩阵按键扫描输出索引 static unsigned char keybuf[4][4]={ {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF}, {0xFF,0xFF,0xFF,0xFF},{0xFF,0xFF,0xFF,0xFF} }; TH0=0xFC; TL0=0x67; /*将一行的4个按键值移入缓冲区*/ keybuf[keyout][0]=(keybuf[keyout][0]<<1)|KEY_IN_1; keybuf[keyout][1]=(keybuf[keyout][1]<<1)|KEY_IN_2; keybuf[keyout][2]=(keybuf[keyout][2]<<1)|KEY_IN_3; keybuf[keyout][3]=(keybuf[keyout][3]<<1)|KEY_IN_4; /*消抖后更新按键状态*/ for(m=0;m<4;m++) { if((keybuf[keyout][m]&0x0F)==0x00) { KeySta[keyout][m]=0;//连续4次扫描值为0,即4×4ms内都是按下状态时,可认为按键已稳定地按下 } else if((keybuf[keyout][m]&0x0F)==0x0F) { KeySta[keyout][m]=1;//弹起 } /*执行下一次的扫描输出*/ keyout++;//输出索引递增 keyout=keyout&0x03;//索引值增加到4即归零 /*根据索引,释放当前输出引脚,拉低下次的输入引脚*/ switch(keyout) { case 0:KEY_OUT_4=1;KEY_OUT_1=0;break; case 1:KEY_OUT_1=1;KEY_OUT_2=0;break; case 2:KEY_OUT_2=1;KEY_OUT_3=0;break; case 3:KEY_OUT_3=1;KEY_OUT_4=0;break; default:break; } } }
这些代码完成了矩阵键盘的扫描、消抖、动作分离的全部内容,通过调用GetKey()可以返回按下的按钮的编号,很方便。
时间: 2024-11-13 02:08:02