51单片机键盘、矩阵键盘松手检测

一、对独立按键进行松手检测

独立按键原理图
当按键按下时,会导致51单片机相应引脚变为低电平。利用这个原理,可以进行按键检测。就像下面这段代码:

if(KEY1 == 0) {
	delay_ms(10);
	if(KEY1 == 0) {
		...
	}
}

如果想要对按键是否能够连按进行控制,只需改成下面的样子:
方法1——

uchar enable = 0;		//使能连按的标志位
while(1) {
	if(KEY1 == 0) {
		delay_ms(10);
		if(KEY1 == 0) {
			//执行按键被按下的操作
			...	
			//前面已经执行完了响应操作
			while(KEY1 == 0 && enable == 0){
				//enable=0不支持连按,如果一直按着就会卡在这个循环
			}
			//在while之后,表明此时已经松手了
			//因此,可以进行一些松手后的操作,例如
			LED1 = 0;
			delay_ms(10);
			LED1 = 1;
		}
	}
}

上面是一种比较粗暴的思路:如果一直按着按键,那么响应的I/O口一定一直是0,再加一个控制位,就可以实现对松手检测的使能了。
方法2——
如果是松手后再按下按键,那么一定在I/O口一定会出现一个由高电平到低电平的变化,我们只需要捕捉这个变化即可。

uchar before;
while(1) {
	//before = 1; 如果需要使用连按功能时,可以这样写
	before = KEY1;
	//如果之前值不等于现在值,必然发生了高低电平的变化
	//这种变化有两种可能,0变1或者1变0,只需在消抖后重新判断即可
	if(KEY1 != before) {
		delay_ms(10);
		if(KEY1 == 0) {
			...
		}
	}
}

当然还有一些思路。矩阵键盘的松手检测就采用了另一种思路。

对矩阵键盘的松手检测

矩阵键盘
矩阵键盘与独立按键的松手检测有一些不同。矩阵键盘的没有端口接地,8个端口全部接入I/O口,这就需要手动改变I/O口的输入来检测是否松手。这里,我将矩阵键盘扫描做成了函数,并且在里面嵌套了按键响应接口函数execute(key_val)接口函数,用户只需在execute()中编写响应操作即可:

//mode=1表示支持连按,flag是用于表示按键是否被连按的标志位
void key(uint time, uint mode, uint* flag)
{
	uint temp = 0x00;
	uint row = 0,line = 0,key_val = 0;
	/*
	逻辑说明:flag取值为0或1,mode取值为0或1
	当mode=1时,表示支持连按,无论*flag取何值,均可以进入键盘扫描判断
	当mode=0,*flag=1时,表示不支持连按,但是按键是被第一次按下的,可以进入键盘扫描判断
	当mode=0,*flag=0时,表示不支持连按,且按键不是第一次被按下,不可以进入键盘扫描判断
	所以,当mode,*flag均为0时,不可以进入键盘扫描判断,也就是说,当两者相加为0时,不能进入键盘扫描函数
	*/
	uint enable;
	enable = mode + *flag;
	P3 = 0x0f;		//行高列低,写引脚
	temp = P3 & 0x0f;	//读引脚
	if(temp == 0x0f){			
		//如果检测到按键没有被按下,说明连按被中断了,此时恢复标志位
		*flag=1;
	}
	if(temp != 0x0f && enable != 0){
		delay(time);
		if(temp != 0x0f){
			switch(temp){
				case 0x0e:
					row = 1;
					break;
				case 0x0d:
					row = 2;
					break;
				case 0x0b:
					row = 3;
					break;
				case 0x07:
					row = 4;
					break;
			}
			P3 = 0xf0;		//列高行低
			temp = P3 & 0xf0;
			if(temp != 0xf0){		//之前已经消抖过了,所以这里不用消抖
				switch(temp){
					case 0xe0:
						line = 1;
						break;
					case 0xd0:
						line = 2;
						break;
					case 0xb0:
						line = 3;
						break;
					case 0x70:
						line = 4;
						break;
				}			
			}
		}
		P3 = 0xf0; 		//P3重新赋值,方便之后的连按检测
		key_val = 4*(line-1)+row;
		execute(key_val);
		//在执行完函数之后,检测按键是否还在被按着
		if(mode == 0 && P3 != 0xf0){
			//如果按键还在被按着,并且不支持连按
			//改变标志位,告诉下一次的键盘扫描之前已经执行过响应操作了
			*flag = 0;			
		}
	}
}

emmmm,所以,看起来矩阵键盘的逻辑更加复杂一点。如果有更简单的方法,希望交流一下。

  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌哒哒虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值