UP 按键扫描支持
parent
99dcb14b60
commit
2d867be49a
|
@ -17,4 +17,4 @@ add_executable(HW_Lib main.c ${SOURCES})
|
||||||
|
|
||||||
#导入库
|
#导入库
|
||||||
add_subdirectory(lib)
|
add_subdirectory(lib)
|
||||||
target_link_libraries(HW_Lib HW_LIB_List HW_LIB_Task HW_LIB_Printf HW_LIB_Utils HW_LIB_Iic HW_LIB_Spi)
|
target_link_libraries(HW_Lib HW_LIB_List HW_LIB_Task HW_LIB_Printf HW_LIB_Utils HW_LIB_Iic HW_LIB_Spi HW_LIB_Key)
|
|
@ -2,7 +2,7 @@
|
||||||
#include "iic.h"
|
#include "iic.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
|
#include "t_iic.h"
|
||||||
uint8_t CLK_Pin(uint8_t l) {
|
uint8_t CLK_Pin(uint8_t l) {
|
||||||
// LOGT("CLK", "P:%d", l);
|
// LOGT("CLK", "P:%d", l);
|
||||||
return l;
|
return l;
|
||||||
|
@ -47,9 +47,9 @@ void Test_iic() {
|
||||||
}
|
}
|
||||||
PRINT_ARRAY(writeData, "%3d", 16);
|
PRINT_ARRAY(writeData, "%3d", 16);
|
||||||
|
|
||||||
foreach(i in writeData) {
|
// foreach(i in writeData) {
|
||||||
writeData[i] = rand() % 200;
|
// writeData[i] = rand() % 200;
|
||||||
}
|
// }
|
||||||
PRINT_ARRAY(writeData, "%3d", 16);
|
PRINT_ARRAY(writeData, "%3d", 16);
|
||||||
Buf_Print("<IIC> TX", writeData, len, 16);
|
Buf_Print("<IIC> TX", writeData, len, 16);
|
||||||
BufPrint("<IIC> TX", writeData, TYPE_T(writeData), len, 16);
|
BufPrint("<IIC> TX", writeData, TYPE_T(writeData), len, 16);
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef HW_LIB_T_KEY_H
|
||||||
|
#define HW_LIB_T_KEY_H
|
||||||
|
|
||||||
|
void Test_Key();
|
||||||
|
|
||||||
|
#endif //HW_LIB_T_KEY_H
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "key.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "tool.h"
|
||||||
|
#include "t_key.h"
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
uint8_t Key_Pin(uint8_t l) {
|
||||||
|
uint8_t k = rand() % 2;
|
||||||
|
// LOGT("KEY", "P:%d-%d", l,k);
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Key_Call(Key_t *key) {
|
||||||
|
switch (key->event) {
|
||||||
|
case KEY_PRESS_DOWN:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "按下事件");
|
||||||
|
break;// 按下事件
|
||||||
|
case KEY_PRESS_UP:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "弹起事件");
|
||||||
|
break;// 弹起事件
|
||||||
|
case KEY_PRESS_REPEAT:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "重复按下事件");
|
||||||
|
break;// 重复按下事件
|
||||||
|
case KEY_SINGLE_CLICK:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "单击事件");
|
||||||
|
break;// 单击事件
|
||||||
|
case KEY_DOUBLE_CLICK:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "双击事件");
|
||||||
|
break;// 双击事件
|
||||||
|
case KEY_LONG_PRESS_START:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "长按开始事件");
|
||||||
|
break;// 长按开始事件
|
||||||
|
case KEY_LONG_PRESS_HOLD:
|
||||||
|
LOGT("KEY", "ID:%d EVENT:%s", key->key_id, "长按保持事件");
|
||||||
|
break;// 长按保持事件
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test_Key() {
|
||||||
|
|
||||||
|
|
||||||
|
Key_t k1, k2;
|
||||||
|
key_init(&k1, Key_Pin, 1, 0);
|
||||||
|
key_init(&k2, Key_Pin, 1, 1);
|
||||||
|
key_attach(&k1, KEY_ALL_EVENT, Key_Call);
|
||||||
|
key_attach(&k2, KEY_ALL_EVENT, Key_Call);
|
||||||
|
key_start(&k1);
|
||||||
|
key_start(&k2);
|
||||||
|
while (1) {
|
||||||
|
// 每5ms调用一次key_ticks函数
|
||||||
|
key_ticks();
|
||||||
|
// Sleep(5); // 使用Windows平台的Sleep函数进行5ms延时
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@ set(LIBRARIES
|
||||||
HW_LIB_Utils src/utils inc/utils
|
HW_LIB_Utils src/utils inc/utils
|
||||||
HW_LIB_Iic src/iic inc/iic
|
HW_LIB_Iic src/iic inc/iic
|
||||||
HW_LIB_Spi src/spi inc/spi
|
HW_LIB_Spi src/spi inc/spi
|
||||||
|
HW_LIB_Key src/key inc/key
|
||||||
)
|
)
|
||||||
|
|
||||||
# 循环浏览库列表以创建它们
|
# 循环浏览库列表以创建它们
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
#ifndef HW_LIB_KEY_H
|
||||||
|
#define HW_LIB_KEY_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define KEY_TICKS_INTERVAL 5 // 定时器间隔时间,单位为毫秒
|
||||||
|
#define DEBOUNCE_TICKS 3 // 按键去抖动计数阈值,最大为7(0 ~ 7)
|
||||||
|
#define SHORT_TICKS (300 / KEY_TICKS_INTERVAL) // 短按阈值,单位为定时器间隔的倍数
|
||||||
|
#define LONG_TICKS (1000 / KEY_TICKS_INTERVAL) // 长按阈值,单位为定时器间隔的倍数
|
||||||
|
#define KEY_STOP_FREE 1 // 按键停止释放状态标识
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct Key_List Key_t; // 定义结构体Key_t为Key_List的别名
|
||||||
|
typedef void (*Key_Callback_t)(Key_t *key); // 定义函数指针类型Key_Callback_t,接受一个Key_t结构体指针参数
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
KEY_PRESS_DOWN = 0, // 按下事件
|
||||||
|
KEY_PRESS_UP, // 弹起事件
|
||||||
|
KEY_PRESS_REPEAT, // 重复按下事件
|
||||||
|
KEY_SINGLE_CLICK, // 单击事件
|
||||||
|
KEY_DOUBLE_CLICK, // 双击事件
|
||||||
|
KEY_LONG_PRESS_START, // 长按开始事件
|
||||||
|
KEY_LONG_PRESS_HOLD, // 长按保持事件
|
||||||
|
number_of_event, // 事件总数
|
||||||
|
KEY_ALL_EVENT, // 所有事件
|
||||||
|
NONE_PRESS // 无按键事件
|
||||||
|
} PressEvent; // 定义枚举类型PressEvent,表示按键事件类型
|
||||||
|
|
||||||
|
struct Key_List {
|
||||||
|
Key_t *next; // 指向下一个按键结构体的指针
|
||||||
|
uint16_t ticks; // 计时器
|
||||||
|
uint8_t repeat: 4; // 按键重复次数,占4位
|
||||||
|
uint8_t event: 4; // 当前按键事件类型,占4位
|
||||||
|
uint8_t state: 3; // 按键状态,占3位
|
||||||
|
uint8_t debounce_cnt: 3; // 按键去抖计数,占3位
|
||||||
|
uint8_t active_level: 1; // 按键激活电平,占1位
|
||||||
|
uint8_t key_level: 1; // 当前按键电平,占1位
|
||||||
|
uint8_t key_id; // 按键ID
|
||||||
|
uint8_t (*hal_key_Level)(uint8_t key_id_); // 函数指针,用于获取按键电平
|
||||||
|
Key_Callback_t cb[number_of_event]; // 按键事件回调函数数组
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化按键模块
|
||||||
|
* @param key: [输入] 指向按键结构体的指针
|
||||||
|
* @param pin_level: [输入] 获取按键电平的回调函数
|
||||||
|
* @param active_level: [输入] 激活电平
|
||||||
|
* @param key_id: [输入] 按键ID
|
||||||
|
* @return void
|
||||||
|
* @example key_init(&my_key, get_pin_level, ACTIVE_HIGH, 1);
|
||||||
|
*/
|
||||||
|
void key_init(Key_t *key, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t key_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 绑定按键事件回调函数
|
||||||
|
* @param key: [输入] 指向按键结构体的指针
|
||||||
|
* @param event: [输入] 按键事件类型
|
||||||
|
* @param cb: [输入] 按键事件回调函数
|
||||||
|
* @return void
|
||||||
|
* @example key_attach(&my_key, PRESS_DOWN, key_press_callback);
|
||||||
|
*/
|
||||||
|
void key_attach(Key_t *key, PressEvent event, Key_Callback_t cb);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取按键当前事件
|
||||||
|
* @param key: [输入] 指向按键结构体的指针
|
||||||
|
* @return 当前按键事件
|
||||||
|
* @example PressEvent current_event = get_key_event(&my_key);
|
||||||
|
*/
|
||||||
|
PressEvent get_key_event(Key_t *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启动按键检测
|
||||||
|
* @param key: [输入] 指向按键结构体的指针
|
||||||
|
* @return 错误码,0表示成功
|
||||||
|
* @example int result = key_start(&my_key);
|
||||||
|
*/
|
||||||
|
int key_start(Key_t *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 停止按键检测
|
||||||
|
* @param key: [输入] 指向按键结构体的指针
|
||||||
|
* @return void
|
||||||
|
* @example key_stop(&my_key);
|
||||||
|
*/
|
||||||
|
void key_stop(Key_t *key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 按键定时处理函数
|
||||||
|
* @return void
|
||||||
|
* @example key_ticks();
|
||||||
|
*/
|
||||||
|
void key_ticks(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif //HW_LIB_KEY_H
|
|
@ -13,8 +13,8 @@ typedef struct List_Node_t { //节点结构
|
||||||
} List_Node_t;
|
} List_Node_t;
|
||||||
|
|
||||||
typedef struct { //链表结构
|
typedef struct { //链表结构
|
||||||
struct List_Node_t *head;
|
List_Node_t *head;
|
||||||
struct List_Node_t *tail;
|
List_Node_t *tail;
|
||||||
long len;
|
long len;
|
||||||
} List_t;
|
} List_t;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef HW_LIB_OLED_H
|
||||||
|
#define HW_LIB_OLED_H
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
// OLED初始化指令数组
|
||||||
|
const uint8_t OLED_Init_Cmd[] = {
|
||||||
|
0xAE, // 关闭显示
|
||||||
|
0xD5, 0x80, // 设置显示时钟分频因子/震荡频率
|
||||||
|
0xA8, 0x3F, // 设置多路复用比
|
||||||
|
0xD3, 0x00, // 设置显示偏移
|
||||||
|
0x40, // 设置起始行
|
||||||
|
0x8D, 0x14, // 启用电荷泵
|
||||||
|
0x20, 0x00, // 设置内存地址模式
|
||||||
|
0xA0, // 设置列地址映射
|
||||||
|
0xC0, // 设置扫描方向
|
||||||
|
0xDA, 0x12, // 设置COM硬件引脚配置
|
||||||
|
0x81, 0xCF, // 设置对比度
|
||||||
|
0xD9, 0xF1, // 设置预充电周期
|
||||||
|
0xDB, 0x40, // 设置VCOMH电压倍率
|
||||||
|
0xA4, // 全局显示开启
|
||||||
|
0xA6, // 设置显示方式
|
||||||
|
0xAF // 打开显示
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif //HW_LIB_OLED_H
|
|
@ -29,36 +29,85 @@ struct TaskList {
|
||||||
void *userdata;
|
void *userdata;
|
||||||
};
|
};
|
||||||
|
|
||||||
//时间基准注册,建议1-10ms的基准
|
/**
|
||||||
|
* @brief 初始化任务模块
|
||||||
|
* @param TicksFunc: [输入] 时间基准函数指针
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskInit(GetPlatformTicks);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskInit(PlatformTicksFunc_t TicksFunc);
|
TaskStatus_t TaskInit(PlatformTicksFunc_t TicksFunc);
|
||||||
|
|
||||||
//创建任务
|
|
||||||
// time:间隔时间
|
/**
|
||||||
// runcnt:执行次数 为-1无限制执行 为0只创建不运行
|
* @brief 创建任务
|
||||||
// callback:回调函数
|
* @param task: [输入/输出] 任务结构体指针
|
||||||
// userdata:用户数据传参
|
* @param time: [输入] 间隔时间
|
||||||
|
* @param runcnt: [输入] 执行次数,-1为无限制执行,0为只创建不运行
|
||||||
|
* @param callback: [输入] 回调函数
|
||||||
|
* @param userdata: [输入] 用户数据传参
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskCreat(&myTask, 100, -1, myCallbackFunc, &myData);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskCreat(Task_t *task, TaskTime_t time, TaskCnt_t runcnt, Task_Callback_t callback, void *userdata);
|
TaskStatus_t TaskCreat(Task_t *task, TaskTime_t time, TaskCnt_t runcnt, Task_Callback_t callback, void *userdata);
|
||||||
|
|
||||||
//添加任务
|
/**
|
||||||
|
* @brief 添加任务
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskAdd(&myTask);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskAdd(Task_t *task);
|
TaskStatus_t TaskAdd(Task_t *task);
|
||||||
|
|
||||||
//删除任务
|
/**
|
||||||
|
* @brief 删除任务
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskDel(&myTask);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskDel(Task_t *task);
|
TaskStatus_t TaskDel(Task_t *task);
|
||||||
|
|
||||||
//重新开始以停止的任务
|
/**
|
||||||
|
* @brief 重新开始停止的任务
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskStart(&myTask);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskStart(Task_t *task);
|
TaskStatus_t TaskStart(Task_t *task);
|
||||||
|
|
||||||
//暂停任务执行
|
/**
|
||||||
|
* @brief 暂停任务执行
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskStop(&myTask);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskStop(Task_t *task);
|
TaskStatus_t TaskStop(Task_t *task);
|
||||||
|
|
||||||
//重设任务执行次数
|
/**
|
||||||
|
* @brief 重设任务执行次数
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @param runcnt: [输入] 新的执行次数
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskSetCnt(&myTask, 5);
|
||||||
|
*/
|
||||||
TaskStatus_t TaskSetCnt(Task_t *task, TaskCnt_t runcnt);
|
TaskStatus_t TaskSetCnt(Task_t *task, TaskCnt_t runcnt);
|
||||||
|
|
||||||
//重设任务间隔时间
|
/**
|
||||||
|
* @brief 重设任务间隔时间
|
||||||
|
* @param task: [输入] 任务结构体指针
|
||||||
|
* @param time: [输入] 新的间隔时间
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskSetTime(&myTask, 50);
|
||||||
|
*/
|
||||||
|
|
||||||
TaskStatus_t TaskSetTime(Task_t *task, TaskTime_t time);
|
TaskStatus_t TaskSetTime(Task_t *task, TaskTime_t time);
|
||||||
|
|
||||||
//任务调度
|
/**
|
||||||
|
* @brief 任务调度
|
||||||
|
* @return TaskStatus_t 返回任务状态
|
||||||
|
* @example TaskRun();
|
||||||
|
*/
|
||||||
TaskStatus_t TaskRun(void);
|
TaskStatus_t TaskRun(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,16 +29,16 @@ typedef union {
|
||||||
u16 u16;
|
u16 u16;
|
||||||
} Data16_t;
|
} Data16_t;
|
||||||
typedef enum { // 定义枚举类型Type_t,包含不同数据类型
|
typedef enum { // 定义枚举类型Type_t,包含不同数据类型
|
||||||
U8, // 无符号8位整数
|
T_U8, // 无符号8位整数
|
||||||
U16, // 无符号16位整数
|
T_U16, // 无符号16位整数
|
||||||
U32, // 无符号32位整数
|
T_U32, // 无符号32位整数
|
||||||
|
|
||||||
CHAR, // 字符
|
T_CHAR, // 字符
|
||||||
SHORT, // 短整数
|
T_SHORT, // 短整数
|
||||||
INT, // 整数
|
T_INT, // 整数
|
||||||
|
|
||||||
FLOAT, // 浮点数
|
T_FLOAT, // 浮点数
|
||||||
DOUBLE, // 双精度浮点数
|
T_DOUBLE, // 双精度浮点数
|
||||||
} Type_t;
|
} Type_t;
|
||||||
|
|
||||||
#define TYPE_T(v) _Generic((v), \
|
#define TYPE_T(v) _Generic((v), \
|
||||||
|
@ -69,7 +69,7 @@ typedef enum { // 定义枚举类型Type_t,包含不同数据类型
|
||||||
|
|
||||||
|
|
||||||
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) // 计算数组的元素个数
|
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0])) // 计算数组的元素个数
|
||||||
#define in , // 定义逗号为in
|
//#define in , // 定义逗号为in
|
||||||
#define _foreach(e, a) for(size_t e = 0; e < ARRAY_SIZE(a); e++) // 实现foreach宏,遍历数组a,e为当前元素下标
|
#define _foreach(e, a) for(size_t e = 0; e < ARRAY_SIZE(a); e++) // 实现foreach宏,遍历数组a,e为当前元素下标
|
||||||
#define foreach(exp) _foreach(exp) // 定义foreach宏,用于遍历数组
|
#define foreach(exp) _foreach(exp) // 定义foreach宏,用于遍历数组
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ float Str2Float(char *str);
|
||||||
**/
|
**/
|
||||||
#define PRINT_ARRAY(arr, fmt, frame) do { \
|
#define PRINT_ARRAY(arr, fmt, frame) do { \
|
||||||
printf("\n"#arr ":\n"); \
|
printf("\n"#arr ":\n"); \
|
||||||
foreach(i in arr) {\
|
for(size_t i = 0; i < ARRAY_SIZE(arr); i++) {\
|
||||||
if(i%frame==0&&i!=0) printf("\n");\
|
if(i%frame==0&&i!=0) printf("\n");\
|
||||||
printf(fmt " ", arr[i]); }\
|
printf(fmt " ", arr[i]); }\
|
||||||
printf("\n"); } while (0)
|
printf("\n"); } while (0)
|
||||||
|
|
|
@ -0,0 +1,170 @@
|
||||||
|
#include <malloc.h>
|
||||||
|
#include "key.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define EVENT_CB(ev) if(key->cb[ev])key->cb[ev](key)
|
||||||
|
#define PRESS_REPEAT_MAX_NUM 15
|
||||||
|
|
||||||
|
|
||||||
|
static Key_t *head_key = NULL;
|
||||||
|
|
||||||
|
static void key_state_switch(Key_t *key);
|
||||||
|
|
||||||
|
|
||||||
|
void key_init(Key_t *key, uint8_t(*pin_level)(uint8_t), uint8_t active_level, uint8_t key_id) {
|
||||||
|
memset(key, 0, sizeof(Key_t));
|
||||||
|
key->event = (uint8_t) NONE_PRESS;
|
||||||
|
key->hal_key_Level = pin_level;
|
||||||
|
key->key_level = !active_level;
|
||||||
|
key->active_level = active_level;
|
||||||
|
key->key_id = key_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void key_attach(Key_t *key, PressEvent event, Key_Callback_t cb) {
|
||||||
|
// 如果事件类型为ALL_EVENT,则将回调函数cb分别赋值给所有事件类型
|
||||||
|
if (event == KEY_ALL_EVENT) {
|
||||||
|
for (uint8_t i = KEY_PRESS_UP; i < number_of_event; i++) {
|
||||||
|
key->cb[i] = cb;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 否则,将回调函数cb赋值给指定的事件类型
|
||||||
|
key->cb[event] = cb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PressEvent get_key_event(Key_t *key) {
|
||||||
|
return (PressEvent) (key->event);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void key_state_switch(Key_t *key) {
|
||||||
|
// 读取按键的GPIO电平
|
||||||
|
uint8_t read_gpio_level = key->hal_key_Level(key->key_id);
|
||||||
|
|
||||||
|
// 如果按键状态大于0,则增加ticks计数
|
||||||
|
if ((key->state) > 0) key->ticks++;
|
||||||
|
|
||||||
|
// 按键去抖动处理
|
||||||
|
if (read_gpio_level != key->key_level) {
|
||||||
|
if (++(key->debounce_cnt) >= DEBOUNCE_TICKS) {
|
||||||
|
key->key_level = read_gpio_level;
|
||||||
|
key->debounce_cnt = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key->debounce_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态机处理按键事件
|
||||||
|
switch (key->state) {
|
||||||
|
case 0:
|
||||||
|
if (key->key_level == key->active_level) {
|
||||||
|
key->event = (uint8_t) KEY_PRESS_DOWN;
|
||||||
|
EVENT_CB(KEY_PRESS_DOWN);
|
||||||
|
key->ticks = 0;
|
||||||
|
key->repeat = 1;
|
||||||
|
key->state = 1;
|
||||||
|
} else {
|
||||||
|
key->event = (uint8_t) NONE_PRESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (key->key_level != key->active_level) {
|
||||||
|
key->event = (uint8_t) KEY_PRESS_UP;
|
||||||
|
EVENT_CB(KEY_PRESS_UP);
|
||||||
|
key->ticks = 0;
|
||||||
|
key->state = 2;
|
||||||
|
} else if (key->ticks > LONG_TICKS) {
|
||||||
|
key->event = (uint8_t) KEY_LONG_PRESS_START;
|
||||||
|
EVENT_CB(KEY_LONG_PRESS_START);
|
||||||
|
key->state = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (key->key_level == key->active_level) {
|
||||||
|
key->event = (uint8_t) KEY_PRESS_DOWN;
|
||||||
|
EVENT_CB(KEY_PRESS_DOWN);
|
||||||
|
if (key->repeat != PRESS_REPEAT_MAX_NUM) {
|
||||||
|
key->repeat++;
|
||||||
|
}
|
||||||
|
EVENT_CB(KEY_PRESS_REPEAT);
|
||||||
|
key->ticks = 0;
|
||||||
|
key->state = 3;
|
||||||
|
} else if (key->ticks > SHORT_TICKS) {
|
||||||
|
if (key->repeat == 1) {
|
||||||
|
key->event = (uint8_t) KEY_SINGLE_CLICK;
|
||||||
|
EVENT_CB(KEY_SINGLE_CLICK);
|
||||||
|
} else if (key->repeat == 2) {
|
||||||
|
key->event = (uint8_t) KEY_DOUBLE_CLICK;
|
||||||
|
EVENT_CB(KEY_DOUBLE_CLICK);
|
||||||
|
}
|
||||||
|
key->state = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (key->key_level != key->active_level) {
|
||||||
|
key->event = (uint8_t) KEY_PRESS_UP;
|
||||||
|
EVENT_CB(KEY_PRESS_UP);
|
||||||
|
if (key->ticks < SHORT_TICKS) {
|
||||||
|
key->ticks = 0;
|
||||||
|
key->state = 2;
|
||||||
|
} else {
|
||||||
|
key->state = 0;
|
||||||
|
}
|
||||||
|
} else if (key->ticks > SHORT_TICKS) {
|
||||||
|
key->state = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
if (key->key_level == key->active_level) {
|
||||||
|
key->event = (uint8_t) KEY_LONG_PRESS_HOLD;
|
||||||
|
EVENT_CB(KEY_LONG_PRESS_HOLD);
|
||||||
|
} else {
|
||||||
|
key->event = (uint8_t) KEY_PRESS_UP;
|
||||||
|
EVENT_CB(KEY_PRESS_UP);
|
||||||
|
key->state = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
key->state = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int key_start(Key_t *key) {
|
||||||
|
Key_t *target = head_key;
|
||||||
|
while (target) {
|
||||||
|
if (target == key) return -1;
|
||||||
|
target = target->next;
|
||||||
|
}
|
||||||
|
key->next = head_key;
|
||||||
|
head_key = key;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_stop(Key_t *key) {
|
||||||
|
Key_t **curr;
|
||||||
|
for (curr = &head_key; *curr;) {
|
||||||
|
Key_t *entry = *curr;
|
||||||
|
if (entry == key) {
|
||||||
|
*curr = entry->next;
|
||||||
|
#if KEY_STOP_FREE
|
||||||
|
free(entry);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
curr = &entry->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_ticks(void) {
|
||||||
|
Key_t *target;
|
||||||
|
for (target = head_key; target; target = target->next) {
|
||||||
|
key_state_switch(target);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,28 +14,28 @@ void BufPrint(char *name, void *buf, Type_t type, unsigned int len, unsigned cha
|
||||||
for (int i = 0; i < len; ++i) {
|
for (int i = 0; i < len; ++i) {
|
||||||
if (i % frame == 0 && i != 0) printf("\n");
|
if (i % frame == 0 && i != 0) printf("\n");
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case U8:
|
case T_U8:
|
||||||
printf("%02X ", *((unsigned char *) buf + i));
|
printf("%02X ", *((unsigned char *) buf + i));
|
||||||
break;
|
break;
|
||||||
case U16:
|
case T_U16:
|
||||||
printf("%04X ", *((unsigned short *) buf + i));
|
printf("%04X ", *((unsigned short *) buf + i));
|
||||||
break;
|
break;
|
||||||
case U32:
|
case T_U32:
|
||||||
printf("%08X ", *((unsigned int *) buf + i));
|
printf("%08X ", *((unsigned int *) buf + i));
|
||||||
break;
|
break;
|
||||||
case CHAR:
|
case T_CHAR:
|
||||||
printf("%c ", *((char *) buf + i));
|
printf("%c ", *((char *) buf + i));
|
||||||
break;
|
break;
|
||||||
case SHORT:
|
case T_SHORT:
|
||||||
printf("%d ", *((short *) buf + i));
|
printf("%d ", *((short *) buf + i));
|
||||||
break;
|
break;
|
||||||
case INT:
|
case T_INT:
|
||||||
printf("%d ", *((int *) buf + i));
|
printf("%d ", *((int *) buf + i));
|
||||||
break;
|
break;
|
||||||
case FLOAT:
|
case T_FLOAT:
|
||||||
printf("%0.2f ", *((float *) buf + i));
|
printf("%0.2f ", *((float *) buf + i));
|
||||||
break;
|
break;
|
||||||
case DOUBLE:
|
case T_DOUBLE:
|
||||||
printf("%0.2f ", *((double *) buf + i));
|
printf("%0.2f ", *((double *) buf + i));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
5
main.c
5
main.c
|
@ -6,6 +6,7 @@
|
||||||
#include "t_task.h"
|
#include "t_task.h"
|
||||||
#include "t_arg.h"
|
#include "t_arg.h"
|
||||||
#include "t_list.h"
|
#include "t_list.h"
|
||||||
|
#include "t_key.h"
|
||||||
#include "tool.h"
|
#include "tool.h"
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
|
@ -23,7 +24,7 @@ int main() {
|
||||||
Test_RunTime("ArgPase", Test_argpase);
|
Test_RunTime("ArgPase", Test_argpase);
|
||||||
Test_RunTime("List", Test_List);
|
Test_RunTime("List", Test_List);
|
||||||
Test_RunTime("Queue", Test_Queue);
|
Test_RunTime("Queue", Test_Queue);
|
||||||
Test_RunTime("Task", Test_task);
|
// Test_RunTime("Task", Test_task);
|
||||||
|
Test_RunTime("Key", Test_Key);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue