打印

怎样识别长短键

[复制链接]
7307|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
book99|  楼主 | 2010-4-28 10:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在在写按键程序,一键多功能,实现正常显示界面,查询界面间的切换,进入查询界面后还要在10个界面间切换,我的思路是短键按下时进入查询界面,每按一次短键切换一个查询界面,长键按下时返回到正常显示界面,现在的问题是程序不能识别长短键,都按短键处理,下面是我的程序,大家帮我看一下对不对呀,有没有更好的长短键程序呀
uchar keyprocessor()                      //短键
{
  uchar kn=0,knum;
for(knum=0;knum<100;knum++)
{
   Delay_m(100);
   if(key1==0)
    kn++;
   else
    kn=kn;
  }
        if(kn==100)
   return 1;
  
else
return 0;
}

uchar lt_key(void)                             //长键
{

  int lkn=0;
int i;
for(i=0;i<1000;i++)
  {
   Delay_m(1000);
   Delay_m(1000);
   Delay_m(1000);
   Delay_m(1000);
   Delay_m(1000);
   if(key1==0)
    lkn++;
   else
      lkn=lkn;  
   }

   if(lkn==1000)
     return 1;
else
  return 0;
}

相关帖子

沙发
ayb_ice| | 2010-4-28 10:23 | 只看该作者
短键松开后处理,长键直接处理

使用特权

评论回复
板凳
liao_fangxing| | 2010-4-28 11:40 | 只看该作者
补充下 记得带锁检测————防止将一次长按处理成一次长按+一次短按:lol

使用特权

评论回复
地板
liao_fangxing| | 2010-4-28 11:42 | 只看该作者
本帖最后由 liao_fangxing 于 2010-4-28 11:44 编辑

延时做的!?:L   那将按键长按下去程序不光在这延时啦  显示还能正常??

使用特权

评论回复
5
hgjinwei| | 2010-4-28 12:25 | 只看该作者
按键状态是关键

使用特权

评论回复
6
book99|  楼主 | 2010-4-28 13:12 | 只看该作者
带锁检测怎么做呀 现在确实出现了一次长按成了一次长按+短按; 我觉得用延时做长键 程序效率不太高 但是想不出给更好的方法了

使用特权

评论回复
7
jiabin1024| | 2010-4-28 13:14 | 只看该作者
使用定时器处理

使用特权

评论回复
8
liao_fangxing| | 2010-4-28 13:49 | 只看该作者
带锁检测怎么做呀 现在确实出现了一次长按成了一次长按+短按; 我觉得用延时做长键 程序效率不太高 但是想不出给更好的方法了
book99 发表于 2010-4-28 13:12


带锁是偶自己的叫法 o(∩_∩)o...哈哈   说的就是在确认一次按键有效后锁住,必须检测到按键松开后解锁  其后才能检测下一次按键;(2次有效按键之间必须检测到一次按键松开)

使用特权

评论回复
9
liao_fangxing| | 2010-4-28 13:50 | 只看该作者
别用延时做  如果有定时器那么用定时器 没有则可用连续累计次数

使用特权

评论回复
10
book99|  楼主 | 2010-4-28 14:19 | 只看该作者
连续累计次数是下面这样写吗, 我试了 按键没有反应 长按短按都没有反应??? [sbit key1=P4^3;
uchar Key_sig(void)
{
uchar keysta=0;
int keynum=0;
//keys1=key1;
if(key1==0)
{
  
  if(key1==0)
  {
   
      key_num++;
      if(key_num>300)
     key_num=300;
    else if((key_num>80)&(key_num<200)) //短键
     keysta=1;
      else if((key_num<300)&(key_num>200))// 长键
     keysta=2;
  
  }
  else
  keysta=0;
  return keysta;

}
}

使用特权

评论回复
11
ayb_ice| | 2010-4-28 14:30 | 只看该作者
错误明显
<if((key_num>80)&(key_num<200)) //短键>
                   ----->&&<------------

使用特权

评论回复
12
liao_fangxing| | 2010-4-28 14:47 | 只看该作者
你是用主函数调用“uchar Key_sig(void)”  那么int keynum=0;  这个变量得是全局变量或静态 而且在key1==1后处理完短按时清零

使用特权

评论回复
13
liao_fangxing| | 2010-4-28 15:06 | 只看该作者
本帖最后由 liao_fangxing 于 2010-4-28 15:08 编辑

unsigned int keynum=0;
unsigned char keysta=0;
unsigned char lock_key=0; //锁
unsigned char s_key=0;    //短按**

void Key_sig(void)
{
  keysta=0;
if(key1==0)
  {
    if(!lock_key)
    {   
      key_num++;
      
      if(key_num>80)
              s_key=1;
              
      if(key_num>200)
              {
                      s_key=0;  //此次按键是长按 则取消前面短按**
                      keysta=2;
                      lock_key=1;//锁存 直到松开按键
              }                     
     
    }
  
  }
else
        {
                if(s_key)  //检测是否有短按**
                  {
                          keysta=1;
                  }
               
                //以下为重新复位变量
                 key_num=0;
                 s_key=0;
                 lock_key=0;//解锁                  
        }
}


void mian(void)

{
//初始化



while(1)
{
        Key_sig();
        if(keysta==1)
                {//短按
                        
                }
        else if(keysta==2)
                {//长按
                        
                }
                        
}        
}



随手写了下 没编译 可能有错  不过思路大概就这样

PS:其中80和200这2个参数可能得根据实际情况进行调整

使用特权

评论回复
14
book99|  楼主 | 2010-4-28 15:39 | 只看该作者
我新改的程序,运行时,怎么按按键 液晶都没反应????
uchar key_test(void)
{
  static int kn=0;
        uchar key_st=0;
       
          if(key1==0)
                {
                  //if(key1==0)
      // {
                                kn++;
                                if(kn>400)
                                kn=400;
                        if((kn>80)&&(kn<200))
                        {
                                key_st=1;
                                kn=0;
                        }
                        if((kn>200)&&(kn<=400))
                        key_st=2;
     else
                 key_st=0;
                //}
               
                }
    return key_st;
}
main()
{
while(1)
        {
   //i=key_test();
         if(key_test()==1)
         show_string("AABBCCDD",32,6,0);//液晶显示
         
         
         if(key_test()==2)
         show_string("EEFF",96,6,0); //液晶显示
   //t_tpye();
  }

}

使用特权

评论回复
15
wwspare| | 2010-4-28 16:08 | 只看该作者
void KeySub(void)
{
if(K_Done_F&&K_LongDown_F==0)//检测有按键按下,而且没有执行过长按功能
{
  if(KeyBoad.KeyValueLong==KeyBoad.KeyValueLongBuf)//判断本次按键和上次是不是一样
  {
      if(KeyBoad.KeyValueLong==KeyLong1_C||KeyBoad.KeyValueLong==KeyLong2_C||KeyBoad.KeyValueLong==KeyLong3_C)//检测是不是长按键
   {
    if(KeyBoad.KeyUp_T<KeyLongT_C)KeyBoad.KeyUp_T++;//长按时间是不是到
    else  
    {
     if(KeyBoad.KeyValueLong==KeyLong1_C)
     {
      KeyBoad.KeyValue=KeyLongValue1_C//执行长按按键
      K_New_F=1;
     }
     else if(KeyBoad.KeyValueLong==KeyLong1_C)
     {
      KeyBoad.KeyValue=KeyLongValue1_C//执行长按按键
      K_New_F=1;
     }
     else if(KeyBoad.KeyValueLong==KeyLong1_C)
     {
      KeyBoad.KeyValue=KeyLongValue1_C//执行长按按键
      K_New_F=1;
     }
    }
   }
  }
  else//按键有切换则清零
  {
   KeyBoad.KeyValueLongBuf=KeyBoad.KeyValueLong;
   KeyBoad.KeyUp_T=0;
   KeyBoad.KeyAdd_T=0;
   KeyBoad.KeyUp_T=0;
  }
}
}
}

使用特权

评论回复
16
wwspare| | 2010-4-28 16:10 | 只看该作者
上面的程序,是我子程序库里的一个,只要更改一下几个宏定义就可以了

使用特权

评论回复
17
wwspare| | 2010-4-28 16:11 | 只看该作者
K_Done_F//指检测到新的按键

使用特权

评论回复
18
wwspare| | 2010-4-28 16:12 | 只看该作者
把你单击的按键键值传递给变量:KeyBoad.KeyValueLong

使用特权

评论回复
19
book99|  楼主 | 2010-4-28 16:19 | 只看该作者
13# liao_fangxing
如果不加延时的话 程序运行太快 只能识别长键,不能识别短键 即把所有键都当成了长键 不管按下的时间多短 即使把200换成60000都不行

使用特权

评论回复
20
xh89595009| | 2010-4-28 16:39 | 只看该作者
AVRX_GCC_TASKDEF(KeyTask, 128, 3)
{
        TimerControlBlock delaytimer;
        unsigned char KeyValue,KeyValueOld,FilterCounter,LongFilterCounter;

        KEY_UP_PORT &= ~KEY_UP_BIT;
        KEY_UP_DDR &= ~KEY_UP_BIT;
        KEY_DOWN_PORT &= ~KEY_DOWN_BIT;
        KEY_DOWN_PORT &= ~KEY_DOWN_BIT;
        AvrXDelay(&delaytimer, 1000);
        while(1)
        {
                AvrXDelay(&delaytimer, 5);
                KeyValue = ((~KEY_PIN) & KEY_MASK);
                if(KeyValue != 0)        //有键值
                {
                        if(KeyValue == KeyValueOld) //与旧键值相同
                        {
                                if(LongFilterCounter != 0)        //已经启用长按去抖
                                {
                                        LongFilterCounter ++;
                                        if(LongFilterCounter >= 10)        BELL_OFF;
                                        if(LongFilterCounter >= 160)
                                        {
                                        //        SpeedSetValue++;        //长按键运行函数
                                                LongKeyFun(KeyValue);
                                                LongFilterCounter = 157;       
                                        }
                                }
                                else        //没启用长按去抖
                                {
                                        FilterCounter++;        //去抖计数器+1
                                //        BELL_ON;
                                        if(FilterCounter >= 100)
                                        {
                                                BELL_ON;
                                        //        SpeedSetValue ++;        //短按键运行函数
                                                KeyFun(KeyValue);
                                                LongFilterCounter = 1;       
                                        }
                                }
                        }
                        else
                        {
                                BELL_OFF;
                                KeyValueOld = KeyValue;
                                FilterCounter = 0;
                                LongFilterCounter = 0;
                        }
                }
                else
                {
                        BELL_OFF;
                        KeyValueOld = KeyValue;
                        LongFilterCounter = 0;
                        FilterCounter = 0;
                }
        }
}

我写的 AVRX的KEY任务  短按键延时 长按键延时 长按键之间缩短延时

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

13

主题

185

帖子

4

粉丝