王昱顺 发表于 2024-12-10 14:23:05

vb2002 发表于 2024-12-10 14:13
或者说,长按和双击翻转P20   P21
短按在哪里执行哦?

双击是必定触发一次单击的,逻辑上就是这样。
所以我没放一块,单击和长按是可以共存的

vb2002 发表于 2024-12-10 14:25:19

王昱顺 发表于 2024-12-10 14:23
双击是必定触发一次单击的,逻辑上就是这样。
所以我没放一块,单击和长按是可以共存的 ...

难怪我在上面打印一个变量
每次都会触发单击
我好好琢磨一下先吧.
不懂再来请教

bkeuqoaq 发表于 2024-12-10 14:38:55

主循环对time的访问没有满足原子操作,存在BUG

bkeuqoaq 发表于 2024-12-10 14:43:04

这个双击不严谨,第一次长按多久也算是一击,一般双击必须是快速的双击

vb2002 发表于 2024-12-10 14:55:12

bkeuqoaq 发表于 2024-12-10 14:43
这个双击不严谨,第一次长按多久也算是一击,一般双击必须是快速的双击

有好的代码分享一下吗?
只要长按单击就行

bkeuqoaq 发表于 2024-12-10 15:24:27

vb2002 发表于 2024-12-10 14:55
有好的代码分享一下吗?
只要长按单击就行

这是真正项目使用的代码,部分宏定义没有列出,意思一看就明白

enum{
        //不可修改
    KEY1 = 0x0001,
    KEY2 = 0x0002,
    KEY3 = 0x0004,

        //不可修改
    KEY_EVENT__SDOWN   = 0x0100,        //短按按下
    KEY_EVENT__LDOWN   = 0x0200,    //长按按下
    KEY_EVENT__CDOWN   = 0x0400,    //连按按下
    KEY_EVENT__SUP   = 0x0800,    //短按松开
    KEY_EVENT__LUP   = 0x1000,    //长按松开
    KEY_EVENT__CUP   = 0x2000,    //连按松开

        //不可修改
        KEY_NUM__ANY = (KEY1+KEY2+KEY3),
        KEY_EVENT__DOWN = KEY_EVENT__SDOWN+KEY_EVENT__LDOWN+KEY_EVENT__CDOWN,
        KEY_EVENT__UP = KEY_EVENT__SUP+KEY_EVENT__LUP+KEY_EVENT__CUP,
        KEY_EVENT__ALL = KEY_EVENT__DOWN+KEY_EVENT__UP,

        //_______________________________________
        //指定按键事件
        KEY1_SDOWN = (KEY1+KEY_EVENT__SDOWN),
        KEY1_SUP   = (KEY1+KEY_EVENT__SUP),
        KEY1_LDOWN = (KEY1+KEY_EVENT__LDOWN),
        KEY1_LUP   = (KEY1+KEY_EVENT__LUP),
        KEY2_SDOWN = (KEY2+KEY_EVENT__SDOWN),
        KEY2_LDOWN = (KEY2+KEY_EVENT__LDOWN),
        KEY2_LUP   = (KEY2+KEY_EVENT__LUP),
        KEY2_CDOWN = (KEY2+KEY_EVENT__CDOWN),
        KEY2_SUP   = (KEY2+KEY_EVENT__SUP),
        KEY3_SDOWN = (KEY3+KEY_EVENT__SDOWN),
        KEY3_LDOWN = (KEY3+KEY_EVENT__LDOWN),
        KEY3_LUP   = (KEY3+KEY_EVENT__LUP),
        KEY3_SUP   = (KEY3+KEY_EVENT__SUP),
        KEY3_CDOWN = (KEY3+KEY_EVENT__CDOWN),
};

#define MS        /10u

//请循环调用,建议10MS调用周期
void KEY_Scan(void)
{
    Key_Typedef* pKey = &s_stKey;
    u32 ulNum=0;
    u32 ulTmpEvent = 0;
    u32 ulGpio = 0;

    pKey->usEventEx = 0;
    if (!GPIO_VAL_GET(GPIO_S1))
    {
      ulGpio = KEY1;
      ulNum++;
    }
    if (GPIO_VAL_GET(GPIO_S2))        //高电平有效
    {
      ulGpio = KEY2;
      ulNum++;
    }
    if (!GPIO_VAL_GET(GPIO_S3))
    {
      ulGpio = KEY3;
      ulNum++;
    }

    if (ulNum == 0)
    {
      //松开
      u16 usTmp = pKey->usDeb;
      pKey->usDeb = 0;
      if (usTmp != 0xffff)
      {
            if (usTmp > 3000MS)
            {
                //此项目不需要此按键事件
                //ulTmpEvent = pKey->ucBkpGpio + KEY_EVENT__CUP;
            }
            else
            if (usTmp > 1000MS)
            {
                ulTmpEvent = pKey->usBkpGpio + KEY_EVENT__LUP;
            }
            else
            if (usTmp > 50MS)
            {
                ulTmpEvent = pKey->usBkpGpio + KEY_EVENT__SUP;
            }
      }
    }
    else
    if (ulNum > 1)
    {
      KEY_Hold();
      return;
    }
    else
    if (ulNum == 1)
    {
      //正常按下
      if (pKey->usDeb != 0xffff)
      {
            pKey->usDeb++;

            if (pKey->usDeb == 40MS)
            {
                ulTmpEvent = ulGpio + KEY_EVENT__SDOWN;
            }
            else
            if (pKey->usDeb == 1000MS)
            {
                ulTmpEvent = ulGpio + KEY_EVENT__LDOWN;
            }
            else
            {
                bit bRepeat = (pKey->usDeb >= (3000MS+1000MS/5))?1:0;
                if (bRepeat || pKey->usDeb == 3000MS)
                {
                  ulTmpEvent = ulGpio + KEY_EVENT__CDOWN;

                  if (bRepeat)
                  {
                        pKey->usDeb = 3000MS + 1;
                  }
                }
            }
      }
    }

    if (ulTmpEvent)
    {
      pKey->usBkpGpio = ulTmpEvent & KEY_NUM__ANY;
      pKey->usEventEx = ulTmpEvent;
    }
}

u32 KEY_GetEx(void)
{
    return s_stKey.usEventEx;
}

        //判断按键的代码必须每个循环周期调用,以确保同步
        if (KEY_GetEx() == KEY1_SUP)
        {
                MF_Set2New(MF_INDEX__MENU0);
        }

bkeuqoaq 发表于 2024-12-10 15:32:02

void KEY_Hold(void)
{
    s_stKey.usBkpGpio = 0;
    s_stKey.usDeb = 0xffff;
}

bkeuqoaq 发表于 2024-12-10 15:36:12

以上代码实际项目使用ARM-M0内核

vb2002 发表于 2024-12-10 16:46:34

弄好了. 仅保留单击和长按, 运行完美,可以唤醒掉电模式


       if (t_10ms)
      {
            t_10ms = 0; // 10ms同步
            val = Get_Key();
            down = val & (val ^ old);
            up = old & (val ^ old);
            old = val;
            if (down == 1)
            {
                l_key = time;
//                if (time - d_key < 200)
//                   P54 = ~P54;   
            }
            if (up == 1)
            {
                if (time - l_key > 100)
               P55 = ~P55;
                else
//                  d_key = time;
                  P54 = ~P54;
            }
      }

vb2002 发表于 2024-12-10 17:05:49

bkeuqoaq 发表于 2024-12-10 15:24
这是真正项目使用的代码,部分宏定义没有列出,意思一看就明白

enum{


c语言底子太差了. 这个我完全看不懂
页: 1 2 [3] 4
查看完整版本: 三行又四行,简单实现长按双击识别