通过 GPIO 监听按键

button.h

#ifndef __BUTTON_H
#define __BUTTON_H

#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"

#define BUTTON_TYPE_NONE            0
#define BUTTON_TYPE_SHORT           1
#define BUTTON_TYPE_LONG            2

void button_init(void);
uint8_t button_wait_action(void);

#endif

button.c

#include "button.h"

#define GPIO_INPUT_BOOT             9
#define GPIO_INPUT_PIN              (1ULL << GPIO_INPUT_BOOT)
#define ESP_INTR_FLAG_DEFAULT       0

static const char *TAG = "BUTTON";

QueueHandle_t button_evt_queue = NULL;

/**
 * @brief 中断回调函数
 */
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    uint32_t gpio_num = (uint32_t)arg;
    xQueueSendFromISR(button_evt_queue, &gpio_num, &xHigherPriorityTaskWoken);
    if (xHigherPriorityTaskWoken)
    {
        portYIELD_FROM_ISR();
    }
}

/**
 * @brief 等待事件
 */
uint8_t button_wait_action(void)
{
    uint32_t io_num;
    static uint32_t tickCount;

    if (xQueueReceive(button_evt_queue, &io_num, portMAX_DELAY))
    {
        ESP_LOGI(TAG, "GPIO[%ld] event, level: %d", io_num, gpio_get_level(io_num));
        if (gpio_get_level(io_num) == 0)// 低电平
        {
            tickCount = xTaskGetTickCount();
        }
        else if (gpio_get_level(io_num) == 1)// 高电平
        {
            if (xTaskGetTickCount() > tickCount + pdMS_TO_TICKS(3000))
            {
                return BUTTON_TYPE_LONG;
            }
            else
            {
                return BUTTON_TYPE_SHORT;
            }
        }
    }
    return BUTTON_TYPE_NONE;
}

/**
 * @brief 初始化
 */
void button_init(void)
{
    gpio_config_t io_config = {
        .pin_bit_mask = GPIO_INPUT_PIN,
        .mode = GPIO_MODE_INPUT,
        .pull_up_en = 1,// pull-up
        .intr_type = GPIO_INTR_ANYEDGE,// both rising and falling edge
    };
    gpio_config(&io_config);

    // Install ISR handler service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    gpio_isr_handler_add(GPIO_INPUT_BOOT, gpio_isr_handler, (void*)GPIO_INPUT_BOOT);

    button_evt_queue = xQueueCreate(10, sizeof(uint32_t));
}
posted on 2025-09-27 14:35  星辰河岳  阅读(17)  评论(0)    收藏  举报