📄 key.c
字号:
/*
按键判断程序
说明: 当按键被长时间按下时,返回LONG_PRESS;
当按键被短时间按下时,返回SHORT_PRESS;
当按键没有被按下时,返回NO_PRESS;
在按键按下但尚未到明确状态时返回NOP;
通过设定LIMIT的值可限制在按键长按时计数的速度
按键的灵敏度可以通过设定LONG_BOUND和SHORT_BOUND改变
例如:#define LONG_BOUND 200
#define SHORT_BOUND 20
比 #define LONG_BOUND 250
#define SHORT_BOUND 40
灵敏度要高一些。
(C)西安电子科技大学 测控技术与仪器 编写:刘东林 2008/04/01
*/
// STC89C52RC
// +---------------+
// | |
// | |
// | | __
// | P2.0(KEY4)|--------+ +--------+
// | | __ |
// | P2.1(KEY3)|--------+ +--------+
// | | __ |
// | P2.2(KEY2)|--------+ +--------+
// | | __ |
// | P2.3(KEY1)|--------+ +--------+--|GND
// | |
// | |
// | |
// +---------------+
#include<reg52.h>
#define LIMIT 150 //长按状态下计数速度限制
#define KeyON 0
#define KeyOFF 1
#define LONG_PRESS 2 //分别对三种按键方式进行宏定义
#define SHORT_PRESS 1
#define NO_PRESS 0
#define NOP 3
#define LONG_BOUND 200 //长按计数上界
#define SHORT_BOUND 30 //短按计数上界
sbit KEY1=P2^3; //定义按键入口
sbit KEY2=P2^2;
sbit KEY3=P2^1;
sbit KEY4=P2^0;
#define IsKEY1_ON KEY1==KeyON?1:0 //按键被按下为1,否则为0(消除器件差异)
#define IsKEY2_ON KEY2==KeyON?1:0
#define IsKEY3_ON KEY3==KeyON?1:0
#define IsKEY4_ON KEY4==KeyON?1:0
unsigned char KEY1_Cnt,KEY2_Cnt,KEY3_Cnt,KEY4_Cnt; //各按键去抖及状态判断延时计数
bit KEY1_Fore=KeyOFF,KEY2_Fore=KeyOFF,KEY3_Fore=KeyOFF,KEY4_Fore=KeyOFF; //各按键之前状态
bit KEY1_Now,KEY2_Now,KEY3_Now,KEY4_Now; //各按键当前状态
/*************************************************
*函数名:KEY1_JUDGE()
*入口参数:无
*出口参数:LONG_PRESS,SHORT_PRESS,NO_PRESS
*说明: 当按键1被长时间按下时,返回LONG_PRESS;
* 当按键1被短时间按下时,返回SHORT_PRESS;
* 当按键1没有被按下时,返回NO_PRESS;
* 在按键按下但尚未到明确状态时返回NOP;
************************************************/
unsigned char KEY1_JUDGE()
{
if(IsKEY1_ON) //按键被按下时做如下判断
{
KEY1_Cnt++;
if(KEY1_Cnt>SHORT_BOUND)
{
KEY1_Now=KeyON;
if(KEY1_Cnt>LONG_BOUND) //当KEY1_Cnt超过长按计数上界时判断为长按
{
KEY1_Cnt=LIMIT; //对KEY1_Cnt赋值作为下次计数的初值,LIMIT越大(上限为LONG_BOUND),下次LONG_PRESS判断来的越快
KEY1_Fore=KEY1_Now; //记录上次按键为KeyON
return LONG_PRESS;
}
if(KEY1_Fore==KeyOFF&&KEY1_Now==KeyON) //当上次按键为KeyOFF并且当前按键为KeyON时,判断为短按
{
KEY1_Fore=KEY1_Now; //记录上次按键为KeyON
return SHORT_PRESS;
}
}
return NOP; //当判断不明确时,返回NOP(分别在“去抖”和再次判断LONG_PRESS时)
}
else
{ //按键没被按下,不做判断,返回NO_PRESS
KEY1_Now=KeyOFF; //则记录当前按键为KeyOFF
KEY1_Cnt=0; //计数清零
KEY1_Fore=KEY1_Now; //记录上次按键为KeyOFF
return NO_PRESS;
}
}
/*************************************************
*函数名:KEY2_JUDGE()
*入口参数:无
*出口参数:LONG_PRESS,SHORT_PRESS,NO_PRESS
*说明: 当按键2被长时间按下时,返回LONG_PRESS;
* 当按键2被短时间按下时,返回SHORT_PRESS;
* 当按键2没有被按下时, 返回NO_PRESS;
* 在按键按下但尚未到明确状态时返回NOP;
************************************************/
unsigned char KEY2_JUDGE()
{
if(IsKEY2_ON) //按键被按下时做如下判断
{
KEY2_Cnt++;
if(KEY2_Cnt>SHORT_BOUND)
{
KEY2_Now=KeyON;
if(KEY2_Cnt>LONG_BOUND) //当KEY2_Cnt超过长按计数上界时判断为长按
{
KEY2_Cnt=LIMIT; //对KEY2_Cnt赋值作为下次计数的初值,LIMIT越大(上限为LONG_BOUND),下次LONG_PRESS判断来的越快
KEY2_Fore=KEY2_Now; //记录上次按键为KeyON
return LONG_PRESS;
}
if(KEY2_Fore==KeyOFF&&KEY2_Now==KeyON) //当上次按键为KeyOFF并且当前按键为KeyON时,判断为短按
{
KEY2_Fore=KEY2_Now; //记录上次按键为KeyON
return SHORT_PRESS;
}
}
return NOP; //当判断不明确时,返回NOP(分别在“去抖”和再次判断LONG_PRESS时)
}
else
{ //按键没被按下,不做判断,返回NO_PRESS
KEY2_Now=KeyOFF; //则记录当前按键为KeyOFF
KEY2_Cnt=0; //计数清零
KEY2_Fore=KEY2_Now; //记录上次按键为KeyOFF
return NO_PRESS;
}
}
/*************************************************
*函数名:KEY3_JUDGE()
*入口参数:无
*出口参数:LONG_PRESS,SHORT_PRESS,NO_PRESS
*说明: 当按键3被长时间按下时,返回LONG_PRESS;
* 当按键3被短时间按下时,返回SHORT_PRESS;
* 当按键3没有被按下时,返回NO_PRESS;
* 在按键按下但尚未到明确状态时返回NOP;
************************************************/
unsigned char KEY3_JUDGE()
{
if(IsKEY3_ON) //按键被按下时做如下判断
{
KEY3_Cnt++;
if(KEY3_Cnt>SHORT_BOUND)
{
KEY3_Now=KeyON;
if(KEY3_Cnt>LONG_BOUND) //当KEY3_Cnt超过长按计数上界时判断为长按
{
KEY3_Cnt=LIMIT; //对KEY3_Cnt赋值作为下次计数的初值,LIMIT越大(上限为LONG_BOUND),下次LONG_PRESS判断来的越快
KEY3_Fore=KEY3_Now; //记录上次按键为KeyON
return LONG_PRESS;
}
if(KEY3_Fore==KeyOFF&&KEY3_Now==KeyON) //当上次按键为KeyOFF并且当前按键为KeyON时,判断为短按
{
KEY3_Fore=KEY3_Now; //记录上次按键为KeyON
return SHORT_PRESS;
}
}
return NOP; //当判断不明确时,返回NOP(分别在“去抖”和再次判断LONG_PRESS时)
}
else
{ //按键没被按下,不做判断,返回NO_PRESS
KEY3_Now=KeyOFF; //则记录当前按键为KeyOFF
KEY3_Cnt=0; //计数清零
KEY3_Fore=KEY3_Now; //记录上次按键为KeyOFF
return NO_PRESS;
}
}
/*************************************************
*函数名:KEY4_JUDGE()
*入口参数:无
*出口参数:LONG_PRESS,SHORT_PRESS,NO_PRESS
*说明: 当按键4被长时间按下时,返回LONG_PRESS;
* 当按键4被短时间按下时,返回SHORT_PRESS;
* 当按键4没有被按下时,返回NO_PRESS;
* 在按键按下但尚未到明确状态时返回NOP;
************************************************/
unsigned char KEY4_JUDGE()
{
if(IsKEY4_ON) //按键被按下时做如下判断
{
KEY4_Cnt++;
if(KEY4_Cnt>SHORT_BOUND)
{
KEY4_Now=KeyON;
if(KEY4_Cnt>LONG_BOUND) //当KEY4_Cnt超过长按计数上界时判断为长按
{
KEY4_Cnt=LIMIT; //对KEY4_Cnt赋值作为下次计数的初值,LIMIT越大(上限为LONG_BOUND),下次LONG_PRESS判断来的越快
KEY4_Fore=KEY1_Now; //记录上次按键为KeyON
return LONG_PRESS;
}
if(KEY4_Fore==KeyOFF&&KEY4_Now==KeyON) //当上次按键为KeyOFF并且当前按键为KeyON时,判断为短按
{
KEY4_Fore=KEY4_Now; //记录上次按键为KeyON
return SHORT_PRESS;
}
}
return NOP; //当判断不明确时,返回NOP(分别在“去抖”和再次判断LONG_PRESS时)
}
else
{ //按键没被按下,不做判断,返回NO_PRESS
KEY4_Now=KeyOFF; //则记录当前按键为KeyOFF
KEY4_Cnt=0; //计数清零
KEY4_Fore=KEY1_Now; //记录上次按键为KeyOFF
return NO_PRESS;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -