1 Star 0 Fork 9

TICKBUG/XxxSwitchScan_Driver

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
XxxSwitchScan_Driver.c 25.35 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
/**
* @brief 开关设备驱动
* @file XxxSwitchScan_Driver.c
* @author 何锡斌
* @email 2537274979@qq.com
* @date 2024/01/19
* @version V1_0_0
* @par 实现功能:
* - 支持多开关设备(按键等)的短按/短按抬起/长按/持续长按/长按抬起/连击/单边沿触发 事件响应;
* - 支持每个设备的按下消抖与抬起消抖的独立配置;
* - 支持每个设备的每个事件响应的独立开启与关闭;
* @par 注意事项:
* - 首次触发的连击事件即为双击,此时`XxxSwitchDevice_ReadComboHitNum()`函数读取到的连击次数返回即为2;
* - 连击一旦没续上则连击次数会被清零,所以在触发连击事件时按需求是否利用或保存连击次数;
* - 边沿模式仅能单边沿触发;
* - 在操作系统中使用时,如果其中一个设备使用到的IPC是阻塞方式,会导致其他设备的扫描被阻塞;
* - tick是由调用者外部决定的,以1~20ms为一次tick均可。tick越小,功耗与cpu占用越高;
* - 消抖时长(计数数值*tick),一般为10~50ms,由实际抖动程度决定;
* @par 修改日志:
* <table>
* <tr><th>日期 <th>版本 <th>作者 <th>更新内容 </tr>
* <tr><td>2024/01/19 <td>V1_0_0 <td>何锡斌 <td>初版发布; </tr>
* </table>
*/
#include "XxxSwitchScan_Driver.h"
#ifndef NULL
#define NULL (void*)0
#endif
/**开关检测步骤*/
typedef enum{
SwitchCheckStep_Wait2Trigger = 0, /**< 等待触发 */
SwitchCheckStep_Wait, /**< 消抖 */
SwitchCheckStep_Wait2Long, /**< 等待长按 */
SwitchCheckStep_Wait2Continue, /**< 等待持续长按 */
SwitchCheckStep_Wait2Up, /**< 等待抬起 */
#if CFG_XXXSWITCH_COMBOHIT
SwitchCheckStep_Wait2ComboHit, /**< 等待连击 */
SwitchCheckStep_ComboHitWait, /**< 连击消抖 */
SwitchCheckStep_Wait2ComboHitUp, /**< 等待连击抬起 */
#endif
#if (CFG_XXXSWITCH_COMBOHIT || CFG_XXXSWITCH_EDGETRIGGER)
SwitchCheckStep_WaitNotTrigge, /**< 等待复位 */
#endif
}enum_XxxSwitchCheckStep;
/**开关设备类*/
struct _STR_XxxSwitchDevice{
enum_XxxSwitchCheckStep step; /**< 检测步骤 */
unsigned char trigger; /**< 有效触发条件 */
enum_XxxSwitchDeviceType type; /**< 类型 */
unsigned short triggerCount; /**< 触发计数器 */
unsigned short upCount; /**< 抬起计数器 */
unsigned short triggerWaitVal; /**< 触发消抖计数值 */
unsigned short upWaitVal; /**< 抬起消抖计数值 */
unsigned short longVal; /**< 长按计数值 */
unsigned short continueVal; /**< 持续长按间隔计数值 */
#if CFG_XXXSWITCH_COMBOHIT
unsigned short comboHitInterval; /**< 连击间最大间隔 */
unsigned short comboHitNum; /**< 连击次数 */
#endif
unsigned char (*readInputStateFunc)(void); /**< 读取输入状态函数函数指针 */
void (*handleFunc)(enum_XxxSwitchCheckState state); /**< 处理函数函数指针 */
STR_XxxSwitchDevice* pNext; /**< 指向下一个设备 */
};
static STR_XxxSwitchDevice* s_pKeyList = NULL; /**< 开关设备链表入口(仅入口,最终直接指向设备实体,所需无需申请空间。链表是单向线性链表) */
/*检测*/
static void XxxSwitchDevice_Check(STR_XxxSwitchDevice* pKey);
/**
* @brief 获取开关设备类的大小(用于申请内存)
* @param null
* @return 开关设备类的大小
* @par 注意事项:
* - null
* @par 示例:
* @code
*
* STR_XxxSwitchDevice* m_pKey;
* m_pKey = (STR_XxxSwitchDevice*)malloc(XxxSwitchDevice_GetSize());
*
* @endcode
*/
unsigned char XxxSwitchDevice_GetSize(void)
{
return sizeof(STR_XxxSwitchDevice);
}
/**
* @brief 注册(自定义)
* @param[in] pKey 设备对象指针
* @param[in] type 设备类型
* @param[in] trigger 有效状态
* @param[in] triggerWaitVal 按下消抖tick次数,允许为零即不按下消抖
* @param[in] upWaitVal 抬起消抖tick次数,允许为零即不抬起消抖
* @param[in] longVal 长按响应tick次数,允许为零即关闭长按/长按抬起/持续长按事件
* @param[in] continueVal 持续长按响应tick次数,允许为零即关闭持续长按事件
* @param[in] comboHitInterval 连击响应允许的间隔tick次数,允许为零即关闭连击事件
* @param[in] readInputStateFunc 读取设备状态的函数的函数指针
* @param[in] handleFunc 应用层的事件处理函数的函数指针
* @return 注册是否成功
* - 0 注册成功
* - 1 配置完成,但设备已存在,无需加入链表
* - -1 pKey为空指针,无效设备
* @par 注意事项:
* - 当longVal设置为零时,关闭长按/长按抬起事件响应,同时伴随关闭持续长按事件响应,即导致continueVal设置值无效;
* @par 示例:
* @code
*
* XxxSwitchDevice_Register(m_pKey_1, SwitchDeviceType_Common, 1, \
* 2, 2, \
* 25, 25, \
* 0, \
* ReadKEY1, \
* (void (*)(enum_XxxSwitchCheckState state))Key1Handle);
*
* @endcode
*/
int XxxSwitchDevice_Register(STR_XxxSwitchDevice* pKey, enum_XxxSwitchDeviceType type, unsigned char trigger, \
unsigned short triggerWaitVal, unsigned short upWaitVal, \
unsigned short longVal, unsigned short continueVal, \
unsigned short comboHitInterval, \
unsigned char (*readInputStateFunc)(void), \
void (*handleFunc)(enum_XxxSwitchCheckState state) \
)
{
if(NULL == pKey)return -1; /* 返回错误:无效设备 */
/*初始化*/
pKey->step = SwitchCheckStep_Wait2Trigger; /* 默认步骤为等待触发 */
if(0 == trigger) /* 防止调用者乱填,保证trigger只能0/1 */
{
pKey->trigger = 0;
}
else
{
pKey->trigger = 1;
}
pKey->type = type;
pKey->triggerCount = 0; /* 默认触发计数器清零 */
pKey->upCount = 0; /* 默认抬起计数器清零 */
pKey->triggerWaitVal = triggerWaitVal;
pKey->upWaitVal = upWaitVal;
pKey->longVal = longVal;
if(0 == pKey->longVal) /* 如果长按功能关闭 */
{
pKey->continueVal = 0; /* 伴随持续长按也关闭 */
}
else
{
pKey->continueVal = continueVal;
}
#if CFG_XXXSWITCH_COMBOHIT
pKey->comboHitInterval = comboHitInterval;
pKey->comboHitNum = 0; /* 默认连击次数清零 */
#endif
#if CFG_XXXSWITCH_EDGETRIGGER
if(SwitchDeviceType_EdgeTrigger == type)
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_WaitNotTrigge; /* 如果是边沿触发类型默认步骤为等待复位 */
}
#endif
pKey->readInputStateFunc = readInputStateFunc;
pKey->handleFunc = handleFunc;
/*遍历链表,防止添加重复*/
for(STR_XxxSwitchDevice* pTemp = s_pKeyList; pTemp != NULL; pTemp = pTemp->pNext)
{
if(pTemp == pKey)
{
return 1; /* 返回成功:配置完成,但设备已存在,无需加入链表 */
}
}
/*加入链表*/
pKey->pNext = s_pKeyList;
s_pKeyList = pKey; /* 把设备加入到链表头部 */
return 0; /* 返回成功:注册成功 */
}
/**
* @brief 配置长按事件(若关闭,则伴随关闭持续长按与长按抬起事件)
* @param[in] pKey 设备对象指针
* @param[in] longVal 长按响应tick次数,允许为零即关闭长按/长按抬起/持续长按事件
* @return 配置是否成功
* - 0 配置成功
* - -1 pKey为空指针,无效设备
* @par 注意事项:
* - null
* @par 示例:
* @code
*
* XxxSwitchDevice_CfgEvent_Long(m_pKey_1, 0); //关闭长按/长按抬起/持续长按事件的响应
* XxxSwitchDevice_CfgEvent_Long(m_pKey_1, 25); //开启长按/长按抬起事件的响应,如果continueVal有效则也开启持续长按事件的响应
*
* @endcode
*/
int XxxSwitchDevice_CfgEvent_Long(STR_XxxSwitchDevice* pKey, unsigned short longVal)
{
if(NULL == pKey)return -1; /* 返回错误:无效设备 */
pKey->longVal = longVal; /* 零值为关闭,非零为开启 */
return 0; /* 返回成功:配置成功 */
}
/**
* @brief 配置持续长按事件
* @param[in] pKey 设备对象指针
* @param[in] continueVal 持续长按响应tick次数,允许为零即关闭持续长按事件
* @return 配置是否成功
* - 0 配置成功
* - -1 pKey为空指针,无效设备
* @par 注意事项:
* - null
* @par 示例:
* @code
*
* XxxSwitchDevice_CfgEvent_Continue(m_pKey_1, 0); //关闭持续长按事件的响应
* XxxSwitchDevice_CfgEvent_Continue(m_pKey_1, 25); //开启持续长按事件的响应
*
* @endcode
*/
int XxxSwitchDevice_CfgEvent_Continue(STR_XxxSwitchDevice* pKey, unsigned short continueVal)
{
if(NULL == pKey)return -1; /* 返回错误:无效设备 */
pKey->continueVal = continueVal; /* 零值为关闭,非零为开启 */
return 0; /* 返回成功:配置成功 */
}
#if CFG_XXXSWITCH_COMBOHIT
/**
* @brief 配置连击事件
* @param[in] pKey 设备对象指针
* @param[in] comboHitInterval 连击允许间隔tick次数,允许为零即关闭连击事件
* @return 配置是否成功
* - 0 配置成功
* - -1 pKey为空指针,无效设备
* @par 注意事项:
* - null
* @par 示例:
* @code
*
* XxxSwitchDevice_CfgEvent_ComboHit(m_pKey_1, 0); //关闭连击事件的响应
* XxxSwitchDevice_CfgEvent_ComboHit(m_pKey_1, 25); //开启连击事件的响应
*
* @endcode
*/
int XxxSwitchDevice_CfgEvent_ComboHit(STR_XxxSwitchDevice* pKey, unsigned short comboHitInterval)
{
if(NULL == pKey)return -1; /* 返回错误:无效设备 */
pKey->comboHitInterval = comboHitInterval; /* 零值为关闭,非零为开启 */
return 0; /* 返回成功:配置成功 */
}
#endif
/**
* @brief 注销(由调用者自己回收内存)
* @param[in] pKey 设备对象指针
* @return 注销是否成功
* - 0 注销成功
* - -1 pKey为空指针,无效设备
* - -2 链表为空
* - -3 查无该设备(设备未注册)
* @par 注意事项:
* - null
*/
int XxxSwitchDevice_Delete(STR_XxxSwitchDevice* pKey)
{
if(NULL == pKey)return -1; /* 返回错误:无效设备 */
if(NULL == s_pKeyList)return -2; /* 返回错误:链表为空 */
if(s_pKeyList == pKey) /* 如果pKey是位于链表头的设备 */
{
s_pKeyList = pKey->pNext; /* 链表入口指向下个设备 */
pKey->pNext = NULL; /* 防止被删除的设备还能入侵链表 */
return 0; /* 返回成功:注销成功 */
}
/*遍历链表,找到对应开关设备并删除*/
for(STR_XxxSwitchDevice* pTemp = s_pKeyList; pTemp->pNext != NULL; pTemp = pTemp->pNext)
{
if(pTemp->pNext == pKey) /* 找到设备 */
{
pTemp->pNext = pTemp->pNext->pNext; /* 链表间的链接越过设备,即删除 */
pKey->pNext = NULL; /* 防止被删除的设备还能入侵链表 */
return 0; /* 返回成功:注销成功 */
}
}
return -3; /* 返回错误:查无该设备(设备未注册) */
}
/**
* @brief 扫描
* @param null
* @return null
* @par 注意事项:
* - 注意外部tick基准是多少;
*/
void XxxSwitchDevice_Scan(void)
{
/*遍历链表,扫描执行所有开关设备的检测*/
for(STR_XxxSwitchDevice* pTemp = s_pKeyList; pTemp != NULL; pTemp = pTemp->pNext)
{
XxxSwitchDevice_Check(pTemp);
}
}
/**
* @brief 是否触发
* @param[in] pKey 设备对象指针
* @return 设备当前是否在被触发的状态(如按键当前是否被按住)
* - 0 非触发状态(如按键当前没被按住)
* - 1 触发状态(如按键当前被按住)
* @par 介绍:
* - 属于高级应用,用于开关设备间的联动。如:当一个按键的某事件触发时,需要先判断另一个按键是否触发,再判断自己是否执行某事件
*/
unsigned char XxxSwitchDevice_IsTrigger(STR_XxxSwitchDevice* pKey)
{
if(pKey->step > SwitchCheckStep_Wait) /* 根据枚举的值大小,大于即为触发 */
{
return 1; /* 处于触发状态(按键按下/限位触发/传感器生效等) */
}
return 0; /* 非触发状态 */
}
/**
* @brief 复位
* @param[in] pKey 设备对象指针
* @return null
* @par 介绍:
* - 属于高级应用,用于开关设备间的互斥。如:当按键按下,在抬起前被"复位"则会无法触发后续的事件(短按抬起/长按/持续长按/长按抬起/连击等)。
*/
void XxxSwitchDevice_Reset(STR_XxxSwitchDevice* pKey)
{
#if CFG_XXXSWITCH_EDGETRIGGER
if(SwitchDeviceType_EdgeTrigger == type) /* 边沿触发类型 */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_WaitNotTrigge; /* 状态切换:等待复位 */
return;
}
#endif
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
#if CFG_XXXSWITCH_COMBOHIT
/**
* @brief 读取连击次数
* @param[in] pKey 设备对象指针
* @return 当前连击次数
* @par 注意事项:
* - 首次连击事件即为双击事件;
* - 仅在连击生效期间有效,连击被断则清零。即应在连击事件触发应用层事件处理函数时及时使用或另外保存;
*/
unsigned short XxxSwitchDevice_ReadComboHitNum(STR_XxxSwitchDevice* pKey)
{
if(pKey->comboHitNum < 2)return 0;
return pKey->comboHitNum;
}
#endif
/**
* @brief 检测
* @param[in] pKey 设备对象指针
* @return null
* @par 介绍:
* - 设备判断自身状态的核心代码,有兴趣的小伙伴可以看看。
* - 原本逻辑挺简单的,但加入支持无消抖/事件响应可开关/连击/边沿触发/等特性后就变复杂了。有能力的小伙伴可自行慎重裁剪
*/
static void XxxSwitchDevice_Check(STR_XxxSwitchDevice* pKey)
{
switch(pKey->step)
{
case SwitchCheckStep_Wait2Trigger:/*等待触发*/
if(pKey->readInputStateFunc() == pKey->trigger) /* 设备触发条件满足 */
{
if(0 == pKey->triggerWaitVal) /* 无需消抖 */
{
#if CFG_XXXSWITCH_EDGETRIGGER
if(SwitchDeviceType_EdgeTrigger == pKey->type) /* 边沿触发类型 */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_WaitNotTrigge; /* 状态切换:等待复位 */
pKey->handleFunc(SwitchCheckState_EdgeTrigger); /* 执行函数(边沿触发) */
break;
}
#endif
if(0 == pKey->longVal) /* 长按计数为0,即关闭长按检测功能(伴随关闭持续长按与长按抬起功能) */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_Wait2Up; /* 状态切换:等待抬起 */
}
else /* 开启长按检测功能 */
{
pKey->triggerCount = pKey->longVal; /* 触发计数器赋值长按计数 */
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_Wait2Long; /* 状态切换:等待长按 */
}
pKey->handleFunc(SwitchCheckState_Click); /* 执行函数(短按) */
}
else /* 需要消抖 */
{
pKey->triggerCount = pKey->triggerWaitVal; /* 触发计数器赋值触发消抖计数 */
pKey->step = SwitchCheckStep_Wait; /* 状态切换:消抖 */
}
}
break;
case SwitchCheckStep_Wait:/*消抖*/
--pKey->triggerCount;
if(0 == pKey->triggerCount) /* 消抖完毕 */
{
if(pKey->readInputStateFunc() == pKey->trigger) /* 设备触发条件满足 */
{
#if CFG_XXXSWITCH_EDGETRIGGER
if(SwitchDeviceType_EdgeTrigger == pKey->type) /* 边沿触发类型 */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_WaitNotTrigge; /* 状态切换:等待复位 */
pKey->handleFunc(SwitchCheckState_EdgeTrigger); /* 执行函数(边沿触发) */
break;
}
#endif
if(0 == pKey->longVal) /* 长按计数为0,即关闭长按检测功能(伴随关闭持续长按与长按抬起功能) */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
#if CFG_XXXSWITCH_COMBOHIT
pKey->triggerCount = pKey->comboHitInterval; /* 这里利用触发计数器来当连击间隔计时 */
#endif
pKey->step = SwitchCheckStep_Wait2Up; /* 状态切换:等待抬起 */
}
else /* 开启长按检测功能 */
{
pKey->triggerCount = pKey->longVal; /* 触发计数器赋值长按计数 */
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_Wait2Long; /* 状态切换:等待长按 */
}
pKey->handleFunc(SwitchCheckState_Click); /* 执行函数(短按) */
}
else /* 设备触发条件不满足 判定为抖动/干扰 */
{
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
}
break;
case SwitchCheckStep_Wait2Long:/*等待长按 */
if(pKey->readInputStateFunc() == pKey->trigger) /* 设备触发条件满足 */
{
pKey->upCount = pKey->upWaitVal; /* 复位抬起计数器的抬起消抖计数(既然判定为按下了就提高抗失效能力) */
--pKey->triggerCount;
if(0 == pKey->triggerCount) /* 满足长按时长 */
{
if(0 == pKey->continueVal) /* 持续长按计数为0,即关闭持续长按功能 */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_Wait2Up; /* 状态切换:等待抬起 */
}
else
{
pKey->triggerCount = pKey->continueVal; /* 触发计数器赋值持续长按计数 */
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->step = SwitchCheckStep_Wait2Continue; /* 状态切换:等待持续长按 */
}
pKey->handleFunc(SwitchCheckState_Long); /* 执行函数(长按) */
}
}
else /* 设备触发条件失效 */
{
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 抬起消抖完毕 */
{
#if CFG_XXXSWITCH_COMBOHIT
if(SwitchDeviceType_ComboHit == pKey->type) /* 附带连击类型 */
{
if(0 != pKey->comboHitInterval) /* 开启连击功能 */
{
pKey->comboHitNum = 1; /* 连击数置一准备 */
pKey->upCount = pKey->comboHitInterval; /* 抬起计数器赋值连击最大间隔 */
pKey->step = SwitchCheckStep_Wait2ComboHit; /* 状态切换:等待连击 */
pKey->handleFunc(SwitchCheckState_Click2Up); /* 执行函数(短按抬起) */
break;
}
}
#endif
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
pKey->handleFunc(SwitchCheckState_Click2Up); /* 执行函数(短按抬起) */
}
}
break;
case SwitchCheckStep_Wait2Continue:/*等待持续长按*/
if(pKey->readInputStateFunc() == pKey->trigger) /* 设备触发条件满足 */
{
pKey->upCount = pKey->upWaitVal; /* 复位抬起计数器的抬起消抖计数(既然判定为按下了就提高抗失效能力) */
--pKey->triggerCount;
if(0 == pKey->triggerCount) /* 满足持续长按时长 */
{
pKey->triggerCount = pKey->continueVal; /* 复位触发计数器的持续长按计数 */
pKey->handleFunc(SwitchCheckState_Continue); /* 执行函数(持续长按) */
}
}
else /* 设备触发条件失效 */
{
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 抬起消抖完毕 */
{
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
pKey->handleFunc(SwitchCheckState_Long2Up); /* 执行函数(长按抬起) */
}
}
break;
case SwitchCheckStep_Wait2Up:/*等待抬起 */
if(pKey->readInputStateFunc() != pKey->trigger) /* 设备触发条件失效 */
{
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 抬起消抖完毕 */
{
if(0 == pKey->longVal) /* 关闭长按功能 */
{
#if CFG_XXXSWITCH_COMBOHIT
if(SwitchDeviceType_ComboHit == pKey->type) /* 附带连击类型 */
{
if(0 != pKey->comboHitInterval) /* 开启连击功能 */
{
if(0 != pKey->triggerCount) /* 连击间隔未超时,则准备连击判断 */
{
pKey->comboHitNum = 1; /* 连击数置一准备 */
pKey->upCount = pKey->comboHitInterval; /* 抬起计数器赋值连击最大间隔 */
pKey->step = SwitchCheckStep_Wait2ComboHit; /* 状态切换:等待连击 */
}
else /* 连击间隔超时,则恢复正常等待 */
{
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
pKey->handleFunc(SwitchCheckState_Click2Up);/* 执行函数(短按抬起) */
break;
}
}
#endif
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
pKey->handleFunc(SwitchCheckState_Click2Up); /* 执行函数(短按抬起) */
}
else /* 长按功能有效 */
{
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
pKey->handleFunc(SwitchCheckState_Long2Up); /* 执行函数(长按抬起) */
}
}
break;
}
pKey->upCount = pKey->upWaitVal; /* 设备触发条件仍然有效,则复位抬起计数器的抬起消抖计数 */
#if CFG_XXXSWITCH_COMBOHIT
if(0 != pKey->triggerCount) /* 这里利用触发计数器来当连击间隔计数 */
{
--pKey->triggerCount;
}
#endif
break;
#if CFG_XXXSWITCH_COMBOHIT
case SwitchCheckStep_Wait2ComboHit:/*等待连击*/
if(pKey->readInputStateFunc() == pKey->trigger) /* 在连击间隔内设备触发条件有效 */
{
if(0 == pKey->triggerWaitVal) /* 无需消抖 */
{
pKey->upCount = pKey->comboHitInterval; /* 复位抬起计数器的连击最大间隔 */
pKey->triggerCount = pKey->upWaitVal; /* 由于抬起计数器要用作于连击间隔计时,所以使用触发计数器来做抬起消抖 */
++pKey->comboHitNum;
pKey->step = SwitchCheckStep_Wait2ComboHitUp; /* 状态切换:等待连击抬起 */
pKey->handleFunc(SwitchCheckState_ComboHit); /* 执行函数(连击) */
}
else /* 需要消抖 */
{
pKey->triggerCount = pKey->triggerWaitVal; /* 触发计数器赋值触发消抖计数 */
pKey->step = SwitchCheckStep_ComboHitWait; /* 状态切换:连击消抖 */
}
break;
}
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 在连击间隔时间内没有触发则连击断掉,恢复正常等待 */
{
pKey->comboHitNum = 0; /* 清零连击数 */
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
break;
case SwitchCheckStep_ComboHitWait:/*连击消抖*/
--pKey->triggerCount;
if(0 == pKey->triggerCount) /* 消抖完毕 */
{
if(pKey->readInputStateFunc() == pKey->trigger) /* 设备触发条件有效 */
{
pKey->upCount = pKey->comboHitInterval; /* 复位抬起计数器的连击最大间隔 */
pKey->triggerCount = pKey->upWaitVal; /* 由于抬起计数器要用作于连击间隔计时,所以使用触发计数器来做抬起消抖 */
++pKey->comboHitNum;
pKey->step = SwitchCheckStep_Wait2ComboHitUp; /* 状态切换:等待连击抬起 */
pKey->handleFunc(SwitchCheckState_ComboHit); /* 执行函数(连击) */
}
else
{
pKey->step = SwitchCheckStep_Wait2ComboHit; /* 状态切换:等待连击 */
}
break;
}
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 在连击间隔时间内没有任何操作则连击断掉,恢复正常等待 */
{
pKey->comboHitNum = 0; /* 清零连击数 */
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
break;
case SwitchCheckStep_Wait2ComboHitUp:/*等待连击抬起*/
if(pKey->readInputStateFunc() != pKey->trigger) /* 设备触发条件失效 */
{
if(0 != pKey->triggerCount) /* 由触发计数器来做抬起消抖 */
{
--pKey->triggerCount;
}
else
{
pKey->upCount = pKey->comboHitInterval; /* 复位抬起计数器的连击最大间隔,等待下次连击 */
pKey->step = SwitchCheckStep_Wait2ComboHit; /* 状态切换:等待连击 */
}
break;
}
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 在连击间隔时间内没有任何操作则连击断掉,等待复位 */
{
pKey->upCount = pKey->upWaitVal; /* 抬起计数器赋值抬起消抖计数 */
pKey->comboHitNum = 0; /* 清零连击数 */
pKey->step = SwitchCheckStep_WaitNotTrigge; /* 状态切换:等待复位 */
}
break;
#endif
#if (CFG_XXXSWITCH_COMBOHIT || CFG_XXXSWITCH_EDGETRIGGER)
case SwitchCheckStep_WaitNotTrigge:/*等待复位*/
if(pKey->readInputStateFunc() != pKey->trigger) /* 设备触发条件失效 */
{
if(0 != pKey->upCount)
{
--pKey->upCount;
}
else /* 抬起消抖完毕 */
{
pKey->step = SwitchCheckStep_Wait2Trigger; /* 状态切换:等待触发 */
}
break;
}
pKey->upCount = pKey->upWaitVal; /* 设备触发条件仍然有效,则复位抬起计数器的抬起消抖计数 */
break;
#endif
}
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C
1
https://gitee.com/tickbug/xxx-switch-scan_-driver.git
git@gitee.com:tickbug/xxx-switch-scan_-driver.git
tickbug
xxx-switch-scan_-driver
XxxSwitchScan_Driver
master

搜索帮助

23e8dbc6 1850385 7e0993f3 1850385