|
![](http://c.51hei.com/a/old/up/0/512220292965506.jpg)
由于单片机I/o口的有限,当需要多个按键的时候,常用矩阵键盘作为输入设备.
由于按键按下后,松开得到的波形实际中不是理想化的方波,会出现机械抖动,对后续单片机检测按键带来麻烦,
![](http://c.51hei.com/a/old/up/0/512220292923510.jpg)
一般教材上基本都是利用延时去抖动:基本套路都:
void key()
{
if(k1==0) //如果按键按下
{
delay_10ms();延时去抖动
if(k1==0) 再次判断
{
你要的功能
}
}
}
由于10ms是理论上人们按键按下后到松手所要的大概时间,由于个体差异,和按键的机械灵活度有差异,导致可能出现按键按太快,没反应,按时间太长导致单片机效率降低等不确定因素.
可以采用判断是否是第一次按下来进行检测,可以大大提高效率,当你按键按了再快也能检测到。
程序如下:
//---------------------------------------------------------------------
#include <reg52.h>
#define key P2
int val;
char code sign[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x83,0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void delay_10ms();
void key_scan(); //矩阵按键函数声明
void main()
{
while(1)
{
P0=sign[val];
key_scan();
}
}
void key_scan()
{
static char a,b; //a用于判断是不是第一次按下,b用于稍微延时
char state; //记录键值
key=0x0f;
if(key!=0x0f) //如果有按键按下
{
state=key; //记录第一次按键状态
if(a==0) //如果第一次按下
{
b++; //略微延时 不需要延时10ms以提高单片机效率
if(b>3)
{
if(key==state) //判断键值是否和第一次一致
{
a=1,b=0; //复位状态值 a==1说明已经按下,等待后续松开
key=0x0f; //测试列
switch(key)
{
case (0x07): val=0;break;
case (0x0b): val=1;break;
case (0x0d): val=2;break;
case (0x0e): val=3;break;
}
key=0xf0; // 测试行
switch(key)
{
case (0x70): val=val;break;
case (0xb0): val=val+4;break;
case (0xd0): val=val+8;break;
case (0xe0): val=val+12;break;
}
}
}
}
}
else
{
a=b=0; //松开后复位状态机
}
}
|
|