freertos开发空气检测仪之输入子系统按键驱动测试
在之前的文章中,写了一些代码,本文继续沿用之前的代码,进行输入子系统之按键测试。
硬件原理图

设计思路:找到自己积累的按键驱动代码,进行移植即可,移植过程略。设计一些c函数,代码片段如下:
扫描任务
c
/*
*********************************************************************************************************
* 函 数 名: key_scan_task
* 功能说明: 按键扫描任务,每10ms调用一次bsp_KeyScan10ms
* 形 参: pvParameters - 任务参数
* 返 回 值: 无
*********************************************************************************************************
*/
static void key_scan_task(void *pvParameters)
{
while (1)
{
/* 每10ms调用一次按键扫描函数 */
bsp_KeyScan10ms();
/* 处理按键事件 */
key_event_process();
/* 延时10ms */
vTaskDelay(10);
}
}
按键处理部分
/*
*********************************************************************************************************
* 函 数 名: key_event_process
* 功能说明: 处理按键事件,转换为InputEvent并发送到队列
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void key_event_process(void)
{
uint8_t key_code;
InputEvent event;
/* 获取按键事件 */
key_code = bsp_GetKey();
if (key_code != KEY_NONE)
{
/* 填充InputEvent结构 */
event.time = xTaskGetTickCount();
event.eType = INPUT_EVENT_TYPE_KEY;
/* 根据按键代码解析按键信息 */
switch (key_code)
{
case KEY_1_DOWN:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_PRESSED;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 0;
break;
case KEY_1_UP:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_RELEASED;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 1;
break;
case KEY_1_LONG_DOWN:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_LONG_PRESS;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 0;
break;
case KEY_1_LONG_UP:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_LONG_RELEASED;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 0;
break;
case KEY_1_AUTO_UP:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_REPEAT;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 0;
break;
case KEY_1_DB_UP:
event.data.key.iKey = 1;
event.data.key.eState = KEY_STATE_DOUBLE_CLICK;
event.data.key.iTime = xTaskGetTickCount();
event.data.key.iClickCount = 2;
break;
default:
return;
}
/* 发送事件到队列 */
xQueueSend(xKeyQueue, &event, 0);
}
}
接收队列
c
/*
*********************************************************************************************************
* 函 数 名: input_test_task
* 功能说明: 按键测试任务
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
static void input_test_task(void *pvParameters)
{
InputEvent event;
while (1)
{
/* 从队列中获取按键事件 */
if (xQueueReceive(xKeyQueue, &event, portMAX_DELAY) == pdTRUE)
{
/* 打印按键事件信息 */
DBG_log("[INFO] Key event: type=%d, key=%d, state=%d, iTime=%d,
click_count=%d\n",
event.eType, event.data.key.iKey, event.data.key.eState,
event.data.key.iTime, event.data.key.iClickCount);
}
}
}
函数入口
c
/*
*********************************************************************************************************
* 函 数 名: input_test_start
* 功能说明: 启动按键扫描任务
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void input_test_start(void)
{
BaseType_t xReturn = pdPASS;
/* 初始化按键测试 */
input_test_init();
/* 创建按键扫描任务 */
xReturn = xTaskCreate(
(TaskFunction_t)key_scan_task,
(const char *)"key_scan",
(uint16_t)128,
(void *)NULL,
(UBaseType_t)1,
(TaskHandle_t *)&xKeyScanTask
);
if (xReturn != pdPASS)
{
DBG_log("[ERROR] Create key scan task failed\n");
return;
}
/* 创建按键测试任务 */
xReturn = xTaskCreate(
(TaskFunction_t)input_test_task,
(const char *)"input_test",
(uint16_t)128,
(void *)NULL,
(UBaseType_t)2,
(TaskHandle_t *)&xInputTestTask
);
if (xReturn != pdPASS)
{
DBG_log("[ERROR] Create input test task failed\n");
return;
}
DBG_log("[INFO] Input test started\n");
}
实验结果

可以看到,按键驱动可以正常驱动起来,日志比较正常。
总结
本文设计了一个按键扫描任务,将按键的键值放进队列中,在接收队列中拿出来,进行处理,算是一个freertos的队列实战。本文实战代码由AI完成,AI还是很强大的,写一些明确代码还是很好用的,有AI的介入,省事很多。本文完!!