喷淋器 P0 功能实现
This commit is contained in:
@@ -0,0 +1,265 @@
|
||||
/******************************************************************************
|
||||
* @file key.c
|
||||
* @brief 按键状态机实现
|
||||
* @author cyWu <1917507415@qq.com>
|
||||
* @date 2026.08.25
|
||||
* @version V1.0.0,首次发布,实现按键短按/长按/释放状态机
|
||||
******************************************************************************/
|
||||
|
||||
#include "key.h"
|
||||
#include <stddef.h>
|
||||
|
||||
static uint32_t s_key_count_time;
|
||||
static uint8_t s_key_num = USR_KEY_COUNT;
|
||||
keyCategory_t keyTable[USR_KEY_COUNT];
|
||||
|
||||
/**
|
||||
* @brief 读按键电平到 fsm
|
||||
* @param key 状态机
|
||||
* @return 1=已读,0=被屏蔽
|
||||
*/
|
||||
static uint8_t get_key_level(keyFSM_t *key)
|
||||
{
|
||||
if (key->keyShield == KEY_DISABLE) {
|
||||
return 0;
|
||||
}
|
||||
if (key->keyReadValue == NULL) {
|
||||
return 0;
|
||||
}
|
||||
key->keyLevel = (key->keyReadValue() == key->keyDownLevel) ? Bit_SET : Bit_RESET;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 单击 / 双击间隔判定
|
||||
* @param click 状态机
|
||||
* @return 1=可以出事件
|
||||
*/
|
||||
static uint8_t key_click_frequency(keyFSM_t *click)
|
||||
{
|
||||
click->keyInterval++;
|
||||
switch (click->keyFrequency) {
|
||||
case CLICK:
|
||||
if (click->keyInterval >= (KEY_INTERVAL / (DEBOUNCE_TIME * KEY_TIMER_MS))) {
|
||||
click->eventType = SHORT_Event;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case DbLCLICK:
|
||||
if (click->keyInterval >= (KEY_INTERVAL / (DEBOUNCE_TIME * KEY_TIMER_MS))) {
|
||||
click->eventType = DBCL_Event;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 按键状态机步进
|
||||
* @param key_buf 状态机
|
||||
* @return 1=已处理
|
||||
*/
|
||||
static uint8_t read_key_status(keyFSM_t *key_buf)
|
||||
{
|
||||
if (!get_key_level(key_buf)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (key_buf->keyStatus) {
|
||||
case KEY_ST_NULL:
|
||||
if (key_buf->keyLevel == Bit_SET) {
|
||||
key_buf->keyStatus = KEY_ST_SURE;
|
||||
}
|
||||
break;
|
||||
case KEY_ST_SURE:
|
||||
if (key_buf->keyLevel == Bit_SET) {
|
||||
key_buf->eventType = DOWN_Event;
|
||||
key_buf->keyStatus = KEY_ST_DOWN;
|
||||
key_buf->keyCount = 0;
|
||||
key_buf->keyLongFlag = 1;
|
||||
} else {
|
||||
key_buf->keyStatus = KEY_ST_NULL;
|
||||
}
|
||||
break;
|
||||
case KEY_ST_DOWN:
|
||||
if (key_buf->keyLevel != Bit_SET) {
|
||||
if (key_buf->keyShortFlag == 0) {
|
||||
key_buf->keyShortFlag = 1;
|
||||
key_buf->keyFrequency++;
|
||||
key_buf->keyInterval = 0;
|
||||
}
|
||||
if (key_click_frequency(key_buf)) {
|
||||
key_buf->keyFrequency = 0;
|
||||
key_buf->keyStatus = KEY_ST_NULL;
|
||||
}
|
||||
if ((key_buf->keyCount >= key_buf->keyLongTime / DEBOUNCE_TIME)
|
||||
&& (key_buf->keyCount < key_buf->keyLastTime / DEBOUNCE_TIME)) {
|
||||
key_buf->keyFrequency = 0;
|
||||
key_buf->keyStatus = KEY_ST_NULL;
|
||||
key_buf->eventType = RELEASE_Event;
|
||||
}
|
||||
key_buf->keyCount = 0;
|
||||
key_buf->keyLongFlag = 1;
|
||||
} else {
|
||||
if ((++key_buf->keyCount >= key_buf->keyLastTime / DEBOUNCE_TIME)) {
|
||||
key_buf->keyCount = 0;
|
||||
key_buf->keyFrequency = 0;
|
||||
key_buf->keyStatus = KEY_ST_LONG;
|
||||
key_buf->eventType = LAST_Event;
|
||||
key_buf->keyLongFlag = 1;
|
||||
}
|
||||
if ((key_buf->keyCount >= key_buf->keyLongTime / DEBOUNCE_TIME)
|
||||
&& (key_buf->keyCount < key_buf->keyLastTime / DEBOUNCE_TIME)) {
|
||||
key_buf->keyFrequency = 0;
|
||||
if (key_buf->keyLongFlag == 1) {
|
||||
key_buf->eventType = LONG_Event;
|
||||
key_buf->keyLongFlag = 0;
|
||||
}
|
||||
}
|
||||
key_buf->keyShortFlag = 0;
|
||||
}
|
||||
break;
|
||||
case KEY_ST_LONG:
|
||||
if (key_buf->keyLevel != Bit_SET) {
|
||||
key_buf->keyStatus = KEY_ST_NULL;
|
||||
key_buf->eventType = RELEASE_Event;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 扫描全部按键状态机
|
||||
* @return 无
|
||||
*/
|
||||
static void key_event_process(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < s_key_num; i++) {
|
||||
(void)read_key_status(&keyTable[i].fsm);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 1ms 调用一次;满 DEBOUNCE_TIME 才真正采样
|
||||
* @return 无
|
||||
*/
|
||||
void keyCheckProcess(void)
|
||||
{
|
||||
s_key_count_time++;
|
||||
if (s_key_count_time >= (DEBOUNCE_TIME / KEY_TIMER_MS)) {
|
||||
s_key_count_time = 0;
|
||||
key_event_process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 拷贝产品按键表
|
||||
* @param keys 按键数组,长度 USR_KEY_COUNT
|
||||
* @return 无
|
||||
*/
|
||||
void keyParaInit(keyCategory_t *keys)
|
||||
{
|
||||
if (keys == NULL) {
|
||||
return;
|
||||
}
|
||||
if (USR_KEY_COUNT >= KEY_MAX_NUMBER) {
|
||||
s_key_num = KEY_MAX_NUMBER;
|
||||
}
|
||||
memcpy(keyTable, keys, sizeof(keyCategory_t) * s_key_num);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 运行中改长按/连按时长并复位状态
|
||||
* @param key_event 按键索引
|
||||
* @param key_param 新参数
|
||||
* @return 无
|
||||
*/
|
||||
void setKeyEventParams(uint8_t key_event, keyCategory_t key_param)
|
||||
{
|
||||
if (key_event >= s_key_num) {
|
||||
return;
|
||||
}
|
||||
keyTable[key_event].fsm.keyShield = key_param.fsm.keyShield;
|
||||
keyTable[key_event].fsm.keyLongTime = key_param.fsm.keyLongTime;
|
||||
keyTable[key_event].fsm.keyLastTime = key_param.fsm.keyLastTime;
|
||||
keyTable[key_event].fsm.keyStatus = KEY_ST_NULL;
|
||||
keyTable[key_event].fsm.eventType = NULL_Event;
|
||||
keyTable[key_event].fsm.keyCount = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 派发按键事件回调
|
||||
* @return 无
|
||||
*/
|
||||
void keyHandle(void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < s_key_num; i++) {
|
||||
if (keyTable[i].fsm.eventType == NULL_Event) {
|
||||
continue;
|
||||
}
|
||||
switch (keyTable[i].fsm.eventType) {
|
||||
case RELEASE_Event:
|
||||
if (keyTable[i].func.releasePressCb != NULL) {
|
||||
keyTable[i].func.releasePressCb();
|
||||
}
|
||||
keyTable[i].fsm.eventType = NULL_Event;
|
||||
break;
|
||||
case SHORT_Event:
|
||||
if (keyTable[i].func.ShortPressCb != NULL) {
|
||||
keyTable[i].func.ShortPressCb();
|
||||
}
|
||||
keyTable[i].fsm.eventType = NULL_Event;
|
||||
break;
|
||||
case DOWN_Event:
|
||||
if (keyTable[i].func.downPressCb != NULL) {
|
||||
keyTable[i].func.downPressCb();
|
||||
}
|
||||
keyTable[i].fsm.eventType = NULL_Event;
|
||||
break;
|
||||
case LONG_Event:
|
||||
if (keyTable[i].func.longPressCb != NULL) {
|
||||
keyTable[i].func.longPressCb();
|
||||
}
|
||||
keyTable[i].fsm.eventType = NULL_Event;
|
||||
break;
|
||||
case LAST_Event:
|
||||
if (keyTable[i].func.lastPressCb != NULL) {
|
||||
keyTable[i].func.lastPressCb();
|
||||
}
|
||||
break;
|
||||
case DBCL_Event:
|
||||
if (keyTable[i].func.dbclPressCb != NULL) {
|
||||
keyTable[i].func.dbclPressCb();
|
||||
}
|
||||
keyTable[i].fsm.eventType = NULL_Event;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 复位指定按键状态机
|
||||
* @param key_index 按键索引
|
||||
* @return 无
|
||||
*/
|
||||
void reset_key_Status(keyList key_index)
|
||||
{
|
||||
if (key_index >= USR_KEY_COUNT) {
|
||||
return;
|
||||
}
|
||||
keyTable[key_index].fsm.keyStatus = KEY_ST_NULL;
|
||||
keyTable[key_index].fsm.eventType = NULL_Event;
|
||||
keyTable[key_index].fsm.keyCount = 0;
|
||||
}
|
||||
Reference in New Issue
Block a user