zoukankan      html  css  js  c++  java
  • 多功能检測按键-3 按键扫描 单按 长按 多个按键 响应方式

    /***************************************
    // 函数功能:按键扫描
    //这是我第三次对按键扫描的优化,为什么我要这么做呢,非常easy,
    //我仅仅想将简单的事情不断完好好
    //第一次发表:http://blog.csdn.net/chuangwu2009/article/details/9466715
    //第一次发表:http://blog.csdn.net/chuangwu2009/article/details/18032195					
    *****************************************/
    
    /* 按键响应方式我个人总结了下,一共同拥有11种(包含无按键)
    按键响应方式:1:单按键按下响应 2:单按键按下释放响应 3:多按键按下响应
    
    当中按下对应有:1.1:按下立即响应
    				1.2:长按后立即响应
    				1.3:长按后一直响应(如:长按累加更改时间设置)
    
    释放响应有:      2.1:短按释放响应
    				2.2长按释放响应
    
    多按键按下响应有: 1.1 1.2 1.3 2.1 2.2四种组合按键响应方式				 
    */
    #define  SETB0   (unsigned char)0x01
    #define  SETB1   (unsigned char)0x02
    #define  SETB2   (unsigned char)0x04
    #define  SETB3   (unsigned char)0x05
    #define  SETB4   (unsigned char)0x10
    #define  SETB5   (unsigned char)0x20
    #define  SETB6   (unsigned char)0x40
    #define  SETB7   (unsigned char)0x80
    
    
    
    typedef union uFLG1{
    	uint8 Flg ;
        struct FLAG1{
            uint8	Flg1   : 1;
            uint8	Flg2   : 1;
            uint8	Flg3   : 1;
            uint8	Flg4   : 1;
            uint8	Flg5   : 1;
            uint8	Flg6   : 1;
            uint8	Flg7   : 1;
            uint8	Flg8   : 1;
        }tFlg1;	
    }uFlg1;
    
    
    uFlg1  F_KEY={0};
    //位定义
    #define		f_onekey			F_KEY.tFlg1.Flg1//有单按键按下标志
    #define		F_longonekey	F_KEY.tFlg1.Flg2//长按标志
    #define		f_mulkey			F_KEY.tFlg1.Flg3//多按键标志
    #define		F_longmulkey 	F_KEY.tFlg1.Flg4//有多按键按下标志
    #define 	F_first    		F_KEY.tFlg1.Flg5//上电识别是否上电按下 开机初始化时 运行 F_first = 1;
    
    
    //按键响应模式
    #define  NONE_KEY			  (unsigned char)0//无效按键值-无按键
    
    #define  ONE_DOWN 			(unsigned char)1
    //单个按键按下响应--(短按)按下立即响应
    #define	 ONE_LONG_DOWN  (unsigned char)2
    //单个按键长按下响应--长按时间到后的(立即)响应
    #define  MUL_DOWN			  (unsigned char)3
    //多个按键按下响应
    #define  MUL_LONG_DOWN  (unsigned char)4
    //多个按键长按下响应
    #define  ONE_UP    			(unsigned char)5
    //单个按键释放响应
    #define  MUL_UP    			(unsigned char)6
    //多个按键释放响应
    #define  ONE_LONG_UP		(unsigned char)7
    //单个按键长按后释放响应
    #define  MUL_LONG_UP		(unsigned char)8
    //多个按键长按后释放响应
    #define  ONE_AL_DOWN		(unsigned char)9
    //单按键长按之后的响应-长按后一直响应(如:长按累加更改时间设置)
    #define  MUL_AL_DOWN		(unsigned char)10
    //多按键长按之后的响应
    
    #define  LongAndShortUpIsSame		//长按和短按释放按键功能一样
    //定义此宏意思是 在短按按键释放后 或者长按按键后
    // 功能运行是一样的 即运行ONE_UP或者MUL_UP的动作
    
    static	 uint8	key_value1=0;//单前按键值
    //按键值寄存器-当前按下的值-按下立即响应一次动作
    
    static	uint8	key_value2=0;
    //按键值寄存器-前一次的值
    //--长按响应一次动作或者按键短按释放响应一次动作
    static	uint8	key_value3=0;
    //按键值寄存器长按的值---长按后一直响应
    
    static	uint8 mode_key=0;//按键响应模式
    
    
    void Key_scan(void)	 // 
    {
    
    
      static	uint8	key_delay=0;//按键去抖动寄存器
      static	uint8	key_value0=0;//前一次按键值寄存器
    
      static	uint8	key1_mult=0;//多按键寄存器2
      
      static	uint8	key_longtime=0;//长按时间累积寄存器1
      static	uint8	key_longtime1=0;//长按时间累积寄存器2
      
      uint8	key_mult=0;//多按键寄存器1
    
      
      if(!P_K0)//	
      {
    		key_value1|=SETB0;
    		key_mult++;
      } 
      
      if(!P_K1)//
      {
    		key_value1|=SETB1;	
    		key_mult++;
      }
      /*
      if(!P_K2)//
      {
    		key_value1|=SETB2;	
    		key_mult++;
      } 
      if(!P_K3)//
      {
    		key_value1|=SETB3;	
    		key_mult++;
      } 
      if(!P_K4)//
      {
    		key_value1|=SETB4;	
    		key_mult++;
      } 
      */
      
      
      if(key_value1 == key_value0)//如不响等,保存当前按键值,清抖动寄存器,以此次识别
      {
        if(key_delay > 10)//抖动处理
        {
          if(key_value1 > 0)//无按键按下确认,等于0时表示无按键
          {
            if(1 == key_mult)
            {//单按键按下处理程序
                if(!f_onekey)
                { //单按键短按按下处理程序
                        f_onekey=1;
                        key1_mult=0;
                        mode_key=ONE_DOWN;
                }
                else
                {//单按键长按
    							if(!F_longonekey)
    							{//还没达到长按时间
    								if(++key_longtime>=100)//
    								{
    									 key_longtime=0;
    									 if(++key_longtime1>=15)
    									 {//长按时间到
    													 key_longtime1=0;	
    													 mode_key=ONE_LONG_DOWN;
    													 F_longonekey=1;
    													//长按按键处理程序
    									 }
    								}
    								else								
    								{//还没达到长按时间
    									mode_key=NONE_KEY;
    								}
    							}
    							else
    							{//单按键长按之后的响应
    								
    								mode_key = ONE_AL_DOWN;
    
    							}
                }
            }
            else
            {	   //多按键按下处理程序
              key1_mult=1;
              if(!f_mulkey)
              {//多按键短按下对应
    							f_mulkey=1;	
    							f_onekey=1;	
    		//	f_onekey=1;	防止多个按键释放时候,不同一时候释放,响应单个按键功能
    							mode_key=MUL_DOWN;
              }
              else
              {//多按键长按
    						if(!F_longmulkey)
    						{
    							if(++key_longtime>=100)//2毫秒1次  100*2*15=3秒
    							{
    								 key_longtime=0;
    								 if(++key_longtime1>=15)
    								 {
    									 key_longtime1=0;//3秒时间到	
    									 
    									 F_longmulkey=1;
    									//多按键长按按键处理程序
    									 mode_key=MUL_LONG_DOWN;
    									}
    																							
    							 }
    							 else
    							{
    											mode_key=NONE_KEY;
    							}
    						}
    						else
    						{
    										//多按键长按之后的响应
    										mode_key = MUL_AL_DOWN;
    						}
    				  }	
    			  }   
           }
            else//按键释放或者无按键
           {
                  
            f_mulkey=0;
            F_first=0;
    
            key_longtime=0;
            key_longtime1=0;
            if(F_longonekey)
            {//长按单按键释放
                F_longonekey=0;
                #ifdef (LongAndShortUpIsSame)
    						 mode_key=ONE_UP;
    						#else
    						 mode_key=ONE_LONG_UP;
    						#endif
               
                    
            }
            else if(F_longmulkey)
            {//长按多按键释放
                F_longmulkey=0;	
        
    						#ifdef (LongAndShortUpIsSame)
    						 mode_key=MUL_UP;
    						#else
    						 mode_key=MUL_LONG_UP;
    						#endif
    				
            }
            else if(f_onekey)
            {//短按按键释放
                            
                if(0==key1_mult)
                {
                    mode_key=ONE_UP;
                }
                else
                {
                    mode_key=MUL_UP;	
                }
            }
            else
            {
                 mode_key=NONE_KEY;
            }
            f_onekey=0;  
           }
        }
        else  
        {//滤波处理
                key_delay++;
        }
      }
      else
      {
              key_value0=key_value1;
              key_delay=0;
      }
    		
    }
    
    //*************************************
    // 函数名称:key_deal
    // 函数功能:按键响应后的处理
    // 入口參数:无
    // 出口參数:无
    //***************************************/
    
    
    void key_deal(void)
    {
      static uint8	key_longtime=0;//长按时间累积寄存器1
    
    
      switch(mode_key)
      {
        case ONE_DOWN://单个按键按下响应
        {
    			switch(key_value1)
    			{
    			 case SETB1://P_K1短按下响应
    			 {		
    						key_value2 =	key_value1;		
    						
    						if(F_first)
    						{//按住按键上电响应-要运行的动作-经常使用于自检
    							
    							
    							break;
    						}
    							break;
    				}
    				 case SETB0:///P_K0短按下响应
    				 {		
    							key_value2 =	key_value1;	
    							if(F_first)
    							{
    									
    									break;
    							}
    							
    							break;
    				 }
    				default:  
    				break;
    			}
    			
        key_value1 = 0;	
        
        break;
        }
        case ONE_LONG_DOWN://单个按键长按下响应--对应一次
        {
    				key_value3=key_value2;
    				
    				  switch(key_value2)
    					{
    									 
    						case SETB1:
    					 {		
    										
    									break;
    					 }
    					 case SETB0:
    					 {		
    							
    									break;
    					 }
    									
    									default:  
    									break;
    					}
    					
    					key_value2=0;
                        
        break;
        }
        case MUL_DOWN://多个按键按下响应
        {
    					switch(key_value1)
    					{		 
    							case (SETB1|SETB0):
    						 {		
    														key_value2 = key_value1;
    										break;
    						 }	
    						default:  
    						break;
    					}     
              key_value1=0;
          
        break;
        }
        case MUL_LONG_DOWN://多个按键长按下响应
        {
        
    				if(key_value2==(SETB0|SETB1))
    				{
    					key_value3=key_value2;
    				}
    				
    				key_value2=0;
        break;
        }
        case ONE_UP://单个按键释放响应
        {
    				switch(key_value2)
    				{
    								 case SETB0:
    								 {//TURBO释放
    												
    												break;
    								 }
    								 case SETB1:
    								 {							 	
    												
    												
    												break;
    								 }
    								default:  
    								break;
    				}
    					key_value2=0;//按键释放后清零
        break;
        }
        case MUL_UP://多个按键释放响应
        {        
    					key_value2=0;//按键释放后清零
    					key_value3=0;
    
        break;
        }		
        case ONE_LONG_UP://单个按键长按后释放响应
        {	
                        
    				switch(key_value3)
    				{
    						 case SETB0:
    						 {//TURBO释放
    										
    														
    										break;
    						 }
    						 case SETB1:
    						 {							 	
    										
    										
    										break;
    						 }
    						default:  
    						break;
    				}
    				key_value2=0;//
    				key_value3=0;
                
        break;
        }
        case MUL_LONG_UP://多个按键长按后释放响应
        {
                                
                         
    				key_value2=0;//按键释放后清零
    				key_value3=0;
        break;
        }
        case ONE_AL_DOWN://单按键长按之后的响应
        {
                                
    			if(++key_longtime>=100)//2毫秒1次  40*15*5=3秒
    			{
    				key_longtime=0;
    							
    				 switch(key_value3)
    				{
    					 case SETB0:
    					 {							 	
    									
    									break;
    					 }
    					 case SETB1:
    					 {							 	
    									
    									
    									break;
    					 }
    					default:  
    					break;
    				}	
    			}	
        break;
        }
        case MUL_AL_DOWN://多按键长按之后的响应
        {	
              if(++key_longtime>=100)//2毫秒1次  40*15*5=3秒
    				{
    								 key_longtime=0;
    				}	
        break;
        }
        default:
        break;
      }
    }
    
    

  • 相关阅读:
    简介.Net对象序列化.txt
    如何在Web页面退出前提示用户保存数据?
    如何将图片存储到数据库中
    页面回车键响应,onkeydown事件
    用C#创建Windows服务(Windows Services)
    解决“Visual Studio 要求设计器使用文件中的第一个类。移动类代码使之成为文件中的第一个类,然后尝试重新加载设计器。”方法
    动态创建htm元素并添加到document中
    如何在Asp.net的Header中添加/title/Meta tages/CSS
    无法打开项目文件,“d:\web\webapp.csproj”,此安装不支持该项目类型
    用Intelligencia.UrlRewriter实现URL重写
  • 原文地址:https://www.cnblogs.com/mengfanrong/p/3788447.html
Copyright © 2011-2022 走看看