功能描述
支持按下防抖,松开防抖,防抖参数可设定 
支持单击,多次长按,释放,很容易扩展成双击,三击……
  
依赖条件
外部中断
定时器
设计细节
实现原理

按下按键后,启动一个周期为 t 的定时器
如果按键不松开,依次到达 T1=tcount1, T2=tcount2, T3=t*count3 (release) 时间点
如果按键松开,可能会触发 release0, release1, release2
press0:可能是抖动,抛弃不用
release0:为了消抖和短按的响应及时,count1 设置较小(例如50ms),所以很难触发 release0
press1:按下按键累计时间到达 count1 设置的时间
 
release1:松开按键的时间处于 count1 和 count2 之间
 
press2:按下按键累计时间到达 count2 设置的时间
 
release2:松开按键的时间处于 count2 和 count3 之间
 
release:按下按键累计时间到达 count3 设置的时间,由于count3是最后一个count,所以即使按键没有释放,也认为按键释放,即按键超时释放
 
结构体
Code: Select all
typedef struct {
    UINT32_T count;
    UINT32_T check_idx;
    UINT32_T check_record;
    UINT32_T state;
} tal_key_inter_param_t;
typedef struct {
    UINT32_T pin; //按键对应的引脚
    tal_key_level_t valid_level; //有效电平
    UINT8_T  count_len; //按键状态数
    UINT32_T count_array[10]; //按键状态时间枚举
    tal_key_handler_t handler; //按键结果处理
    tal_key_inter_param_t inter; //内部变量,不用赋值
} tal_key_param_t;
使用场景
场景1
Code: Select all
//(1)定义静态全局变量
STATIC tal_key_param_t key_press_param = {
    .pin = APP_KEY_PIN,
    .valid_level = TUYA_KEY_LEVEL_LOW,
    .count_len = 3,
    .count_array = {5, 300, 500},
    .handler = app_key_handler,
};
//(2)初始化
tal_key_init(&key_press_param);
//(3)启动一个循环定时器(建议10ms),tal_key_timeout_handler() 放到定时器处理函数中
if(!tal_key_timeout_handler(&key_press_param)) {
    //停止循环定时器
}
//(4)实现 tal_key_get_pin_level() 
// Weak function instance
UINT32_T tal_key_get_pin_level(UINT32_T pin)
{
    //实现虚函数
}
//(5)在各种 state 中加上自定义处理功能即可
STATIC VOID_T app_key_handler(UINT32_T state)
{
//    TAL_PR_INFO("Key state: %d", state);
    switch(state)
    {
        //Short press
        case 1: {
        } break;
        
        //Long press
        case 2: {
        } break;
        
        //Long long press timeout
        case 3: {
        } break;
        
        //Short press release
        case 5: {
        } break;
        
        //Long press release
        case 6: {
        } break;
        
        default: {
        } break;
    }
}