new version

This commit is contained in:
Jaup 2016-09-09 10:36:01 +00:00
parent 305da86b64
commit 837afe22fc
6 changed files with 160 additions and 97 deletions

View File

@ -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...
}
...
```

View File

@ -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;
}

View File

@ -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);

View File

@ -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)
{}
}

58
examples/event_callback.c Normal file
View File

@ -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...
}
...

37
examples/event_inquire.c Normal file
View File

@ -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
}
}
}
}