#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
// 定义状态
typedef enum {
IDLE,
DEBOUNCE,
PRESSED,
SHORT_PRESS,
LONG_PRESS
} State;
// 定义事件
typedef enum {
KEY_DOWN,
KEY_UP
} Event;
// 定义按键状态机
typedef struct {
State currentState;
uint32_t debounceTimer;
uint32_t longPressTimer;
} KeyStateMachine;
// 初始化状态机
void KeyStateMachine_Init(KeyStateMachine *sm) {
sm->currentState = IDLE;
sm->debounceTimer = 0;
sm->longPressTimer = 0;
}
// 检测按键电平
bool IsKeyPressed(void) {
// 模拟读取按键电平
// 返回true表示按键按下,false表示未按下
return true; // 替换为实际读取按键电平的代码
}
// 状态机处理函数
void KeyStateMachine_Process(KeyStateMachine *sm) {
Event event = IsKeyPressed() ? KEY_DOWN : KEY_UP;
switch (sm->currentState) {
case IDLE:
if (event == KEY_DOWN) {
sm->currentState = DEBOUNCE;
sm->debounceTimer = 20; // 消抖时间20ms
}
break;
case DEBOUNCE:
if (event == KEY_DOWN && --sm->debounceTimer == 0) {
sm->currentState = PRESSED;
sm->longPressTimer = 1000; // 长按时间1000ms
} else if (event == KEY_UP) {
sm->currentState = IDLE;
}
break;
case PRESSED:
if (event == KEY_UP) {
sm->currentState = SHORT_PRESS;
// 执行短按操作
printf("Short press detected\n");
} else if (--sm->longPressTimer == 0) {
sm->currentState = LONG_PRESS;
// 执行长按操作
printf("Long press detected\n");
}
break;
case SHORT_PRESS:
if (event == KEY_DOWN) {
sm->currentState = PRESSED;
sm->longPressTimer = 1000; // 重置长按时间
}
break;
case LONG_PRESS:
if (event == KEY_UP) {
sm->currentState = IDLE;
}
break;
default:
sm->currentState = IDLE;
break;
}
}
int main() {
KeyStateMachine sm;
KeyStateMachine_Init(&sm);
while (1) {
KeyStateMachine_Process(&sm);
// 模拟延时
for (volatile uint32_t i = 0; i < 1000000; i++);
}
return 0;
} |