esp32学习之按键检测gpio中断

esp32学习之gpio中断

  • 前言
  • 流程
    • 选定gpio
    • gpio配置
    • 设置回调函数
    • 注册中断处理程序

前言

最近在做一个按键检测,按键检测有两种方法,一种是轮询法,即在rtos中建立一个任务,然后在死循环中判断按键状态,还有一种方式是使用中断,注册一个事件,事件触发后,会向RTOS队列写入数据。
在官方示例examples\peripherals\gpio中有相关代码

流程

选定gpio

首先选定gpio,由于我使用4个按键,故需要四个gpio

#define INPUT_UP     34
#define INPUT_LEFT   35
#define INPUT_RIGHT  32
#define INPUT_DOWN    33

#define GPIO_INPUT_PIN_SEL  ((1ULL<//选定gpio
#define ESP_INTR_FLAG_DEFAULT 0//设置一个flag标志位
static xQueueHandle gpio_evt_queue = NULL;//消息队列

gpio配置

首先初始化gpio结构体 gpio_config_t io_conf;
然后配置触发类型 io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
一共有一下类型

typedef enum {
    GPIO_PIN_INTR_DISABLE = 0,//不使能
    GPIO_PIN_INTR_POSEDGE = 1,//上升沿
    GPIO_PIN_INTR_NEGEDGE = 2,//下降沿
    GPIO_PIN_INTR_ANYEDGE = 3,//任何变化
    GPIO_PIN_INTR_LOLEVEL = 4,//低电平触发
    GPIO_PIN_INTR_HILEVEL = 5//高电平触发
} GPIO_INT_TYPE;

由于我将按键一端接在3.3v,所以这里选择下降沿触发。
然后选择io口

io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;

然后设置模式,由于是下降沿触发,故平常应该io口上拉,使能并配置

io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);

设置回调函数

首先初始化队列,然后创建一个接受函数

 gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
    start gpio task
 xTaskCreate(anjian, "get down", 2048, NULL, 10, NULL);

在接受函数中读取队列信息

static void anjian(void* arg)
{
    uint32_t io_num;
    for(;;) {
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
            printf("GPIO[%d] intr, val: %d\n", io_num, gpio_get_level(io_num));
        }
    }
}

注册中断处理程序

注册中断函数,并将按键触发加入中断函数

   gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
    gpio_isr_handler_add(INPUT_UP, gpio_isr_handler, (void*) INPUT_UP);
    gpio_isr_handler_add(INPUT_DOWN, gpio_isr_handler, (void*) INPUT_DOWN);
    gpio_isr_handler_add(INPUT_LEFT, gpio_isr_handler, (void*) INPUT_LEFT);
    gpio_isr_handler_add(INPUT_RIGHT, gpio_isr_handler, (void*) INPUT_RIGHT);

按键触发后将进入gpio_isr_handler回调函数中,然后在中断函数中将按键标号写入队列。

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}

然后就是在之前的按键函数中从队列中读取按键信息。

你可能感兴趣的:(esp32学习之按键检测gpio中断)