本帖最后由 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,保存键值并响应; 以上就是这次分享的长按和短按的实现,代码也没有做优化,我相信各位大佬会有很多更加优秀的代码,这里抛砖引玉,**大家一起分享学习一下。
|