打印
[单片机芯片]

触摸/轻触按键的长按和短按实现

[复制链接]
2504|15
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lilijin1995|  楼主 | 2023-7-6 10:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lilijin1995 于 2023-7-6 10:24 编辑

今天想和大家分享一个触摸/轻触按键的长按和短按实现;GitHub有好轮子MultiButton,本来我也想着直接套用,奈何MCU资源太有限,ROM是连Flash都没有的,是支持1000 次写操作MTP ;
实习参加工作时候有继承公司的一套I2C驱动触摸芯片代码如下:
//=============================================================================
//Function:TK scan
//Input:  null
//Output: KeyCode
//Remark: call every 10ms
//=============================================================================
UINT8 ctm_TKScan(void)
{
        volatile UINT16 TKStatue = 0;
        volatile UINT8 TKStatue_L = 0;
        volatile UINT8 TKStatue_H = 0;

        //Power delay 500ms, wait TK stable!
        if( TKScan_PowerDelay <= 50 )
        {        
                return 0;
        }
        
        //clr keycode  
        KeyCode = D_KeyNull;
        
        //backup "AnyKeyDn_Flag" statue
        if( AnyKeyDn_Flag ){
                AnyKeyDnBuf_Flag = 1;}
        else{
                AnyKeyDnBuf_Flag = 0;}
        
        //read key value
        TKStatue_L = ctm_APT8L16_RdByte( R_K0_VR );                                //read key value        
        TKStatue_H = ctm_APT8L16_RdByte( R_K1_VR );                                //read key value        
        TKStatue = (((UINT16)TKStatue_H)<<8) + TKStatue_L;

        //key12 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK13) )
                {
                        Key12_DCnt += 1;        
                }
                else
                {
                        Key12_DCnt = 0;
                }
                //down
                if( Key12_DCnt >= D_KeyDCnt )
                {
                        Key12_DCnt = 0;
                        Key12Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key11 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK12) )
                {
                        Key11_DCnt += 1;        
                }
                else
                {
                        Key11_DCnt = 0;
                }
                //down
                if( Key11_DCnt >= D_KeyDCnt )
                {
                        Key11_DCnt = 0;
                        Key11Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key10 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK11) )
                {
                        Key10_DCnt += 1;        
                }
                else
                {
                        Key10_DCnt = 0;
                }
                //down
                if( Key10_DCnt >= D_KeyDCnt )
                {
                        Key10_DCnt = 0;
                        Key10Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key9 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK10) )
                {
                        Key9_DCnt += 1;        
                }
                else
                {
                        Key9_DCnt = 0;
                }
                //down
                if( Key9_DCnt >= D_KeyDCnt )
                {
                        Key9_DCnt = 0;
                        Key9Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }
        
        //key8 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK07) )
                {
                        Key8_DCnt += 1;        
                }
                else
                {
                        Key8_DCnt = 0;
                }
                //down
                if( Key8_DCnt >= D_KeyDCnt )
                {
                        Key8_DCnt = 0;
                        Key8Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key7 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK06) )
                {
                        Key7_DCnt += 1;        
                }
                else
                {
                        Key7_DCnt = 0;
                }
                //down
                if( Key7_DCnt >= D_KeyDCnt )
                {
                        Key7_DCnt = 0;
                        Key7Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key6 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK05) )
                {
                        Key6_DCnt += 1;        
                }
                else
                {
                        Key6_DCnt = 0;
                }
                //down
                if( Key6_DCnt >= D_KeyDCnt )
                {
                        Key6_DCnt = 0;
                        Key6Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key5 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK04) )
                {
                        Key5_DCnt += 1;        
                }
                else
                {
                        Key5_DCnt = 0;
                }
                //down
                if( Key5_DCnt >= D_KeyDCnt )
                {
                        Key5_DCnt = 0;
                        Key5Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key4 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK03) )
                {
                        Key4_DCnt += 1;        
                }
                else
                {
                        Key4_DCnt = 0;
                }
                //down
                if( Key4_DCnt >= D_KeyDCnt )
                {
                        Key4_DCnt = 0;
                        Key4Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }
        
        //key3 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK02) )
                {
                        Key3_DCnt += 1;        
                }
                else
                {
                        Key3_DCnt = 0;
                }
                //down
                if( Key3_DCnt >= D_KeyDCnt )
                {
                        Key3_DCnt = 0;
                        Key3Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }

        //key2 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK01) )
                {
                        Key2_DCnt += 1;        
                }
                else
                {
                        Key2_DCnt = 0;
                }
                //down
                if( Key2_DCnt >= D_KeyDCnt )
                {
                        Key2_DCnt = 0;
                        Key2Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }        
        
        //key1 down
        if( AnyKeyDn_Flag == 0 )
        {
                //debonce
                if( (TKStatue & D_TK00) )
                {
                        Key1_DCnt += 1;        
                }
                else
                {
                        Key1_DCnt = 0;
                }
                //down
                if( Key1_DCnt >= D_KeyDCnt )
                {
                        Key1_DCnt = 0;
                        Key1Dn_Flag = 1;
                        AnyKeyDn_Flag = 1;
                }
        }        


        //key12 long down               
        if( Key12Dn_Flag && (Key12LDn_Flag==0) )
        {
                Key12_LDCnt += 1;
                if( Key12_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key12_LDCnt = 0;
                        Key12LDn_Flag = 1;
                        KeyCode = D_KeyAuto02LD;
                }
        }
        else
        {
                Key12_LDCnt = 0;        
        }

        //key11 long down               
        if( Key11Dn_Flag && (Key11LDn_Flag==0) )
        {
                Key11_LDCnt += 1;
                if( Key11_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key11_LDCnt = 0;
                        Key11LDn_Flag = 1;
                        KeyCode = D_KeyAuto01LD;
                }
        }
        else
        {
                Key11_LDCnt = 0;        
        }

        //key10 long down               
        if( Key10Dn_Flag && (Key10LDn_Flag==0) )
        {
                Key10_LDCnt += 1;
                if( Key10_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key10_LDCnt = 0;
                        Key10LDn_Flag = 1;
                        KeyCode = D_KeyPowerLD;
                }
        }
        else
        {
                Key10_LDCnt = 0;        
        }

        //key9 long down               
        if( Key9Dn_Flag && (Key9LDn_Flag==0) )
        {
                Key9_LDCnt += 1;
                if( Key9_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key9_LDCnt = 0;
                        Key9LDn_Flag = 1;
                        KeyCode = D_KeyAmountLD;
                }
        }
        else
        {
                Key9_LDCnt = 0;        
        }
        
        //key8 long down               
        if( Key8Dn_Flag && (Key8LDn_Flag==0) )
        {
                Key8_LDCnt += 1;
                if( Key8_LDCnt >= 500 )                                //500*10ms=5s                        
                {
                        Key8_LDCnt = 0;
                        Key8LDn_Flag = 1;
                        KeyCode = D_KeyTimerLD;
                }
        }
        else
        {
                Key8_LDCnt = 0;        
        }
        
        //key7 long down               
        if( Key7Dn_Flag && (Key7LDn_Flag==0) )
        {
                Key7_LDCnt += 1;
                if( Key7_LDCnt >= 500 )                                //500*10ms = 5s
                {
                        Key7_LDCnt = 0;
                        Key7LDn_Flag = 1;
                        KeyCode = D_KeyUpLD;
                }
        }
        else
        {
                Key7_LDCnt = 0;        
        }
        
        //Key6 long down               
        if( Key6Dn_Flag && (Key6LDn_Flag==0) )
        {
                Key6_LDCnt += 1;
                if( Key6_LDCnt >= 500 )                                        //500*10ms = 5s
                {
                        Key6_LDCnt = 0;
                        Key6LDn_Flag = 1;
                        KeyCode = D_KeyDownLD;
                }
        }
        else
        {
                Key6_LDCnt = 0;        
        }
        
        //key5 long down               
        if( Key5Dn_Flag && (Key5LDn_Flag==0) )
        {
                Key5_LDCnt += 1;
                if( Key5_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key5_LDCnt = 0;
                        Key5LDn_Flag = 1;
                        KeyCode = D_KeyVersionLD;
                }
        }
        else
        {
                Key5_LDCnt = 0;        
        }
        
        //key4 long down               
        if( Key4Dn_Flag && (Key4LDn_Flag==0) )
        {
                Key4_LDCnt += 1;
                if( Key4_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key4_LDCnt = 0;
                        Key4LDn_Flag = 1;
                        KeyCode = D_KeyWaterLD;
                }
        }
        else
        {
                Key4_LDCnt = 0;        
        }
        
        //key3 long down               
        if( Key3Dn_Flag && (Key3LDn_Flag==0) )
        {
                Key3_LDCnt += 1;
                if( Key3_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key3_LDCnt = 0;
                        Key3LDn_Flag = 1;
                        KeyCode = D_KeyCleanLD;
                }
        }
        else
        {
                Key3_LDCnt = 0;        
        }
        
        //key2 long down               
        if( Key2Dn_Flag && (Key2LDn_Flag==0) )
        {
                Key2_LDCnt += 1;
                if( Key2_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key2_LDCnt = 0;
                        Key2LDn_Flag = 1;
                        KeyCode = D_KeyHandLD;
                }
        }
        else
        {
                Key2_LDCnt = 0;        
        }
        
        //key1 long down               
        if( Key1Dn_Flag && (Key1LDn_Flag==0) )
        {
                Key1_LDCnt += 1;
                if( Key1_LDCnt >= 500 )                                //500*10ms=5s
                {
                        Key1_LDCnt = 0;
                        Key1LDn_Flag = 1;
                        KeyCode = D_KeyContinueLD;
                }
        }
        else
        {
                Key1_LDCnt = 0;        
        }

        //all key release
        if( AnyKeyDn_Flag && (TKStatue==0) )
        {
                AllKeyRel_DCnt += 1;
                if( AllKeyRel_DCnt >= 3 )
                {
                        //释放响应
                        if( Key12Dn_Flag && (Key12LDn_Flag==0) ){        
                                KeyCode = D_KeyAuto02;        }
                        if( Key11Dn_Flag && (Key11LDn_Flag==0) ){        
                                KeyCode = D_KeyAuto01;        }
                        if( Key10Dn_Flag && (Key10LDn_Flag==0) ){        
                                KeyCode = D_KeyPower;        }
                        if( Key9Dn_Flag && (Key9LDn_Flag==0) ){        
                                KeyCode = D_KeyAmount;        }
                        if( Key8Dn_Flag && (Key8LDn_Flag==0) ){               
                                KeyCode = D_KeyTimer;                }
                        if( Key7Dn_Flag && (Key7LDn_Flag==0) ){        
                                KeyCode = D_KeyUp;        }
                        if( Key6Dn_Flag && (Key6LDn_Flag==0) ){        
                                KeyCode = D_KeyDown; }
                        if( Key5Dn_Flag && (Key5LDn_Flag==0) ){        
                                KeyCode = D_KeyVersion;        }
                        if( Key4Dn_Flag && (Key4LDn_Flag==0) ){        
                                KeyCode = D_KeyWater;        }
                        if( Key3Dn_Flag && (Key3LDn_Flag==0) ){        
                                KeyCode = D_KeyClean;}
                        if( Key2Dn_Flag && (Key2LDn_Flag==0) ){        
                                KeyCode = D_KeyHand;        }
                        if( Key1Dn_Flag && (Key1LDn_Flag==0) ){        
                                KeyCode = D_KeyContinue;        }
                        
                        //clr ram
                        AnyKeyDn_Flag = 0;
                        AllKeyRel_DCnt = 0;
                        
                        Key12Dn_Flag = 0;
                        Key12LDn_Flag = 0;
                        Key12_DCnt = 0;
                        Key12_LDCnt = 0;

                        Key11Dn_Flag = 0;
                        Key11LDn_Flag = 0;
                        Key11_DCnt = 0;
                        Key11_LDCnt = 0;
                        
                        Key10Dn_Flag = 0;
                        Key10LDn_Flag = 0;
                        Key10_DCnt = 0;
                        Key10_LDCnt = 0;

                        Key9Dn_Flag = 0;
                        Key9LDn_Flag = 0;
                        Key9_DCnt = 0;
                        Key9_LDCnt = 0;

                        Key8Dn_Flag = 0;
                        Key8LDn_Flag = 0;
                        Key8_DCnt = 0;
                        Key8_LDCnt = 0;
                        
                        Key7Dn_Flag = 0;
                        Key7LDn_Flag = 0;
                        Key7_DCnt = 0;
                        Key7_LDCnt = 0;

                        Key6Dn_Flag = 0;
                        Key6LDn_Flag = 0;
                        Key6_DCnt = 0;
                        Key6_LDCnt = 0;

                        Key5Dn_Flag = 0;
                        Key5LDn_Flag = 0;
                        Key5_DCnt = 0;
                        Key5_LDCnt = 0;

                        Key4Dn_Flag = 0;
                        Key4LDn_Flag = 0;
                        Key4_DCnt = 0;
                        Key4_LDCnt = 0;

                        Key3Dn_Flag = 0;
                        Key3LDn_Flag = 0;
                        Key3_DCnt = 0;
                        Key3_LDCnt = 0;

                        Key2Dn_Flag = 0;
                        Key2LDn_Flag = 0;
                        Key2_DCnt = 0;
                        Key2_LDCnt = 0;

                        Key1Dn_Flag = 0;
                        Key1LDn_Flag = 0;
                        Key1_DCnt = 0;
                        Key1_LDCnt = 0;                        
                }
        }
        else
        {
                AllKeyRel_DCnt = 0;
        }
        
        //every key down, beep 1
        if( (AnyKeyDn_Flag==1) && (AnyKeyDnBuf_Flag==0) ){
                Set_BuzNum(1); }                                                                //beep 1
        
        return 1;                        
}
这段代码支持12个触摸按键的,实现的效果是短按释放响应,长按5S响应,轮询周期是10ms;这段代码有个缺点是定义了很多散乱的全局变量,可以通过结构体去整合优化,可能看起来可读性更强;
接着分享我现在工作中遇到的,如下:
void User(void)
{
   static u8 bTouchKey = 0;
   static u16 Touchtick = 0;
   KeyCode = D_KeyNull;
   if(TouchResult)                        //test
   {
      if(bTouchKey==0)
      {
         bTouchKey = 1;   

      }else if(bTouchKey==1)
      {
          Touchtick+=1;
          if(Touchtick>=300)
          {
            Touchtick=0;
            bTouchKey=2;
            
           KeyCode=D_KeyLD;            
          }
      }  
   }
   else
   {
      if(bTouchKey==1)
      {

         KeyCode=D_Key;         
      }
      bTouchKey = 0;
      Touchtick=0;
   }
}
我们介绍一下这部分代码,bTouchKey是按键状态切换标志,Touchtick是长按计时tick,也是10ms轮询一次;KeyCode保存键码,区分长按短按;TouchResult是扫到按键触摸;
短按实现思路:
bTouchKey在按键按下赋1,表示按键按下,如果没有超时3S,那么释放掉会响应保存键值;
长按实现思路:
同上如果超时3S,bTouchKey赋值3,保存键值并响应;
以上就是这次分享的长按和短按的实现,代码也没有做优化,我相信各位大佬会有很多更加优秀的代码,这里抛砖引玉,**大家一起分享学习一下。

使用特权

评论回复
沙发
caigang13| | 2023-7-6 19:20 | 只看该作者
用定时器计时器

使用特权

评论回复
板凳
Antecer| | 2023-7-7 12:28 | 只看该作者
地狱级的if判断链...

使用特权

评论回复
地板
远方的家乡| | 2023-7-21 17:14 | 只看该作者
有点烦锁。不错的代码!

使用特权

评论回复
5
zerorobert| | 2023-8-3 22:04 | 只看该作者
MultiButton不错的。              

使用特权

评论回复
6
saservice| | 2023-8-3 22:47 | 只看该作者
如何修改代码的灵敏度?              

使用特权

评论回复
7
tpgf| | 2023-8-4 11:50 | 只看该作者
这个轻触按键的话 如何区别轻重呢

使用特权

评论回复
8
nawu| | 2023-8-4 12:14 | 只看该作者
硬件上需要连接压力传感器吗?

使用特权

评论回复
9
abotomson| | 2023-8-4 12:57 | 只看该作者
这个按键需要有什么要求呢              

使用特权

评论回复
10
hearstnorman323| | 2023-8-4 13:28 | 只看该作者
这个需要定时器判断的嘛              

使用特权

评论回复
11
linfelix| | 2023-8-4 13:38 | 只看该作者
可以实现连击的判断吗              

使用特权

评论回复
12
aoyi| | 2023-8-4 13:49 | 只看该作者
这种轻触的情况如何排除这种水流击打呢

使用特权

评论回复
13
zljiu| | 2023-8-4 14:40 | 只看该作者
if语句的分支着实有些多了啊

使用特权

评论回复
14
gwsan| | 2023-8-4 16:11 | 只看该作者
需要判断的内容和条件太多了 很容易就出现重复的地方

使用特权

评论回复
15
tfqi| | 2023-8-4 16:16 | 只看该作者
这个长按和短按必定是认为规定的

使用特权

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

本版积分规则

54

主题

162

帖子

7

粉丝