⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 key.c

📁 扫描按键的程序
💻 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 + -