多功能按键
多功能按键
一、按键基本操作定义:
单击(短按):按键按下,按下时间<1s,属于一次单击操作。
双击:2次单击操作间隔时间<0.5s,则将2次短按操作视为1次双击事件
长按:按键按下,按下时间>1s,属于一次长按操作。
二、特殊情况说明:
1、连续n次(n为奇数)短按操作,且间隔均<0.5s,产生(n-1)/2次双击事件+1次单击事件
2、连续n次(n为偶数)短按操作,且间隔均<0.5s,产生n/2次双击事件
3、若短按操作后,0.5s内执行长按操作,会在第一次短按操作0.5s后执行短按操作,第二次按下1s后执行长按操作。
三、使用建议:
由于按键的多功能性质,建议操作者每次在单击/长按/双击按键事件发生后,隔0.5s后再进行下一次的按键操作。因为在特别操作情况下,程序是保证按定义进行判断和处理的,主要是怕操作者自己记不清楚导致操作失误。
四、源码实现:
此功能模块能够实现多个按键的简单增减,代码复用高。 .h文件中的定义 #define KEY_NR 2
#define KEY_LONG_PRESS_TM 50
#define KEY_DOUBLE_CLICK_TM 25#define PRESS 1
#define UP 2typedef void (*key_press_handler_t)(void);
struct Key
{uint8_t pin;key_press_handler_t click_hook, double_click_hook, long_press_hook;
};
extern struct Key keys[KEY_NR];void key_tick_hook(void);
void tap_hook(void);
void hold_hook(void);
void double_click_hook(void);
.c中的源码实现:
#include "comfunc.h" #include "key.h" #include "rgb_lamp.h"/*---------------------------------------------------------------------------------------------key model ---------------------------------------------------------------------------------------------*/#define key_log(M, ...) custom_log("KEY", M, ##__VA_ARGS__) #define key_log_trace() custom_log_trace("KEY")#define system_log(M, ...) custom_log("SYSTEM", M, ##__VA_ARGS__)enum {KEY_EVENT_NO,KEY_PRESS,KEY_LONG_PRESS, };struct KeyMessage {int key_no;int key_event; }; //--------------------------------------------------------------------------------------------- void tap_hook(void) {key_log("tap!"); } //--------------------------------------------------------------------------------------------- void double_click_hook(void) {key_log("double click!"); } //--------------------------------------------------------------------------------------------- void hold_hook(void) {key_log("hold!"); } //--------------------------------------------------------------------------------------------- struct Key keys[KEY_NR] = {{KEY_PIN_1, tap_hook, double_click_hook, hold_hook},{KEY_PIN_2, tap_hook, double_click_hook, hold_hook}, }; //--------------------------------------------------------------------------------------------- static inline int is_key_press(uint8_t key_no) {bool pin_state;if (key_no >= array_size(keys)) return 0; pin_state = port_pin_get_input_level(keys[key_no].pin);return (!pin_state); } //--------------------------------------------------------------------------------------------- static void key_init(struct Key *key) {struct port_config config_port_pin;port_get_config_defaults(&config_port_pin);config_port_pin.direction = PORT_PIN_DIR_INPUT;config_port_pin.input_pull = PORT_PIN_PULL_UP;port_pin_set_config(key->pin, &config_port_pin); } //--------------------------------------------------------------------------------------------- static uint32_t key_pre; static uint32_t key_press_cnt[array_size(keys)]; #define is_key_pre_press(key_no) tst_bit(key_pre, key_no) #define set_key_pre_press(key_no) set_bit(key_pre, key_no) #define reset_key_pre_press(key_no) clr_bit(key_pre, key_no)static uint8_t key_click_time[array_size(keys)]; static uint8_t key_click_cnt[array_size(keys)]; void key_tick_hook(void) {uint8_t i;static uint32_t key_status[array_size(keys)] = { 0 };for (i = 0; i < array_size(keys); ++i){key_status[i] <<= 1;key_status[i] |= is_key_press(i);} #define is_key_press_ok(key_no) ((key_status[key_no] & 0x03) == 0x03) #define is_key_up_ok(key_no) ((key_status[key_no] & 0x03) == 0x00)for (i = 0; i < array_size(keys); ++i){if (is_key_press_ok(i)){if (!is_key_pre_press(i)) //key down{key_press_cnt[i] = KEY_LONG_PRESS_TM;set_key_pre_press(i);} else if (key_press_cnt[i] > 0){if (--key_press_cnt[i] == 0) //over tm{keys[i].long_press_hook();}}} else if (is_key_up_ok(i) && is_key_pre_press(i)) //key up{if(key_press_cnt[i] > 0)//click{key_click_cnt[i]++;key_click_time[i] = KEY_DOUBLE_CLICK_TM;}reset_key_pre_press(i);}if(key_click_time[i] > 0)key_click_time[i]--;if(key_click_time[i] == 0 && key_click_cnt[i] == 1)//single click{key_click_cnt[i] = 0;key_click_time[i] = 0;keys[i].click_hook();}else if(key_click_time[i] > 0 && key_click_cnt[i] == 2)//double click{key_click_cnt[i] = 0;key_click_time[i] = 0;keys[i].double_click_hook();}} } //--------------------------------------------------------------------------------------------- void key_multi_init(void) {for(uint8_t i=0;i
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
