KST51单片机:通过中断实现矩阵按键的次数检测与消抖

以Key4为例,使用定时中断2ms进行消抖,对连续8次(16ms)的按键状态进行判断.

如果全部为1则弹起,将按键当前状态(Keysta)为1;

全部为0则按下,将按键当前状态(Keysta)置0;

其余状态都为抖动,按键当前状态不变

在主程序里对按键状态进行判断,如果按键当前状态(Keysta)与按键历史状态(backup)不同,则说明按键状态发生变化。程序中是弹起时,按键次数改变,将最新的按键次数送给数码管显示,将按键历史状态更新为当前状态并进行下一次判断。源代码如下:

#include

sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
sbit KEY1 = P2^4;
sbit KEY2 = P2^5;
sbit KEY3 = P2^6;
sbit KEY4 = P2^7;

unsigned char code LedChar[] ={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e
};

bit KeySta = 1;           //位定义

void main()
{
	bit backup = 1;       //定义一个位变量,保存前一次扫描的按键值。
	unsigned char cnt = 0;

	EA = 1;
	ENLED = 0;            //使能U3 选中数码管DS1
	ADDR3 = 1;			
	ADDR2 = 0;
	ADDR1 = 0;
	ADDR0 = 0;
	TMOD = 0x01;          //T0为模式1
	TH0 = 0xf8;           //定时2ms
	TL0 = 0xcd;
	ET0 = 1;
	TR0 = 1;              //启动T0
	P2 = 0xf7;            //P2.3置0,即输出低电平
	P0 = LedChar[cnt];    //显示按键次数
	
	while(1)
	{
		if(KeySta != backup)         //当前值与前次值不相等说明此时有动作
		{
			if(backup == 0)          //如果前次值为0,则说明是弹起动作
			{
				cnt++;               //按键次数加1
				if(cnt >= 10)
				{
					cnt = 0;         //10次清0
				}
 				P0 = LedChar[cnt];
			}
			backup = KeySta;         //更新备份为当前值
		}

	}
}
/*T0中断服务函数,用于按键状态的扫描并消抖*/
void InterruptTimer0() interrupt 1
{
	static unsigned char keybuf =0xff;  //扫描缓冲区,保存一段时间内的扫描值
	TH0 = 0xf8;                         //重新加载初值
	TL0 = 0xcd;
	keybuf= (keybuf<<1) |KEY4;          //缓冲区左移一位,并将当前扫描值移入最低位
	if(keybuf == 0x00)                  //连续8次扫描值都为0,16ms内状态不变,即按键已按下
	{
		KeySta = 0;
	}
	else if(keybuf == 0xff)             //连续8次扫描值都为1,16ms内状态不变,即按键已弹起
	{
		KeySta = 1;
	}
	else                                //其他情况则按键状态还未稳定
	{}	
}

 

你可能感兴趣的:(单片机,源代码)