一、对独立按键进行松手检测
当按键按下时,会导致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,所以,看起来矩阵键盘的逻辑更加复杂一点。如果有更简单的方法,希望交流一下。