stm32 按键长按短按组合按键状态机
时间: 2023-07-13 17:09:45 浏览: 198
实现按键的长按、短按和组合按键功能可以通过状态机来实现。下面提供一个简单的示例代码,以两个按键为例,一个为K1,一个为K2。
首先定义状态:
```c
typedef enum {
KEY_IDLE_STATE,
KEY_SHORT_PRESS_STATE,
KEY_LONG_PRESS_STATE,
KEY_COMB_PRESS_STATE
} KEY_STATE;
```
然后定义按键结构体:
```c
typedef struct {
GPIO_TypeDef *port;
uint16_t pin;
uint32_t long_press_time;
uint32_t comb_press_time;
uint32_t last_time;
uint8_t comb_flag;
KEY_STATE state;
} KEY_TypeDef;
```
其中,`port`和`pin`表示按键所在的GPIO口和引脚,`long_press_time`表示长按的时间阈值,`comb_press_time`表示组合按键的时间阈值,`last_time`表示上次检测按键的时间,`comb_flag`表示组合按键标志,`state`表示当前状态。
接下来定义状态转换函数:
```c
static void key_state_transfer(KEY_TypeDef *key)
{
uint32_t current_time = HAL_GetTick();
switch (key->state) {
case KEY_IDLE_STATE:
if (HAL_GPIO_ReadPin(key->port, key->pin) == GPIO_PIN_RESET) {
key->state = KEY_SHORT_PRESS_STATE;
key->last_time = current_time;
}
break;
case KEY_SHORT_PRESS_STATE:
if (HAL_GPIO_ReadPin(key->port, key->pin) == GPIO_PIN_SET) {
key->state = KEY_IDLE_STATE;
if (current_time - key->last_time < key->long_press_time) {
// 短按
} else {
// 长按
}
} else {
if (current_time - key->last_time >= key->comb_press_time) {
key->state = KEY_COMB_PRESS_STATE;
key->comb_flag = 1;
}
}
break;
case KEY_LONG_PRESS_STATE:
if (HAL_GPIO_ReadPin(key->port, key->pin) == GPIO_PIN_SET) {
key->state = KEY_IDLE_STATE;
}
break;
case KEY_COMB_PRESS_STATE:
if (HAL_GPIO_ReadPin(key->port, key->pin) == GPIO_PIN_SET) {
key->state = KEY_IDLE_STATE;
if (key->comb_flag) {
// 组合按键
}
key->comb_flag = 0;
}
break;
default:
key->state = KEY_IDLE_STATE;
break;
}
}
```
在主函数中循环调用按键状态转换函数即可:
```c
KEY_TypeDef key1 = { GPIOA, GPIO_PIN_0, 1000, 500, 0, 0, KEY_IDLE_STATE };
KEY_TypeDef key2 = { GPIOA, GPIO_PIN_1, 1000, 500, 0, 0, KEY_IDLE_STATE };
while (1) {
key_state_transfer(&key1);
key_state_transfer(&key2);
}
```
上述代码实现了两个按键的长按、短按和组合按键功能,你可以根据实际需要进行修改和扩展。
阅读全文