更新按键程序,加入时钟源,加入连击功能

This commit is contained in:
不吃油炸鸡
2025-12-02 19:23:11 +08:00
parent 6a27b28ace
commit e141aa4260
2 changed files with 327 additions and 60 deletions

View File

@@ -5,43 +5,96 @@
extern "C" {
#endif
#include "main.h"
#pragma once
// boot, yes, right, left, no
#define KEYB_NUM 1
#define KEYY_NUM 2
#define KEYL_NUM 3
#define KEYR_NUM 4
#define KEYN_NUM 5
#include "main.h"
#include <stdint.h>
#include <stdbool.h>
// 时间参数单位ms
#define KEY_LONG_THRESHOLD_MS 500 // 长按判定时间
#define KEY_REPEAT_INTERVAL_MS 150 // 连发间隔时间
#define KEY_DEBOUNCE_MS 3 // 消抖时间
/* 掩码工具(位索引即 key_id_t */
#define KEY_BIT(id) (1U << (uint8_t)(id))
#define KEY_ALL_MASK ((uint32_t)((KEY_ID_MAX >= 32) ? 0xFFFFFFFFu : ((1u << KEY_ID_MAX) - 1)))
//KEYB
#define KEYB_PORT GPIOA
#define KEYB_PIN GPIO_PIN_0
#define KEYB HAL_GPIO_ReadPin(KEYB_PORT,KEYB_PIN)
//KEYN
#define KEYN_PORT GPIOA
#define KEYN_PIN GPIO_PIN_4
#define KEYN HAL_GPIO_ReadPin(KEYN_PORT,KEYN_PIN)
//KEYL
#define KEYL_PORT GPIOA
#define KEYL_PIN GPIO_PIN_3
#define KEYL HAL_GPIO_ReadPin(KEYL_PORT,KEYL_PIN)
//KEYR
#define KEYR_PORT GPIOA
#define KEYR_PIN GPIO_PIN_2
#define KEYR HAL_GPIO_ReadPin(KEYR_PORT,KEYR_PIN)
//KEYY
#define KEYY_PORT GPIOA
#define KEYY_PIN GPIO_PIN_1
#define KEYY HAL_GPIO_ReadPin(KEYY_PORT,KEYY_PIN)
void Key_Port_Init(void);
uint8_t KeyScan(uint8_t mode);
/**
* @brief 按键ID与掩码位索引一致
*/
typedef enum {
KEY_ID_B = 0, // KEYB
KEY_ID_Y, // KEYY
KEY_ID_L, // KEYL
KEY_ID_R, // KEYR
KEY_ID_N, // KEYN
KEY_ID_MAX
} key_id_t;
/**
* @brief 事件类型
*/
typedef enum {
KEY_EVT_NONE = 0,
KEY_EVT_DOWN = 1, // 去抖后稳定按下
KEY_EVT_UP = 2, // 去抖后稳定释放
KEY_EVT_CLICK = 3, // 短按(一次按下->释放,且未触发长按)
KEY_EVT_LONG = 4, // 达到长按阈值触发一次
KEY_EVT_REPEAT = 5 // 长按连发周期事件
} key_evt_type_t;
/**
* @brief 事件对象
*/
typedef struct {
key_id_t id;
key_evt_type_t type;
} key_event_t;
/**
* @brief 扫描模式(可组合)
*/
typedef enum {
KEY_MODE_REPORT_DOWN_UP = 0x01, // 上报 DOWN/UP
KEY_MODE_CLICK_ON_RELEASE = 0x02, // 释放时若未长按,上报 CLICK
KEY_MODE_LONG_ONCE = 0x04, // 达到阈值上报一次 LONG
KEY_MODE_REPEAT = 0x08 // 达到阈值后周期性上报 REPEAT
} key_mode_t;
/**
* @brief 时序参数单位ms可运行时修改
*/
typedef struct {
uint16_t debounce_ms; // 消抖时间,建议 3~20
uint16_t long_ms; // 长按判定时间,建议 400~800
uint16_t repeat_ms; // 连发间隔,建议 80~200
} key_timing_t;
void Key_Init(void);
bool Key_Scan(key_event_t* out_evt);
#ifdef __cplusplus
}