KST51 マイクロコントローラー: マトリックスのボタン数検出と割り込みによるデバウンスを実現

Key4 を例にとると、デバウンスには 2ms のスケジュール割り込みが使用され、キーの状態が 8 回連続 (16ms) 判定されます。

すべて 1 の場合、ポップアップが表示され、キー (Keysta) の現在の状態が 1 になります。

すべてが 0 の場合は、それを押してキー (Keysta) の現在のステータスを 0 に設定します。

残りの状態はすべてジッタリングしており、ボタンの現在の状態は変化しません

鍵の状態はメインプログラムで判断され、現在の鍵の状態(Keysta)と過去の鍵の状態(バックアップ)が異なる場合、鍵の状態が変化したことを意味しますプログラムでは、ボタンがポップアップされるとキーストロークの数が変化し、最新のキーストローク時間がデジタル管に送信されて表示され、キーパッドの履歴状態が次の判断のために現在の状態に更新されます。ソースコードは次のとおりです。

#include<reg52.h>

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                                //其他情况则按键状态还未稳定
	{}	
}

 

おすすめ

転載: blog.csdn.net/Wapiti_y/article/details/84500593