按键检测

 转载至http://bbs.21ic.com/icview-1656908-1-1.html

个人做笔记,留给后面看

短按操作:按键按下。按下时间<1s,属于短按操作
长按操作:按键按下。时间>1s,属于长按操作

长按事件:任何1次出现的长按操作都属于长按事件
单机事件:1次短按操作后,间隔0.5内没有短按操作
双击事件:2次短按操作间隔事件<0.5s,则2次短按操作为1次双击事件,,且2次短按都消失

#define  N_Key 0   无键
#define  S_Key 1   单键
#define  D_Key 2   双键
#define  L_Key 10   长键
#define  T-Key 3    3次点击
#define  F-Key 4   4次点击
#define  V_Key 5    5次点击

#define Key_state_0   0
#define Key_state_1   1
#define Key_state_2   2
#define Key_state_3   3
#define Key_state_4   4

unsigned char key_driver(void)
{
   static unsigned char key_state = key_state_0, key_time = 0;
   unsigned char key_press, key_return = N_key;
  key_press=key_input;    //读按键I/O电平
  switch(key_state)
  {
    case key_state_0:
     if(!key_press)    //如果键被按下,状态转换到按键消抖和确认状态
      key_state=key_state_1;
      break;
    case key_state_1:
     if(!key_press)
      {
        key_time=0;
        key_state=key_state_2; //按键仍然处于按下,消抖完成,状态切换到按下键时间的计时状态,但返回的无键状态
      }      
      else
        key_state=key_state_0;//按键已抬起,转换到按键初始态。此处完成和实现软件消抖,其实按键的按下和释放都在此消抖的
     break;
    
     case key_state_2:
      if(key_press)
      {
       key_return=S_Key;     //此时按键释放,说明是产生一次端操作,回送S_key
       key_state=key_state_0;
      }
      else if(++key_time>=100)//继续按下,计时加10ms(定时器为10s)
      {
        key_retuen=L_Key;   //按下时间>1000ms,此按键位长按操作,返回长按事件
        key_state=key_state_3;   转换到等待按键释放状态
      }
 
  }

}
unsigned char  key_read(void)
{
  static unsigned char key_m=key_state_0,key_time_1=0;
  unsigned char key_return=N_Key,key_temp;
  key_temp=key_driver();
   switch(key_m)
   {
     case key_state_0:
      if(key_temp==S_Key)
      {
        key_time_1=0;  //第一次单机,不返回,到下个状态判断返回后面是否出现双击
        key_m=key_state_1;
      }
      else
       key_return=key_temp;
       
       break;
     case  key_state_1:
      if(key_temp==S_Key)   // 又一次单击(间隔肯定<500ms)
      {
       key_return=D_Key;     // 返回双击键事件,
       key_m=key_state_2;    //第二次单机,不返回,到下个判断是否出现三击
      }
      else
      {
       if(++key_time_1>=50)
       {
         key_return=S_Key;  //500ms内没有再次出现单键事件,返回上一次的事件
         key_m=Key_state_0;//返回初始状态
       }
      }
      break;
      case key_state_2:
       if(key_temp==S_Key)
       {
         key_return=T_Key;  //返回三击键事件
         key_m=key_state_3; //第三次单机,不返回,到下个判断是否出现三击
       }
       else
       {
         if(++key_time>=50)
         {
            key_return=D_Key;
            key_m=key_state_0;
         }
       
       }
       break;
       case key_state_3:
        if(key_temp==S_Key)
        {
          key_return=F_Key;  //返回四击键事件
          key_m=key_state_4;//第四次单机,不返回,到下个判断是否出现三击
        }
        else
        {
          if(++key_time_1>=50)
          {
            key_return=T_Key;
            key_m=key_state_0;
          }
        }
        break;
        case key_state_4:
         if(key_temp==S_Key)
         {
          key_return=V_Key;  //返回五击键事件,回初始状态
          key_m=key_state_0;//第五次单机,不返回,到下个判断是否出现三击
         }
         else
         {
         if(++key_time_1>=50)
         {
                key_return=F_Key;
               key_m=key_state_0;
         }
    
         }
         break
        
   }

    return key_return;
}

void T1_INT_INTERRUPT interrupt 3
{
  time_10ms_ok=1;

}

void initTimer1(void)
{
  TIMER1_MODE1_ENABLE;
  TH1 = (65536-TIMER1_10MS_VALUE)/256;
  TL1 = (65536-TIMER1_10MS_VALUE)%256;
  set_ET1;
  set_EA;
  set_TR1;
}

void mian(void)
{
  while(1)
  {
   if(time_10ms_ok)
   {
     time_10ms_ok=0;
     key=key_read();
     switch(key)
     {
      case S_Key:   //单击事件
        break;
      case D_Key:   //双击事件
        break;
      case T-Key:   //三击事件
        break;
      case F-Key:    //四击事件
        break;
      case V_Key:   //五击事件
        break;
    
     }
   }
 
  }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值