[单片机芯片] 触摸/轻触按键的长按和短按实现

[复制链接]
3807|15
 楼主| lilijin1995 发表于 2023-7-6 10:23 | 显示全部楼层 |阅读模式
本帖最后由 lilijin1995 于 2023-7-6 10:24 编辑

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

  12.         //Power delay 500ms, wait TK stable!
  13.         if( TKScan_PowerDelay <= 50 )
  14.         {        
  15.                 return 0;
  16.         }
  17.         
  18.         //clr keycode  
  19.         KeyCode = D_KeyNull;
  20.         
  21.         //backup "AnyKeyDn_Flag" statue
  22.         if( AnyKeyDn_Flag ){
  23.                 AnyKeyDnBuf_Flag = 1;}
  24.         else{
  25.                 AnyKeyDnBuf_Flag = 0;}
  26.         
  27.         //read key value
  28.         TKStatue_L = ctm_APT8L16_RdByte( R_K0_VR );                                //read key value        
  29.         TKStatue_H = ctm_APT8L16_RdByte( R_K1_VR );                                //read key value        
  30.         TKStatue = (((UINT16)TKStatue_H)<<8) + TKStatue_L;

  31.         //key12 down
  32.         if( AnyKeyDn_Flag == 0 )
  33.         {
  34.                 //debonce
  35.                 if( (TKStatue & D_TK13) )
  36.                 {
  37.                         Key12_DCnt += 1;        
  38.                 }
  39.                 else
  40.                 {
  41.                         Key12_DCnt = 0;
  42.                 }
  43.                 //down
  44.                 if( Key12_DCnt >= D_KeyDCnt )
  45.                 {
  46.                         Key12_DCnt = 0;
  47.                         Key12Dn_Flag = 1;
  48.                         AnyKeyDn_Flag = 1;
  49.                 }
  50.         }

  51.         //key11 down
  52.         if( AnyKeyDn_Flag == 0 )
  53.         {
  54.                 //debonce
  55.                 if( (TKStatue & D_TK12) )
  56.                 {
  57.                         Key11_DCnt += 1;        
  58.                 }
  59.                 else
  60.                 {
  61.                         Key11_DCnt = 0;
  62.                 }
  63.                 //down
  64.                 if( Key11_DCnt >= D_KeyDCnt )
  65.                 {
  66.                         Key11_DCnt = 0;
  67.                         Key11Dn_Flag = 1;
  68.                         AnyKeyDn_Flag = 1;
  69.                 }
  70.         }

  71.         //key10 down
  72.         if( AnyKeyDn_Flag == 0 )
  73.         {
  74.                 //debonce
  75.                 if( (TKStatue & D_TK11) )
  76.                 {
  77.                         Key10_DCnt += 1;        
  78.                 }
  79.                 else
  80.                 {
  81.                         Key10_DCnt = 0;
  82.                 }
  83.                 //down
  84.                 if( Key10_DCnt >= D_KeyDCnt )
  85.                 {
  86.                         Key10_DCnt = 0;
  87.                         Key10Dn_Flag = 1;
  88.                         AnyKeyDn_Flag = 1;
  89.                 }
  90.         }

  91.         //key9 down
  92.         if( AnyKeyDn_Flag == 0 )
  93.         {
  94.                 //debonce
  95.                 if( (TKStatue & D_TK10) )
  96.                 {
  97.                         Key9_DCnt += 1;        
  98.                 }
  99.                 else
  100.                 {
  101.                         Key9_DCnt = 0;
  102.                 }
  103.                 //down
  104.                 if( Key9_DCnt >= D_KeyDCnt )
  105.                 {
  106.                         Key9_DCnt = 0;
  107.                         Key9Dn_Flag = 1;
  108.                         AnyKeyDn_Flag = 1;
  109.                 }
  110.         }
  111.         
  112.         //key8 down
  113.         if( AnyKeyDn_Flag == 0 )
  114.         {
  115.                 //debonce
  116.                 if( (TKStatue & D_TK07) )
  117.                 {
  118.                         Key8_DCnt += 1;        
  119.                 }
  120.                 else
  121.                 {
  122.                         Key8_DCnt = 0;
  123.                 }
  124.                 //down
  125.                 if( Key8_DCnt >= D_KeyDCnt )
  126.                 {
  127.                         Key8_DCnt = 0;
  128.                         Key8Dn_Flag = 1;
  129.                         AnyKeyDn_Flag = 1;
  130.                 }
  131.         }

  132.         //key7 down
  133.         if( AnyKeyDn_Flag == 0 )
  134.         {
  135.                 //debonce
  136.                 if( (TKStatue & D_TK06) )
  137.                 {
  138.                         Key7_DCnt += 1;        
  139.                 }
  140.                 else
  141.                 {
  142.                         Key7_DCnt = 0;
  143.                 }
  144.                 //down
  145.                 if( Key7_DCnt >= D_KeyDCnt )
  146.                 {
  147.                         Key7_DCnt = 0;
  148.                         Key7Dn_Flag = 1;
  149.                         AnyKeyDn_Flag = 1;
  150.                 }
  151.         }

  152.         //key6 down
  153.         if( AnyKeyDn_Flag == 0 )
  154.         {
  155.                 //debonce
  156.                 if( (TKStatue & D_TK05) )
  157.                 {
  158.                         Key6_DCnt += 1;        
  159.                 }
  160.                 else
  161.                 {
  162.                         Key6_DCnt = 0;
  163.                 }
  164.                 //down
  165.                 if( Key6_DCnt >= D_KeyDCnt )
  166.                 {
  167.                         Key6_DCnt = 0;
  168.                         Key6Dn_Flag = 1;
  169.                         AnyKeyDn_Flag = 1;
  170.                 }
  171.         }

  172.         //key5 down
  173.         if( AnyKeyDn_Flag == 0 )
  174.         {
  175.                 //debonce
  176.                 if( (TKStatue & D_TK04) )
  177.                 {
  178.                         Key5_DCnt += 1;        
  179.                 }
  180.                 else
  181.                 {
  182.                         Key5_DCnt = 0;
  183.                 }
  184.                 //down
  185.                 if( Key5_DCnt >= D_KeyDCnt )
  186.                 {
  187.                         Key5_DCnt = 0;
  188.                         Key5Dn_Flag = 1;
  189.                         AnyKeyDn_Flag = 1;
  190.                 }
  191.         }

  192.         //key4 down
  193.         if( AnyKeyDn_Flag == 0 )
  194.         {
  195.                 //debonce
  196.                 if( (TKStatue & D_TK03) )
  197.                 {
  198.                         Key4_DCnt += 1;        
  199.                 }
  200.                 else
  201.                 {
  202.                         Key4_DCnt = 0;
  203.                 }
  204.                 //down
  205.                 if( Key4_DCnt >= D_KeyDCnt )
  206.                 {
  207.                         Key4_DCnt = 0;
  208.                         Key4Dn_Flag = 1;
  209.                         AnyKeyDn_Flag = 1;
  210.                 }
  211.         }
  212.         
  213.         //key3 down
  214.         if( AnyKeyDn_Flag == 0 )
  215.         {
  216.                 //debonce
  217.                 if( (TKStatue & D_TK02) )
  218.                 {
  219.                         Key3_DCnt += 1;        
  220.                 }
  221.                 else
  222.                 {
  223.                         Key3_DCnt = 0;
  224.                 }
  225.                 //down
  226.                 if( Key3_DCnt >= D_KeyDCnt )
  227.                 {
  228.                         Key3_DCnt = 0;
  229.                         Key3Dn_Flag = 1;
  230.                         AnyKeyDn_Flag = 1;
  231.                 }
  232.         }

  233.         //key2 down
  234.         if( AnyKeyDn_Flag == 0 )
  235.         {
  236.                 //debonce
  237.                 if( (TKStatue & D_TK01) )
  238.                 {
  239.                         Key2_DCnt += 1;        
  240.                 }
  241.                 else
  242.                 {
  243.                         Key2_DCnt = 0;
  244.                 }
  245.                 //down
  246.                 if( Key2_DCnt >= D_KeyDCnt )
  247.                 {
  248.                         Key2_DCnt = 0;
  249.                         Key2Dn_Flag = 1;
  250.                         AnyKeyDn_Flag = 1;
  251.                 }
  252.         }        
  253.         
  254.         //key1 down
  255.         if( AnyKeyDn_Flag == 0 )
  256.         {
  257.                 //debonce
  258.                 if( (TKStatue & D_TK00) )
  259.                 {
  260.                         Key1_DCnt += 1;        
  261.                 }
  262.                 else
  263.                 {
  264.                         Key1_DCnt = 0;
  265.                 }
  266.                 //down
  267.                 if( Key1_DCnt >= D_KeyDCnt )
  268.                 {
  269.                         Key1_DCnt = 0;
  270.                         Key1Dn_Flag = 1;
  271.                         AnyKeyDn_Flag = 1;
  272.                 }
  273.         }        


  274.         //key12 long down               
  275.         if( Key12Dn_Flag && (Key12LDn_Flag==0) )
  276.         {
  277.                 Key12_LDCnt += 1;
  278.                 if( Key12_LDCnt >= 500 )                                //500*10ms=5s
  279.                 {
  280.                         Key12_LDCnt = 0;
  281.                         Key12LDn_Flag = 1;
  282.                         KeyCode = D_KeyAuto02LD;
  283.                 }
  284.         }
  285.         else
  286.         {
  287.                 Key12_LDCnt = 0;        
  288.         }

  289.         //key11 long down               
  290.         if( Key11Dn_Flag && (Key11LDn_Flag==0) )
  291.         {
  292.                 Key11_LDCnt += 1;
  293.                 if( Key11_LDCnt >= 500 )                                //500*10ms=5s
  294.                 {
  295.                         Key11_LDCnt = 0;
  296.                         Key11LDn_Flag = 1;
  297.                         KeyCode = D_KeyAuto01LD;
  298.                 }
  299.         }
  300.         else
  301.         {
  302.                 Key11_LDCnt = 0;        
  303.         }

  304.         //key10 long down               
  305.         if( Key10Dn_Flag && (Key10LDn_Flag==0) )
  306.         {
  307.                 Key10_LDCnt += 1;
  308.                 if( Key10_LDCnt >= 500 )                                //500*10ms=5s
  309.                 {
  310.                         Key10_LDCnt = 0;
  311.                         Key10LDn_Flag = 1;
  312.                         KeyCode = D_KeyPowerLD;
  313.                 }
  314.         }
  315.         else
  316.         {
  317.                 Key10_LDCnt = 0;        
  318.         }

  319.         //key9 long down               
  320.         if( Key9Dn_Flag && (Key9LDn_Flag==0) )
  321.         {
  322.                 Key9_LDCnt += 1;
  323.                 if( Key9_LDCnt >= 500 )                                //500*10ms=5s
  324.                 {
  325.                         Key9_LDCnt = 0;
  326.                         Key9LDn_Flag = 1;
  327.                         KeyCode = D_KeyAmountLD;
  328.                 }
  329.         }
  330.         else
  331.         {
  332.                 Key9_LDCnt = 0;        
  333.         }
  334.         
  335.         //key8 long down               
  336.         if( Key8Dn_Flag && (Key8LDn_Flag==0) )
  337.         {
  338.                 Key8_LDCnt += 1;
  339.                 if( Key8_LDCnt >= 500 )                                //500*10ms=5s                        
  340.                 {
  341.                         Key8_LDCnt = 0;
  342.                         Key8LDn_Flag = 1;
  343.                         KeyCode = D_KeyTimerLD;
  344.                 }
  345.         }
  346.         else
  347.         {
  348.                 Key8_LDCnt = 0;        
  349.         }
  350.         
  351.         //key7 long down               
  352.         if( Key7Dn_Flag && (Key7LDn_Flag==0) )
  353.         {
  354.                 Key7_LDCnt += 1;
  355.                 if( Key7_LDCnt >= 500 )                                //500*10ms = 5s
  356.                 {
  357.                         Key7_LDCnt = 0;
  358.                         Key7LDn_Flag = 1;
  359.                         KeyCode = D_KeyUpLD;
  360.                 }
  361.         }
  362.         else
  363.         {
  364.                 Key7_LDCnt = 0;        
  365.         }
  366.         
  367.         //Key6 long down               
  368.         if( Key6Dn_Flag && (Key6LDn_Flag==0) )
  369.         {
  370.                 Key6_LDCnt += 1;
  371.                 if( Key6_LDCnt >= 500 )                                        //500*10ms = 5s
  372.                 {
  373.                         Key6_LDCnt = 0;
  374.                         Key6LDn_Flag = 1;
  375.                         KeyCode = D_KeyDownLD;
  376.                 }
  377.         }
  378.         else
  379.         {
  380.                 Key6_LDCnt = 0;        
  381.         }
  382.         
  383.         //key5 long down               
  384.         if( Key5Dn_Flag && (Key5LDn_Flag==0) )
  385.         {
  386.                 Key5_LDCnt += 1;
  387.                 if( Key5_LDCnt >= 500 )                                //500*10ms=5s
  388.                 {
  389.                         Key5_LDCnt = 0;
  390.                         Key5LDn_Flag = 1;
  391.                         KeyCode = D_KeyVersionLD;
  392.                 }
  393.         }
  394.         else
  395.         {
  396.                 Key5_LDCnt = 0;        
  397.         }
  398.         
  399.         //key4 long down               
  400.         if( Key4Dn_Flag && (Key4LDn_Flag==0) )
  401.         {
  402.                 Key4_LDCnt += 1;
  403.                 if( Key4_LDCnt >= 500 )                                //500*10ms=5s
  404.                 {
  405.                         Key4_LDCnt = 0;
  406.                         Key4LDn_Flag = 1;
  407.                         KeyCode = D_KeyWaterLD;
  408.                 }
  409.         }
  410.         else
  411.         {
  412.                 Key4_LDCnt = 0;        
  413.         }
  414.         
  415.         //key3 long down               
  416.         if( Key3Dn_Flag && (Key3LDn_Flag==0) )
  417.         {
  418.                 Key3_LDCnt += 1;
  419.                 if( Key3_LDCnt >= 500 )                                //500*10ms=5s
  420.                 {
  421.                         Key3_LDCnt = 0;
  422.                         Key3LDn_Flag = 1;
  423.                         KeyCode = D_KeyCleanLD;
  424.                 }
  425.         }
  426.         else
  427.         {
  428.                 Key3_LDCnt = 0;        
  429.         }
  430.         
  431.         //key2 long down               
  432.         if( Key2Dn_Flag && (Key2LDn_Flag==0) )
  433.         {
  434.                 Key2_LDCnt += 1;
  435.                 if( Key2_LDCnt >= 500 )                                //500*10ms=5s
  436.                 {
  437.                         Key2_LDCnt = 0;
  438.                         Key2LDn_Flag = 1;
  439.                         KeyCode = D_KeyHandLD;
  440.                 }
  441.         }
  442.         else
  443.         {
  444.                 Key2_LDCnt = 0;        
  445.         }
  446.         
  447.         //key1 long down               
  448.         if( Key1Dn_Flag && (Key1LDn_Flag==0) )
  449.         {
  450.                 Key1_LDCnt += 1;
  451.                 if( Key1_LDCnt >= 500 )                                //500*10ms=5s
  452.                 {
  453.                         Key1_LDCnt = 0;
  454.                         Key1LDn_Flag = 1;
  455.                         KeyCode = D_KeyContinueLD;
  456.                 }
  457.         }
  458.         else
  459.         {
  460.                 Key1_LDCnt = 0;        
  461.         }

  462.         //all key release
  463.         if( AnyKeyDn_Flag && (TKStatue==0) )
  464.         {
  465.                 AllKeyRel_DCnt += 1;
  466.                 if( AllKeyRel_DCnt >= 3 )
  467.                 {
  468.                         //释放响应
  469.                         if( Key12Dn_Flag && (Key12LDn_Flag==0) ){        
  470.                                 KeyCode = D_KeyAuto02;        }
  471.                         if( Key11Dn_Flag && (Key11LDn_Flag==0) ){        
  472.                                 KeyCode = D_KeyAuto01;        }
  473.                         if( Key10Dn_Flag && (Key10LDn_Flag==0) ){        
  474.                                 KeyCode = D_KeyPower;        }
  475.                         if( Key9Dn_Flag && (Key9LDn_Flag==0) ){        
  476.                                 KeyCode = D_KeyAmount;        }
  477.                         if( Key8Dn_Flag && (Key8LDn_Flag==0) ){               
  478.                                 KeyCode = D_KeyTimer;                }
  479.                         if( Key7Dn_Flag && (Key7LDn_Flag==0) ){        
  480.                                 KeyCode = D_KeyUp;        }
  481.                         if( Key6Dn_Flag && (Key6LDn_Flag==0) ){        
  482.                                 KeyCode = D_KeyDown; }
  483.                         if( Key5Dn_Flag && (Key5LDn_Flag==0) ){        
  484.                                 KeyCode = D_KeyVersion;        }
  485.                         if( Key4Dn_Flag && (Key4LDn_Flag==0) ){        
  486.                                 KeyCode = D_KeyWater;        }
  487.                         if( Key3Dn_Flag && (Key3LDn_Flag==0) ){        
  488.                                 KeyCode = D_KeyClean;}
  489.                         if( Key2Dn_Flag && (Key2LDn_Flag==0) ){        
  490.                                 KeyCode = D_KeyHand;        }
  491.                         if( Key1Dn_Flag && (Key1LDn_Flag==0) ){        
  492.                                 KeyCode = D_KeyContinue;        }
  493.                         
  494.                         //clr ram
  495.                         AnyKeyDn_Flag = 0;
  496.                         AllKeyRel_DCnt = 0;
  497.                         
  498.                         Key12Dn_Flag = 0;
  499.                         Key12LDn_Flag = 0;
  500.                         Key12_DCnt = 0;
  501.                         Key12_LDCnt = 0;

  502.                         Key11Dn_Flag = 0;
  503.                         Key11LDn_Flag = 0;
  504.                         Key11_DCnt = 0;
  505.                         Key11_LDCnt = 0;
  506.                         
  507.                         Key10Dn_Flag = 0;
  508.                         Key10LDn_Flag = 0;
  509.                         Key10_DCnt = 0;
  510.                         Key10_LDCnt = 0;

  511.                         Key9Dn_Flag = 0;
  512.                         Key9LDn_Flag = 0;
  513.                         Key9_DCnt = 0;
  514.                         Key9_LDCnt = 0;

  515.                         Key8Dn_Flag = 0;
  516.                         Key8LDn_Flag = 0;
  517.                         Key8_DCnt = 0;
  518.                         Key8_LDCnt = 0;
  519.                         
  520.                         Key7Dn_Flag = 0;
  521.                         Key7LDn_Flag = 0;
  522.                         Key7_DCnt = 0;
  523.                         Key7_LDCnt = 0;

  524.                         Key6Dn_Flag = 0;
  525.                         Key6LDn_Flag = 0;
  526.                         Key6_DCnt = 0;
  527.                         Key6_LDCnt = 0;

  528.                         Key5Dn_Flag = 0;
  529.                         Key5LDn_Flag = 0;
  530.                         Key5_DCnt = 0;
  531.                         Key5_LDCnt = 0;

  532.                         Key4Dn_Flag = 0;
  533.                         Key4LDn_Flag = 0;
  534.                         Key4_DCnt = 0;
  535.                         Key4_LDCnt = 0;

  536.                         Key3Dn_Flag = 0;
  537.                         Key3LDn_Flag = 0;
  538.                         Key3_DCnt = 0;
  539.                         Key3_LDCnt = 0;

  540.                         Key2Dn_Flag = 0;
  541.                         Key2LDn_Flag = 0;
  542.                         Key2_DCnt = 0;
  543.                         Key2_LDCnt = 0;

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

  11.       }else if(bTouchKey==1)
  12.       {
  13.           Touchtick+=1;
  14.           if(Touchtick>=300)
  15.           {
  16.             Touchtick=0;
  17.             bTouchKey=2;
  18.             
  19.            KeyCode=D_KeyLD;            
  20.           }
  21.       }  
  22.    }
  23.    else
  24.    {
  25.       if(bTouchKey==1)
  26.       {

  27.          KeyCode=D_Key;         
  28.       }
  29.       bTouchKey = 0;
  30.       Touchtick=0;
  31.    }
  32. }
我们介绍一下这部分代码,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 | 显示全部楼层
有点烦锁。不错的代码!
zerorobert 发表于 2023-8-3 22:04 | 显示全部楼层
MultiButton不错的。              
saservice 发表于 2023-8-3 22:47 | 显示全部楼层
如何修改代码的灵敏度?              
tpgf 发表于 2023-8-4 11:50 | 显示全部楼层
这个轻触按键的话 如何区别轻重呢
nawu 发表于 2023-8-4 12:14 | 显示全部楼层
硬件上需要连接压力传感器吗?
abotomson 发表于 2023-8-4 12:57 | 显示全部楼层
这个按键需要有什么要求呢              
hearstnorman323 发表于 2023-8-4 13:28 | 显示全部楼层
这个需要定时器判断的嘛              
linfelix 发表于 2023-8-4 13:38 | 显示全部楼层
可以实现连击的判断吗              
aoyi 发表于 2023-8-4 13:49 | 显示全部楼层
这种轻触的情况如何排除这种水流击打呢
zljiu 发表于 2023-8-4 14:40 | 显示全部楼层
if语句的分支着实有些多了啊
gwsan 发表于 2023-8-4 16:11 | 显示全部楼层
需要判断的内容和条件太多了 很容易就出现重复的地方
tfqi 发表于 2023-8-4 16:16 | 显示全部楼层
这个长按和短按必定是认为规定的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

56

主题

165

帖子

8

粉丝
快速回复 在线客服 返回列表 返回顶部