vb2002 发表于 2024-12-28 23:41:35

找到个很好的状态机按键程序.想添加3击,4击,怎么弄哦求大神


之前找到个三击四击的.但是和掉电模式的唤醒有冲突.不能唤醒.
这个可以直接唤醒.
但是不会加3击4击,或者短击接着马上长击.. 长击马上短击,,短击短击长击,,长击短击短击


vb2002 发表于 2024-12-28 23:42:21

//---按键读取(状态机方式)---
//采用不返回参数方式,将按键值直接赋予全局变量"Key_value"
void Key_Scan(void)
{
    static u8 KeyState = 0; //按键状态(必须为静态"static"变量)
    static u8 KeyTime = 0;//计时(必须为静态"static"变量)
       
    switch(KeyState)//0=初始状态,1=确认状态,2=短按/长按判断状态,3=单击/双击判断状态,88=释放状态
    {
    case 0://进入按键"初始"状态
      if (!key)//如有按键按下
      {
            KeyState = 1;//转到按键"确认"状态
      }
      break;//按键"初始"状态结束
    case 1://进入按键"确认"状态(消抖)
      if (!key)//如按键仍按下
      {
            KeyTime = 0;//计时清零(准备计时)
            KeyState = 2;//转到"短按/长按"判断状态
      }
      else//否则, (按键已松开)
      {
            Key_value = 0;//是"无键"
            KeyState = 0;//转到按键"初始"状态
      }
      break;//按键"确认"状态结束
    case 2://进入按键"短按/长按"判断状态
      if ( key)//如按键已松开
      {
            KeyState = 3;//转到按键"单击/双击"判断状态,(即第一次单击不作反应,待后面来判断是否有双击)
      }
      else//否则, (按键仍按下)
      {
            if(++KeyTime >= 30)//如"长按"计时到, ("长按"的保持时间,可调整)
            {
                KeyTime = 0;//计时清零
                Key_value = 2;//是"长按"
                KeyState = 88;//转到按键"释放"状态
            }
      }
      break;//按键"短按/长按"判断状态结束
    case 3://进入按键"单击/双击"判断状态
      if (!key)//如按键又按下, (即第二次按下)
      {
            Key_value = 3;//是"双击"
            KeyState = 88;//转到按键"释放"状态
      }
      else//否则, (按键未按下)
      {
            if(++KeyTime >= 30)//如"双击"计时到, ("双击"的间隔时间,可调整)
            {
                KeyTime = 0;//计时清零
                Key_value = 1;//是"短按"(单击)
                KeyState = 0;//转到按键"初始"状态
            }
      }
      break;//按键"单击/双击"判断状态结束
    case 88://进入按键"释放"状态
      if ( key)//如按键已松开
      {
            KeyState = 0;//转到按键初始状态
      }
      break;//按键"释放"状态结束
    }
}

21cnsound 发表于 2024-12-29 06:45:34

建议画一下状态机转换图,标注清楚原理(各个状态的进入条件、状态内处理)再写代码。

vb2002 发表于 2024-12-29 08:58:57

wnagming 发表于 2024-12-29 07:18
手动改改吧,按键释放未超过一个时间被再次按下,表示连按,这样累加,连按3次就是3击,连按4次就是4击 ...

增加了一个计数器
然后判定3击.成了


vb2002 发表于 2024-12-29 08:59:17

21cnsound 发表于 2024-12-29 06:45
建议画一下状态机转换图,标注清楚原理(各个状态的进入条件、状态内处理)再写代码。 ...

好像可以了. 增加了一个变量来计数三击,,

vb2002 发表于 2024-12-29 10:10:34

wnagming 发表于 2024-12-29 07:18
手动改改吧,按键释放未超过一个时间被再次按下,表示连按,这样累加,连按3次就是3击,连按4次就是4击 ...
如果不加变量

是否是需要在 case 3 那里做出三个判定
1,判定单击还是双击
2,判定双击还是三击
3,确认是双击(到case3 以后 超时就是双击,,未超时继续按下就是三击)

lezjin 发表于 2024-12-29 10:14:11

这个是单按键还是多按键的?

vb2002 发表于 2024-12-29 11:41:50

lezjin 发表于 2024-12-29 10:14
这个是单按键还是多按键的?

一个按键复用多种状态
类似于以前的汽车调节时间那个,就一个按钮调节
短按,长按,双击,

vb2002 发表于 2024-12-29 11:46:00

wnagming 发表于 2024-12-29 10:44
鼠标操作是按下和松开都有事件的,我推荐你使用第一种,按下即执行,但要保证单机指令不影响双击,双击指令 ...

这个理解为上升沿和下降沿
我这个应该只能用第二种.
刚刚我不添加变量的已经弄好了. 但是有一个问题.
双击可以正常识别.
三击也能识别出来.
但是三击需要双击以后,第三次不松手才能识别出三击.
误打误撞实现了我说的那个 短按,短按,长按的效果.
但并非我想要的效果.
可能是case4那个地方没有处理好. ++keytime>=50那里 .
我在下面贴出来

vb2002 发表于 2024-12-29 11:50:44

wnagming 发表于 2024-12-29 10:44
鼠标操作是按下和松开都有事件的,我推荐你使用第一种,按下即执行,但要保证单机指令不影响双击,双击指令 ...




页: [1] 2 3
查看完整版本: 找到个很好的状态机按键程序.想添加3击,4击,怎么弄哦求大神