From 837afe22fc76685ef8c28ed0b78239678df736b5 Mon Sep 17 00:00:00 2001 From: Jaup <270995079@qq.com> Date: Fri, 9 Sep 2016 10:36:01 +0000 Subject: [PATCH] new version --- README.md | 71 +++++++++++++++++++----------------- button.c | 29 ++++++--------- button.h | 21 ++++++++--- examples/SimpleMultiButton.c | 41 --------------------- examples/event_callback.c | 58 +++++++++++++++++++++++++++++ examples/event_inquire.c | 37 +++++++++++++++++++ 6 files changed, 160 insertions(+), 97 deletions(-) delete mode 100644 examples/SimpleMultiButton.c create mode 100644 examples/event_callback.c create mode 100644 examples/event_inquire.c diff --git a/README.md b/README.md index 4fa063f..b974c14 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ button_init(&button1, read_button_pin, 0); 3.注册按键事件 ``` -button_attach(&button1, CLICK, Callback_CLICK_Handler); +button_attach(&button1, SINGLE_CLICK, Callback_SINGLE_CLICK_Handler); button_attach(&button1, DOUBLE_CLICK, Callback_DOUBLE_Click_Handler); ... ``` @@ -44,14 +44,16 @@ MultiButton 使用C语言实现,基于面向对象方式设计思路,每个 ``` struct Button { - uint16_t ticks; - uint8_t state : 3; - uint8_t debounce_cnt : 3; - uint8_t active_level : 1; - uint8_t button_level : 1; - uint8_t (*hal_button_Level)(void); - CallBackFunc cb[number_of_event]; - struct Button* next; + uint16_t ticks; + uint8_t repeat: 4; + uint8_t event : 4; + uint8_t state : 3; + uint8_t debounce_cnt : 3; + uint8_t active_level : 1; + uint8_t button_level : 1; + uint8_t (*hal_button_Level)(void); + BtnCallback cb[number_of_event]; + struct Button* next; }; ``` 这样每个按键使用单向链表相连,依次进入 button_handler(struct Button* handle) 状态机处理,所以每个按键的状态彼此独立。 @@ -62,43 +64,46 @@ struct Button { ``` #include "button.h" -struct Button button1; +struct Button btn1; -int read_button_pin() +int read_button1_GPIO() { - return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin); //HAL GPIO read. + return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin); } + int main() { - button_init(&button1, read_button_pin, 0); - button_attach(&button1, PRESSED, BTN1_PRESSED_Handler); - button_attach(&button1, CLICK, BTN1_CLICK_Handler); - button_attach(&button1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler); - button_attach(&button1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler); - button_attach(&button1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler); - button_attach(&button1, LONG_PRESS_STOP, BTN1_LONG_PRESS_STOP_Handler); - button_start(&button1); - - //make the timer repeat invoking the button_ticks() interval 5ms. - //This function is implemented by yourself. - __timer_start(button_ticks, 0, 5); - - while(ture) - { - ... - } + button_init(&btn1, read_button1_GPIO, 0); + + button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler); + button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler); + button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler); + button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler); + button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler); + button_attach(&btn1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler); + button_attach(&btn2, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler); + + button_start(&btn1); + + //make the timer invoking the button_ticks() interval 5ms. + //This function is implemented by yourself. + __timer_start(button_ticks, 0, 5); + + while(1) + {} } -void BTN1_PRESSED_Handler() +void BTN1_PRESS_DOWN_Handler(void* btn) { - //do something.. + //do something... } -void BTN1_DOUBLE_Click_Handler() +void BTN1_PRESS_UP_Handler(void* btn) { - //do something.. + //do something... } + ... ``` diff --git a/button.c b/button.c index 5bc79db..85ad37d 100644 --- a/button.c +++ b/button.c @@ -5,14 +5,9 @@ #include "button.h" -#define TICKS_INTERVAL 5 //ms -#define EVENT_CB(ev) if(handle->cb[ev]){handle->cb[ev](handle)} - -//According to your need to modify the constants. -const uint8_t kDebounceTicks = 3; //MAX 8 -const uint16_t kShortTicks = (350/TICKS_INTERVAL); -const uint16_t kLongTicks = (1000/TICKS_INTERVAL); +#define EVENT_CB(ev) if(handle->cb[ev])handle->cb[ev]((Button*)handle) + //button handle list head. static struct Button* head_handle = NULL; @@ -26,6 +21,7 @@ static struct Button* head_handle = NULL; void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level) { memset(handle, sizeof(struct Button), 0); + handle->event = (uint8_t)NONE_PRESS; handle->hal_button_Level = pin_level; handle->button_level = handle->hal_button_Level(); handle->active_level = active_level; @@ -38,7 +34,7 @@ void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_le * @param cb: callback function. * @retval None */ -void button_attach(struct Button* handle, PressEvent event, CallBackFunc cb) +void button_attach(struct Button* handle, PressEvent event, BtnCallback cb) { handle->cb[event] = cb; } @@ -48,9 +44,9 @@ void button_attach(struct Button* handle, PressEvent event, CallBackFunc cb) * @param handle: the button handle strcut. * @retval button event. */ -PressEvent get_button_event(const struct Button* handle) +PressEvent get_button_event(struct Button* handle) { - return (handle->event); + return (PressEvent)(handle->event); } /** @@ -68,11 +64,10 @@ void button_handler(struct Button* handle) /*------------button debounce handle---------------*/ if(read_gpio_level != handle->button_level) { //not equal to prev one //continue read 3 times same new level change - if(++(handle->debounce_cnt) >= kDebounceTicks) { + if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) { handle->button_level = read_gpio_level; handle->debounce_cnt = 0; } - } else { //leved not change ,counter reset. handle->debounce_cnt = 0; } @@ -96,7 +91,7 @@ void button_handler(struct Button* handle) handle->ticks = 0; handle->state = 2; - } else if(handle->ticks > kLongTicks) { + } else if(handle->ticks > LONG_TICKS) { handle->event = (uint8_t)LONG_RRESS_START; EVENT_CB(LONG_RRESS_START); handle->state = 5; @@ -107,7 +102,7 @@ void button_handler(struct Button* handle) if(handle->button_level == handle->active_level) { //press down again handle->event = (uint8_t)PRESS_DOWN; EVENT_CB(PRESS_DOWN); - handle->repeat++; + handle->repeat++; if(handle->repeat == 2) { handle->event = (uint8_t)DOUBLE_CLICK; EVENT_CB(DOUBLE_CLICK); // repeat hit @@ -118,7 +113,7 @@ void button_handler(struct Button* handle) EVENT_CB(PRESS_REPEAT); // repeat hit handle->ticks = 0; handle->state = 3; - } else if(handle->ticks > kShortTicks) { + } else if(handle->ticks > SHORT_TICKS) { if(handle->repeat == 1) { handle->event = (uint8_t)SINGLE_CLICK; EVENT_CB(SINGLE_CLICK); @@ -132,7 +127,7 @@ void button_handler(struct Button* handle) if(handle->button_level != handle->active_level) { //released press up handle->event = (uint8_t)PRESS_UP; EVENT_CB(PRESS_UP); - if(handle->ticks < kShortTicks) { + if(handle->ticks < SHORT_TICKS) { handle->ticks = 0; handle->state = 2; //repeat press } else { @@ -151,7 +146,7 @@ void button_handler(struct Button* handle) } else { //releasd handle->event = (uint8_t)PRESS_UP; - EVENT_CB(PRESS_UP) + EVENT_CB(PRESS_UP); handle->state = 0; //reset handle->event = (uint8_t)NONE_PRESS; } diff --git a/button.h b/button.h index 5bfb78d..20d4013 100644 --- a/button.h +++ b/button.h @@ -8,8 +8,17 @@ #include "stdint.h" #include "string.h" +#include "button.h" -typedef void (*BtnCallback)(const struct Button* btn); + +//According to your need to modify the constants. +#define TICKS_INTERVAL 5 //ms +#define DEBOUNCE_TICKS 4 //MAX 8 +#define SHORT_TICKS (300 /TICKS_INTERVAL) +#define LONG_TICKS (1000 /TICKS_INTERVAL) + + +typedef void (*BtnCallback)(void*); typedef enum { PRESS_DOWN = 0, @@ -19,11 +28,11 @@ typedef enum { DOUBLE_CLICK, LONG_RRESS_START, LONG_PRESS_HOLD, - number_of_event, + number_of_event, NONE_PRESS }PressEvent; -struct Button { +typedef struct Button { uint16_t ticks; uint8_t repeat : 4; uint8_t event : 4; @@ -34,15 +43,15 @@ struct Button { uint8_t (*hal_button_Level)(void); BtnCallback cb[number_of_event]; struct Button* next; -}; +}Button; #ifdef __cplusplus extern "C" { #endif void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level); -void button_attach(struct Button* handle, PressEvent event, CallBackFunc cb); -PressEvent get_button_event(const struct Button* handle); +void button_attach(struct Button* handle, PressEvent event, BtnCallback cb); +PressEvent get_button_event(struct Button* handle); int button_start(struct Button* btn); void button_stop(struct Button* btn); void button_ticks(void); diff --git a/examples/SimpleMultiButton.c b/examples/SimpleMultiButton.c deleted file mode 100644 index 38d1375..0000000 --- a/examples/SimpleMultiButton.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "button.h" - -struct Button btn1; -struct Button btn2; -struct Button btn3; - -void main() -{ - button_init(&btn1, read_K1_pin, 0); - button_attach(&btn1, PRESSED, BTN1_PRESSED_Handler); - button_attach(&btn1, CLICK, BTN1_Click_Handler); - button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler); - button_attach(&btn1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler); - button_attach(&btn1, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler); - button_attach(&btn1, LONG_PRESS_STOP, BTN1_LONG_PRESS_STOP_Handler); - button_start(&btn1); - - button_init(&btn2, read_K2_pin, 0); - button_attach(&btn2, PRESSED, BTN2_PRESSED_Handler); - button_attach(&btn2, CLICK, BTN2_Click_Handler); - button_attach(&btn2, DOUBLE_CLICK, BTN2_DOUBLE_Click_Handler); - button_attach(&btn2, LONG_RRESS_START, BTN2_LONG_RRESS_START_Handler); - button_attach(&btn2, LONG_PRESS_HOLD, BTN2_LONG_PRESS_HOLD_Handler); - button_attach(&btn2, LONG_PRESS_STOP, BTN2_LONG_PRESS_STOP_Handler); - button_start(&btn2); - - button_init(&btn3, read_K3_pin, 0); - button_attach(&btn3, PRESSED, BTN3_PRESSED_Handler); - button_attach(&btn3, CLICK, BTN3_Click_Handler); - button_attach(&btn3, DOUBLE_CLICK, BTN3_DOUBLE_Click_Handler); - button_attach(&btn3, LONG_RRESS_START, BTN3_LONG_RRESS_START_Handler); - button_attach(&btn3, LONG_PRESS_HOLD, BTN3_LONG_PRESS_HOLD_Handler); - button_attach(&btn3, LONG_PRESS_STOP, BTN3_LONG_PRESS_STOP_Handler); - button_start(&btn3); - - //make the timer invoking the button_ticks() interval 5ms. - __timer_start(button_ticks, 0, 5); //This function is implemented by yourself. - - while(1) - {} -} \ No newline at end of file diff --git a/examples/event_callback.c b/examples/event_callback.c new file mode 100644 index 0000000..9918373 --- /dev/null +++ b/examples/event_callback.c @@ -0,0 +1,58 @@ +#include "button.h" + +struct Button btn1; +struct Button btn2; + +int read_button1_GPIO() +{ + return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin); +} + +int read_button2_GPIO() +{ + return HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin); +} + +int main() +{ + button_init(&btn1, read_button1_GPIO, 0); + button_init(&btn2, read_button2_GPIO, 0); + + button_attach(&btn1, PRESS_DOWN, BTN1_PRESS_DOWN_Handler); + button_attach(&btn1, PRESS_UP, BTN1_PRESS_UP_Handler); + button_attach(&btn1, PRESS_REPEAT, BTN1_PRESS_REPEAT_Handler); + button_attach(&btn1, SINGLE_CLICK, BTN1_SINGLE_Click_Handler); + button_attach(&btn1, DOUBLE_CLICK, BTN1_DOUBLE_Click_Handler); + button_attach(&btn1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler); + button_attach(&btn2, LONG_PRESS_HOLD, BTN1_LONG_PRESS_HOLD_Handler); + + button_attach(&btn2, PRESS_DOWN, BTN2_PRESS_DOWN_Handler); + button_attach(&btn2, PRESS_UP, BTN2_PRESS_UP_Handler); + button_attach(&btn2, PRESS_REPEAT, BTN2_PRESS_REPEAT_Handler); + button_attach(&btn2, SINGLE_CLICK, BTN2_SINGLE_Click_Handler); + button_attach(&btn2, DOUBLE_CLICK, BTN2_DOUBLE_Click_Handler); + button_attach(&btn2, LONG_RRESS_START, BTN2_LONG_RRESS_START_Handler); + button_attach(&btn2, LONG_PRESS_HOLD, BTN2_LONG_PRESS_HOLD_Handler); + + button_start(&btn1); + button_start(&btn2); + + //make the timer invoking the button_ticks() interval 5ms. + //This function is implemented by yourself. + __timer_start(button_ticks, 0, 5); + + while(1) + {} +} + +void BTN1_PRESS_DOWN_Handler(void* btn) +{ + //do something... +} + +void BTN1_PRESS_UP_Handler(void* btn) +{ + //do something... +} + +... \ No newline at end of file diff --git a/examples/event_inquire.c b/examples/event_inquire.c new file mode 100644 index 0000000..c0074d8 --- /dev/null +++ b/examples/event_inquire.c @@ -0,0 +1,37 @@ +#include "button.h" + +struct Button btn1; + +int read_button1_GPIO() +{ + return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin); +} + + +int main() +{ + static uint8_t btn1_event_val; + + button_init(&btn1, read_button1_GPIO, 0); + button_start(&btn1); + + //make the timer invoking the button_ticks() interval 5ms. + //This function is implemented by yourself. + __timer_start(button_ticks, 0, 5); + + while(1) + { + if(btn1_event_val != get_button_event(&btn1)) { + btn1_event_val = get_button_event(&btn1); + + if(btn1_event_val == SINGLE_CLICK) { + //do something + } else if(btn1_event_val == DOUBLE_CLICK) { + //do something + } else if(btn1_event_val == LONG_RRESS_START) { + //do something + } + } + } +} +