-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbutton.cpp
135 lines (126 loc) · 4.07 KB
/
button.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include "button.h"
Button::Button(char* str, EventInfo ev, PinInfo pin)
{
for (int i = 0; i < 8; i++) callbackFun[i] = nullptr;
this->state = 1;
this->eventInfo = ev;
this->pinInfo = pin;
this->name = str;
}
BTN_Event Button::getState()
{
return this->event;
}
BTN_Event Button::stateMachine()
{
uint8_t n = this->state;
uint8_t PinLevel = pinInfo.readPin();
pinInfo.level = PinLevel;
switch (n) {
case 1:
if (PinLevel == PIN_LEVEL) {
this->event = PRESS_DOWN;
this->state = 2;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
else {
this->event = IMPENDING;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
eventInfo.holdingTime = 0;
eventInfo.releaseTime = 0;
break;
case 2:
if (PinLevel == PIN_LEVEL) { //按键保持按下状态
eventInfo.holdingTime += eventInfo.scanPeriod;
if (eventInfo.holdingTime > eventInfo.holdingTimeThread) { //按键处于长按状态
this->state = 5;
this->event = LONG_TIME_HOLD_START;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
else { //触发HOLDING状态
this->state = 2;
}
}
else {
eventInfo.holdingTime += eventInfo.scanPeriod;
if (eventInfo.holdingTime > eventInfo.joggleTimeThread) { //按键弹起
this->event = PRESS_UP;
this->state = 3;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
else { //发生抖动,进行滤波消抖
this->event = IMPENDING;
this->state = 1;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
}
break;
case 3:
if (PinLevel == PIN_LEVEL) {
eventInfo.holdingTime += eventInfo.scanPeriod;
if (eventInfo.holdingTime > eventInfo.joggleTimeThread) { //按键再次按下
this->event = PRESS_DOWN;
this->state = 4;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
else { //维持状态不变
this->state = 3;
}
}
else { //按键已经松开
eventInfo.releaseTime += eventInfo.scanPeriod;
if (eventInfo.releaseTime > eventInfo.releaseTimeThread) { //按键单击
this->event = SINGLE_CLICK;
this->state = 1;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
else {
this->state = 3;
}
}
break;
case 4:
if (PinLevel == PIN_LEVEL) {
eventInfo.holdingTime += eventInfo.scanPeriod;
}
else { //按键已经松开
this->event = DOUBLE_CLICK;
this->state = 1;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
}
break;
case 5:
if (PinLevel == PIN_LEVEL) {
eventInfo.holdingTime += eventInfo.scanPeriod;
}
else { //按键已经松开
this->event = PRESS_UP;
this->callbackFun[this->event];
this->event = LONG_TIME_HOLD;
if (this->callbackFun[this->event] != nullptr)
this->callbackFun[this->event]();
this->state = 1;
}
break;
default:
break;
}
return this->event;
}
void Button::eventRegist(BTN_Event state, CbFun pFunction)
{
this->callbackFun[state] = pFunction;
}
void Button::eventUpdate(BTN_Event state)
{
this->callbackFun[state]();
}