目录
一、原理图:
二、思路梳理:
1.独立按键控制角
2.LED灯控制角
3.独立按键键值
4.延时函数
5.独立按键扫描函数
6.主函数
三、一些说明:
1.定义独立按键控制脚:
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^3;
sbit KEY4=P3^4;
2.使用宏定义独立按键按下的键值:
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
#define KEY1_PRESS 1
:将 KEY1_PRESS
定义为 1
,表示按键 K1
按下时,程序中用 KEY1_PRESS
这个标识符代表其键值 。当程序检测到 K1
按键被按下,key_scan
函数会返回 KEY1_PRESS
,即返回 1
。
下面会有key_scan
函数。
3.key_scan
函数:
u8 key_scan(u8 mode)
mode
是函数的参数,用于控制按键扫描的模式:- 当
mode
为0
时,表示单次扫描按键,即按键按下一次,函数只返回一次键值,直到按键释放后才能再次触发。 - 当
mode
为1
时,表示连续扫描按键,即只要按键一直按下,函数会不断返回对应的键值。
- 当
4.按键状态:
key
用于记录按键的状态,初始值为 1
,表示按键处于未按下状态。一定要分清,key为1就是未按下,所以一开始要设置key=1.
KEY1 == 0 || KEY2 == 0 || KEY3 == 0 || KEY4 == 0
表示检测是否有任意一个按键被按下。在硬件电路中,按键按下时对应的引脚电平通常为低电平(0
)。
将 key
置为 0
,表示按键已经被按下。
key
是在 key_scan
函数中定义的静态变量(static u8 key = 1;
),它的作用是标记当前按键检测的状态。key
的值只有 1
和 0
两种情况:
- 当
key
为1
时,意味着当前按键处于未被按下或者已经释放的状态,程序可以开始检测是否有新的按键按下事件。 - 当
key
为0
时,表明按键已经被按下,并且还未释放,在这种状态下,程序不会再次对按键按下事件进行检测,以此避免重复触发按键响应。
不论key还是单个按键,都是为0的时候是被按下。key标记当前按键检测的状态,key为1表示可以检测按键状态。
5.按键扫描模式:
连续扫描模式:当 mode
参数为非零值(一般设为 1
)时,if(mode)
条件满足,会执行 key = 1;
。这意味着不管当前按键状态如何,都会把 key
置为 1
,即允许函数再次检测按键按下事件。在这种模式下,只要按键一直被按着,key_scan
函数每次被调用时都会去检查按键状态,一旦检测到按键按下,就会返回相应键值,达成连续扫描的效果。
单次扫描模式:当 mode
参数为 0
时,if(mode)
条件不成立,key
的值不会被强制置为 1
。这就保证了只有在按键释放(key
变为 1
)之后,再次按下按键才会被检测到。在这种模式下,按键按下一次,函数仅返回一次键值,适用于只需要响应一次按键按下事件的场景,比如开关控制。
笨人理解:
在连续扫描模式下,可以进行长按,得到的结果就是长按想要的。
在单次扫描模式下,进行长按时,只会算一次结果,并不能达到长按的想要的状态。
6.消抖:
在检测到有按键按下后,程序先调用 delay_10us(1000);
进行延时消抖,然后再次检测按键状态,若按键仍然处于按下状态,就判定为有效按键按下事件,并返回对应的键值。
7.key为0:
当检测到有按键按下,并且经过消抖处理确认是有效按下事件之后,将 key
置为 0
。在按键释放之前,由于 key
已经是 0
,if (key == 1 && ...)
这个条件就不会成立,函数不会再次判定按键按下,这样就避免了在按键持续按下的过程中对同一事件进行重复检测。
8.返回值问题:
将 return KEY_UNPRESS;
放在 else if
语句块外面,是为了确保函数在没有检测到有效按键按下事件时,能够有一个明确的默认返回值。
9.调用key_scan
函数:
调用 key_scan
函数进行按键扫描,0
作为参数传递给 key_scan
函数,表示使用单次扫描模式。在单次扫描模式下,按键按下一次,函数只返回一次键值,直到按键释放后才能再次触发。
四、程序实现:
#include <REGX51.H>
typedef unsigned int u16;
typedef unsigned char u8;
sbit KEY1=P3^1;
sbit KEY2=P3^0;
sbit KEY3=P3^3;
sbit KEY4=P3^4;
sbit LED=P2^0;
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY_UNPRESS 0
void delay_10us(u16 t)
{
while(t--);
}
u8 key_scan(u8 mode)
{
static u8 key=1;
if(mode)key=1;
if (key==1&(KEY1==0||KEY2==0||KEY3==0||KEY4==0) )
{
delay_10us(1000);
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
}
else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1)
{
key=1;
}
return KEY_UNPRESS;
}
void main( )
{
u8 key=0;
while(1)
{
key=key_scan(0);
if (key==KEY1_PRESS)
{
LED=!LED;
}
}
}