长按键的判断

TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
 ……
 //打印日志aType  iRepeats:

 switch (aKeyEvent.iCode)
 {
  case EKeyUpArrow:
  {
   //按键处理         
   break;
  }
  case EKeyDownArrow:
  {
   //按键处理         
   break;
  }
 }
 ……
}


短按键日志信息:
EEventKeyDown  iRepeats:0
EEventKey      iRepeats:0         
EEventKeyUp    iRepeats:0


长按键日志信息:
EEventKeyDown  iRepeats:0
EEventKey      iRepeats:0          //第一次会走短按键处理
EEventKey      iRepeats:1
EEventKey      iRepeats:1
……
EEventKey      iRepeats:1
EEventKeyUp    iRepeats:0

 


方案:上下键延迟到弹起时处理。

TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
   ……
    if (EEventKeyUp == aType && iKeyEvent.iRepeats == 0)
    {
        if (iKeyEvent.iCode == EKeyUpArrow)
        {
            HandleUpArrowEventL(iKeyEvent, EEventKey);
        }

        if (iKeyEvent.iCode == EKeyDownArrow)
        {
            HandleDownArrowEventL(iKeyEvent, EEventKey);
        }
    }

  //增加成员变量iKeyEvent,保存上一次aKeyEvent。
  iKeyEvent = aKeyEvent;    

  switch (aKeyEvent.iCode)
  {
      case EKeyUpArrow:
        {
     if (aKeyEvent.iRepeats == 1)
     {
      //长按键处理
     }         
     break;
       }
       case EKeyDownArrow:
       {
     if (aKeyEvent.iRepeats == 1)
     {
      //长按键处理
     }         
     break;
    }
    //其它键处理不变
 }
 ……
}

 


但是有些手机iRepeats不同


E52手机 长按键日志信息:
 EEventKeyDown   iRepeats:0
 EEventKey       iRepeats:0
 EEventKey       iRepeats:0
 EEventKey       iRepeats:536975507
 EEventKey       iRepeats:536975507
 ……
 EEventKey       iRepeats:536975507
 EEventKeyUp     iRepeats:536975507
 
6700s手机iRepeats始终为0


解决方法:

TKeyResponse OfferKeyEventL(const TKeyEvent& aKeyEvent, TEventCode aType)
{
   ……
  
  if ((EEventKeyUp == aType) || (EEventKeyDown == aType))
    {
        iKeyEventNum = 0;
    }
    else
    {
        iKeyEventNum++;
    }

    TKeyEvent keyEvent = aKeyEvent;

    if (3 <= iKeyEventNum)
    {
        keyEvent.iRepeats = 1;
        iKeyEventNum = 3;
    }
   
    if (EEventKeyUp == aType && iKeyEvent.iRepeats == 0)
    {
        if (iKeyEvent.iCode == EKeyUpArrow)
        {
            HandleUpArrowEventL(iKeyEvent, EEventKey);
        }

        if (iKeyEvent.iCode == EKeyDownArrow)
        {
            HandleDownArrowEventL(iKeyEvent, EEventKey);
        }
    }

  //增加成员变量iKeyEvent
  iKeyEvent = keyEvent;    

  switch (keyEvent.iCode)
  {
      case EKeyUpArrow:
        {
     if (keyEvent.iRepeats == 1)
     {
      //长按键处理
     }         
     break;
       }
       case EKeyDownArrow:
       {
     if (keyEvent.iRepeats == 1)
     {
      //长按键处理
     }         
     break;
    }
    //其它键处理不变
 }
 ……
}

### C51 单片机独立按键判断实现方法 为了实现在C51单片机上对独立按键按事件检测,可以采用定时器配合状态机的方式来进行处理。下面是一个具体的实现方案。 #### 定义变量与初始化设置 定义必要的全局变量用于记录按键的状态以及计数时间间隔内的按键次数: ```c unsigned int key_long_press_time = 0; // 记录按键持续的时间 bit long_pressed_flag = 0; // 标记是否发生过按操作 ``` 在`main()`函数之前完成这些声明,并确保它们在整个程序范围内可见。 对于硬件资源而言,在主循环外调用相应的初始化子程序来配置好所需的I/O端口和中断源等参数[^1]。 #### 主要逻辑流程设计 通过不断轮询读取当前是否有键被按下(`Key()`)并依据返回值更新上述两个标志位之一;当发现有特定编号的按键处于闭合状态时启动一个周期性的延时过程(通常借助于软件延迟或更推荐使用的硬件定时/计数器),期间保持监测该按钮是否仍然维持激活状况直到达到预设阈值才确认为“按”。 一旦判定发生了时间触摸行为,则置高对应的指示信号以便后续业务模块能够据此作出响应动作;反之则认为是一次瞬态点击即所谓的“短按”。具体代码如下所示: ```c void main(void){ Timer1Init(); // 初始化定时器 while (TRUE){ // 进入无限循环等待按键输入 KeyNum = Key(); // 获取当前按键编码 if(KeyNum == 1){ // 如果检测到目标按键按下 TMOD |= 0x10; // 设置T1工作模式为方式1(16位自动重装载) TH1 = TL1 = 0xFF; // 设定初值以获得大约1ms溢出周期 TR1 = 1; // 启动定时器 do{ // 循环检查直至超时或者松开为止 if(TF1 != 0){ // 当前时刻已过去至少1毫秒 TF1 = 0; if(!Key()) break; // 若此时按键已经释放跳出内层循环 ++key_long_press_time;// 增加累计停留时间量度 if(key_long_press_time >= LONG_PRESS_THRESHOLD){ long_pressed_flag = 1; // 达到了设定好的按时限触发标记 /* 执行此处应采取的动作 */ goto end_of_checking;/* 跳转至结束处防止重复进入此分支*/ } } }while(TRUE); end_of_checking: TR1 = 0; // 关闭定时器停止进一步累加 TH1 = TL1 = 0; // 清零寄存器准备下一轮测试 ET1 = EX1 = IE = EA = 0; // 禁用所有相关中断以防干扰正常运行流控结构 } // 处理其他可能存在的任务... if(long_pressed_flag){ /* 对于已被识别出来的'按'情况做额外处理 */ long_pressed_flag = 0; // 重置状态供下次评估使用 } } } ``` 以上伪代码片段展示了如何利用定时机制辅助判别用户交互意图——区分简单的轻触还是较持久的压力施加情形。值得注意的是实际应用中还需考虑去抖动措施确保采集数据准确性等问题[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值