EmbeddedButton
簡介
EmbeddedButton是一個輕量級簡單易用的嵌入式按鍵驅動模塊,可無限拓展按鍵,支持多連擊、長按、短按長按等多種按鍵事件;該模塊通過異步回調方式來簡化程序結構,根據幾個簡單原則完成了整個代碼邏輯的支撐。
使用方法
1.定義按鍵實體
struct button_obj_t button1;
2.建立鍵值映射表(設置回調事件)
const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_press_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_press_then_long_press_handle
},
};
3.初始化按鍵對象,參數含義分別為
按鍵實體
綁定按鍵的GPIO電平讀取接口read_button1_pin()
設置有效觸發電平
按鍵ID
鍵值映射表
鍵值映射表大小
button_init(&button1, read_button1_pin, 0, 0, button1_map, ARRAY_SIZE(button1_map));
4.啟動按鍵
button_start(&button1);
5.設置一個5ms間隔的定時器循環調用按鍵后臺處理函數
while(1) {
...
if(timer_ticks == 5) {
timer_ticks = 0;
button_ticks();
}
}
特性
1.依靠簡單幾個原則,支持起整個按鍵判斷邏輯
只要鍵值非零,時間tick++
只要按鍵狀態發生變化,改變一次鍵值(__append_bit()),tick時間清零(確保tick為按下或抬起的時間)
以tick時間的長短及按鍵抬起作為一次狀態結束的判斷依據,可以很好的實現短按長按等操作;
2.使用C語言實現,巧妙利用位運算來實現每個按鍵鍵值的二進制記錄表示,1代表按下,0代表松開
3.利用數據驅動思想完成對應按鍵事件的調用:
typedef struct {
key_value_type_t key_value;
void ( kv_func_cb)(void );
} key_value_map_t;
const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_press_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_press_then_long_press_handle
},
};
for(size_t i = 0; i < button->map_size; i++) {
if((button->map_ptr[i].key_value == button->key_value)
&& (button->map_ptr[i].kv_func_cb))
{
button->map_ptr[i].kv_func_cb(button);
}
}
4.基于面向對象方式設計思路,每個按鍵對象單獨用一份數據結構管理:
typedef struct button_obj_t {
uint8_t debounce_cnt : 4;
uint8_t active_level : 1;
uint8_t read_level : 1;
uint8_t read_level_update : 1;
uint8_t event_analyze_en : 1;
uint8_t id;
uint16_t ticks;
state_bits_type_t state_bits;
key_value_type_t key_value;
uint8_t (* read_button_func_ptr)(uint8_t button_id );
const key_value_map_t map_ptr;
size_t map_size;
struct button_obj_t next;
}button_obj_t;
Examples
#include "embedded_button.h"
struct button_obj_t button1;
uint8_t read_button_pin(uint8_t button_id)
{
// you can share the GPIO read function with multiple Buttons
switch(button_id)
{
case 0:
return get_button1_value(); //Require self implementation
break;
default:
return 0;
break;
}
return 0;
}
void single_click_handle(void* btn)
{
//do something...
printf("/ single click /rn");
}
void double_click_handle(void* btn)
{
//do something...
printf("/ double click /rn");
}
void long_press_handle(void* btn)
{
//do something...
printf("/ long press /rn");
}
void single_click_then_long_press_handle(void* btn)
{
//do something...
printf("/ single click and long press /rn");
}
void double_click_then_long_press_handle(void* btn)
{
//do something...
printf("/ double click and long press /rn");
}
const key_value_map_t button1_map[] =
{
{
.key_value = SINGLE_CLICK_KV,
.kv_func_cb = single_click_handle
},
{
.key_value = DOUBLE_CLICK_KV,
.kv_func_cb = double_click_handle
},
{
.key_value = LONG_PRESEE_START,
.kv_func_cb = long_press_handle
},
{
.key_value = SINGLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = single_click_then_long_press_handle
},
{
.key_value = DOUBLE_CLICK_THEN_LONG_PRESS_KV,
.kv_func_cb = double_click_then_long_press_handle
}
};
...
int main()
{
button_init(&button1, read_button_pin, 0, 0, button1_map, ARRAY_SIZE(button1_map));
button_start(&button1);
//make the timer invoking the button_ticks() interval 5ms.
//This function is implemented by yourself.
__timer_start(button_ticks, 0, 5);
while(1)
{}
}
-
嵌入式系統
+關注
關注
41文章
3587瀏覽量
129438 -
定時器
+關注
關注
23文章
3246瀏覽量
114731 -
狀態機
+關注
關注
2文章
492瀏覽量
27530 -
GPIO
+關注
關注
16文章
1204瀏覽量
52059 -
按鍵驅動
+關注
關注
0文章
11瀏覽量
7133
發布評論請先 登錄
相關推薦
評論