按键消抖问题
机械按键消抖是必须的,
1、上学的时候用的是延时:可是实际工作中根本不实用
2、轮询方法,启用一个定时中断,每2ms进一次中断,扫描一次按键状态并且存储起来,连续扫描8次后,看看这连续8次的按键状态是否是一致的。8次按键的时间大概是16ms,这16ms内如果按键状态一直保持一种状态,那就可以确定现在按键是稳定的阶段,并非处于抖动的阶段,
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;
sbit OUT1 = P1^1;
sbit OUT2 = P1^2;
sbit OUT3 = P1^3;
bit KeySta = 1; //当前按键状态
/************************************************************************************************************
* Main function
************************************************************************************************************/
void main(void)
{
//配置T0工作在模式1,定时2ms
TMOD = 0x01;
TH0 = 0xF8;
TL0 = 0xCD;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1)
{
if (KeySta_1 == 0 ) //当前值与前一次值不相等说明此时按键有动作
{
OUT1=~OUT1;
}
}
}
void InterruptTimer0() interrupt 1
{
static unsigned char keybuf = 0xFF; //按键扫描缓冲区,保存一段时间内的扫描值
TH0 = 0xF8; //溢出后进入中断重新赋值
TL0 = 0xCD;
keybuf = (keybuf << 1) | KEY1; //只取KEY1为例,缓冲区左移一位,并将当前扫描值移入最低位
if (keybuf == 0x00)
{ //当连续8次扫描值都为0,即16ms内都只检测到按下状态时,可认为按键已按下
KeySta_1 = 0; //按键状态值为按下
}
else if (keybuf == 0xFF)
{ //当连续8次扫描值都为1,即16ms内都只检测到弹起状态时,可认为按键已弹起
KeySta_1 = 1; //按键状态值为弹起
}
else
{} //其它情况下则说明按键状态尚未稳定,则不对KeySta变量值进行更新
}