#51单片机#中断实现按键消抖

在实际工程中常用到中断的算法来实现按键消抖。

思路:启动一个定时中断,每2ms进一次中断扫描按键状态并储存。连续扫描8次后,观察这8次按键状态是否一致。如果一致,即按键没有发生动作,处于稳定状态。

被监测到的按键动作,通常如下图所示:
在这里插入图片描述
具体代码如下:

#include 

unsigned char code LedChar[10]={//数码管显示的数字0~9。
0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};

sbit KEY1 = P3^3;
sbit DigitalTube = P1^0;

bit KeySta = 1;	//当前按键状态。

void main()
{
	bit backup = 1;//按键值备份,保存前一次扫描的值。
	unsigned char cnt = 0;//按键计数,记录按键按下的次数。

	EA = 1;//中断总开关。
	ET0 = 1;//使能中断。
	TH0=0XF8;//定时器设定,定时2ms。
	TL0=0XCD;
	TR0 = 1;//启动T0。

	KEY1 = 1; //按键引脚输出高电平。

	while(1)
	{
 		DigitalTube = 0;
		P0 = LedChar[cnt];
		if(backup != KeySta)	 //当前值不同于前一次的值。
		{
			if(backup == 0)		//如果前值为0,说明当前状态是0->1,即按键弹起。
			{
				cnt++;
				if(cnt>9)
				{
					cnt = 0;
				}	
			}
			backup = KeySta;	//更新备份位当前值,以便进行下一次比较。
		}
	} 
}
//T0中断服务函数,用于扫描按键状态
void InterruptTimer0()interrupt 1
{
	static unsigned char keybuf = 0XFF;	 //扫描缓冲区,保存一段时间内的扫描值。

	TH0=0XF8;
	TL0=0XCD;
	keybuf = (keybuf<<1)|KEY1; //缓冲区左移一位,并将当前扫描值移入最低位。
	if(keybuf == 0X00)
	{				//连续8次扫描值为0,即16ms内都只检测到按下状态,可认为按键已按下。
		KeySta = 0;	
	}
	else if(keybuf == 0XFF)
	{				//连续8次扫描值为1,即16ms内都只检测到弹起状态,可认为按键已弹起。
		KeySta = 1;
	}
	else
	{}			   //其他情况。按键状态不确定,不更新KeySta变量值。
}

你可能感兴趣的:(单片机)