键盘松手检测

2025-10-14 02:07:17 1969

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

当按键按下时,会导致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;

}

}

}