ESP32使用SDK开发,用GPIO21和GPIO22作为两个按键的输入,其中GPIO21低电平触发中断,GPIO22高电平触发中断的代码怎么写
时间: 2024-04-29 15:25:54 浏览: 7
以下是ESP32使用SDK开发,使用GPIO21和GPIO22作为两个按键输入,其中GPIO21低电平触发中断,GPIO22高电平触发中断的代码示例:
```c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#define GPIO_INPUT_PIN_SEL ((1ULL<<21) | (1ULL<<22)) //GPIO21和GPIO22作为输入
#define ESP_INTR_FLAG_DEFAULT 0
static xQueueHandle gpio_evt_queue = NULL;
static void IRAM_ATTR gpio_isr_handler(void* arg)
{
uint32_t gpio_num = (uint32_t) arg;
xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);
}
static void gpio_task_example(void* arg)
{
uint32_t io_num;
for(;;) {
if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {
if(io_num == 21) {
printf("GPIO21 button pressed\n");
} else if(io_num == 22) {
printf("GPIO22 button pressed\n");
}
}
}
}
void app_main()
{
gpio_config_t io_conf;
//配置GPIO21作为低电平触发中断
io_conf.intr_type = GPIO_INTR_NEGEDGE;
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//配置GPIO22作为高电平触发中断
io_conf.intr_type = GPIO_INTR_POSEDGE;
io_conf.pin_bit_mask = GPIO_INPUT_PIN_SEL;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pull_up_en = 1;
gpio_config(&io_conf);
//创建GPIO事件队列
gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));
//安装GPIO21中断服务程序
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
gpio_isr_handler_add(21, gpio_isr_handler, (void*) 21);
//安装GPIO22中断服务程序
gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);
gpio_isr_handler_add(22, gpio_isr_handler, (void*) 22);
//创建GPIO任务
xTaskCreate(gpio_task_example, "gpio_task_example", 2048, NULL, 10, NULL);
}
```
在以上示例代码中,使用了ESP32的GPIO API和FreeRTOS API来实现GPIO的中断处理和任务处理。首先,定义了GPIO21和GPIO22作为输入,并设置了它们的中断触发方式为低电平触发和高电平触发,使用xQueueCreate函数创建了一个GPIO事件队列,用来接收GPIO中断事件。接着,安装了GPIO21和GPIO22的中断服务程序,使用gpio_isr_handler_add函数将GPIO21和GPIO22的中断服务程序添加到中断处理程序中,并指定了中断的优先级。最后,创建了一个GPIO任务,该任务接收GPIO事件队列中的事件,并根据事件的GPIO引脚号来判断是哪个按键被按下。
需要注意的是,由于ESP32的GPIO中断处理程序是在中断处理上下文中运行的,因此需要使用IRAM_ATTR关键字声明中断处理程序,以确保其在RAM中运行,而不是在闪存中运行。