这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » MCU » 【MAX32625PICO开发板】高效按键处理

共4条 1/1 1 跳转至

【MAX32625PICO开发板】高效按键处理

工程师
2025-06-02 17:11:46     打赏

【前言】

如果需要通过按键来实现用户的交互,就需要创建一个高效的按键处理。这一篇我在FreeRTOS的多任务系统下,实现一个基于状态机的按键处理程序。

【实现目标】

在MAX32625MBED开发板中,有两个按键SW2与SW3,需要实现按下按键并松开后,在串口打印出按键按下的信息。

【原理图】

在MAX32625MBED的原理图中,两个按键分别接到了P2.2与P2.3中,并有上拉电阻,在松开状态时,为高电平。

image.png

image.png

【注】 在MAX32625PICO开发板上是没有这两个物理按键的,如果实现需要自行拉入两个按键。

【程序代码】

1、在工程中添加两个文件,分别为key.c/h,key.c代码如下:

#include "key.h"
#include "gpio.h"
#include "max32625.h"
#include "FreeRTOS.h"
#include "task.h"
#include "stdio.h"

// 按键引脚定义
#define SW2_PIN PIN_2
#define SW2_PORT PORT_2
#define SW3_PIN PIN_3
#define SW3_PORT PORT_2

// 按键状态机
typedef enum
{
    KEY_STATE_IDLE,
    KEY_STATE_PRESSED,
    KEY_STATE_RELEASED
} key_state_t;

static key_state_t sw2_state = KEY_STATE_IDLE;
static key_state_t sw3_state = KEY_STATE_IDLE;

// 按键消抖时间(毫秒)
#define DEBOUNCE_TIME_MS 20

gpio_cfg_t sw2_cfg = {SW2_PORT, SW2_PIN, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP};
gpio_cfg_t sw3_cfg = {SW3_PORT, SW3_PIN, GPIO_FUNC_GPIO, GPIO_PAD_INPUT_PULLUP};

void key_init(void)
{
    GPIO_Config(&sw2_cfg);
    GPIO_Config(&sw3_cfg);
}

// 获取按键单击状态(非阻塞式)
key_event_t key_get_click(void)
{
    static TickType_t last_sw2_time = 0;
    static TickType_t last_sw3_time = 0;
    static uint8_t sw2_last = 1;
    static uint8_t sw3_last = 1;

    uint8_t sw2_current = GPIO_InGet(&sw2_cfg);
    uint8_t sw3_current = GPIO_InGet(&sw3_cfg);
    TickType_t now = xTaskGetTickCount();
    key_event_t event = KEY_NONE;

    // SW2状态处理
    if (sw2_current != sw2_last)
    {
        if ((now - last_sw2_time) > pdMS_TO_TICKS(DEBOUNCE_TIME_MS))
        {
            if (sw2_current == 0)
            { // 按下
                sw2_state = KEY_STATE_PRESSED;
            }
            else
            { // 松开
                if (sw2_state == KEY_STATE_PRESSED)
                {
                    sw2_state = KEY_STATE_RELEASED;
                    event = KEY_SW2_CLICK;
                }
            }
            last_sw2_time = now;
        }
        sw2_last = sw2_current;
    }

    // SW3状态处理
    if (sw3_current != sw3_last)
    {
        if ((now - last_sw3_time) > pdMS_TO_TICKS(DEBOUNCE_TIME_MS))
        {
            if (sw3_current == 0)
            { // 按下
                sw3_state = KEY_STATE_PRESSED;
            }
            else
            { // 松开
                if (sw3_state == KEY_STATE_PRESSED)
                {
                    sw3_state = KEY_STATE_RELEASED;
                    event = KEY_SW3_CLICK;
                }
            }
            last_sw3_time = now;
        }
        sw3_last = sw3_current;
    }

    return event;
}

// 示例使用(在任务中调用)
void vTaskKeyScan(void *pvParameters)
{
    key_init();

    while (1)
    {
        key_event_t event = key_get_click();

        switch (event)
        {
        case KEY_SW2_CLICK:
            printf("SW2 Clicked\n");
            break;
        case KEY_SW3_CLICK:
            printf("SW3 Clicked\n");
            break;
        default:
            break;
        }

        vTaskDelay(pdMS_TO_TICKS(10)); // 10ms扫描间隔
    }
}

// 创建任务函数
void vCreateKeyScanTask(void)
{
    xTaskCreate(vTaskKeyScan, "KeyScanTask", 512, NULL, tskIDLE_PRIORITY + 1, NULL);
}

key.h

#ifndef __KEY_H
#define __KEY_H

typedef enum
{
    KEY_NONE,
    KEY_SW2_CLICK,
    KEY_SW3_CLICK
} key_event_t;

void key_init(void);
key_event_t key_get_click(void);
void vCreateKeyScanTask(void);
#endif

最后在main.c的任务创建中调用vCreateKeyScanTask。就完成任务的创建。

【实现效果】

分别按下两个按键,在串口中输出内容如下:

image.png

【总结】

结合freertos的多任务操作系统,实现多按键的状态获取,可以为今后的用户交互做好准备。




关键词: MAX32625PICO     按键     FreeRTOS    

院士
2025-06-04 09:44:26     打赏
2楼

看代码像是阻塞式的检测按键。效率上面应该是低效的吧


工程师
2025-06-04 20:35:51     打赏
3楼

image.png

使用的是非常阻塞的延迟,不是阻塞式呢。


院士
2025-06-05 09:07:40     打赏
4楼

明白了。

使用RTOS之后,延时就显得灵活了


共4条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]