目录

工欲善其事

实践出真知

活跃标签: linux java mysql 待分类 js springboot win10 电路 vue macOS nginx esp32 windows git docker idea maven esp8266 python Arduino

存档:

[ESP-IDF] GPIO端口中断

esp32 中断demo如下:

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"

const gpio_num_t gpio01 = 18;
const gpio_num_t gpio02 = 17;

static bool sta = true;

static QueueHandle_t gpioEventQueue = NULL;

static void IRAM_ATTR intrHandler(void* arg) {
    uint32_t gpio_num = (uint32_t)arg;
    xQueueSendFromISR(gpioEventQueue, &gpio_num, NULL);
}
static void gpioTaskExample(void* arg) {
    int ioNum = (int)arg;
    while (true) {
        if (xQueueReceive(gpioEventQueue, &ioNum, portMAX_DELAY)) {
            int a = gpio_get_level(ioNum);
            if (a == 1) {
                sta = !sta;
                printf("GPIO[%d] intrrupted, level: %d\n", ioNum, gpio_get_level(ioNum));
            }


        }
    }

}

void app_main(void) {

    // gpio_config_t gpio18 = {
    //     .pin_bit_mask = 1ull << 18,
    //     .mode = GPIO_MODE_INPUT_OUTPUT,
    //     .intr_type = GPIO_INTR_ANYEDGE,
    //     .pull_down_en = 1,
    // };
    // gpio_config(&gpio18);

    // 设置输入模式
    gpio_set_direction(gpio01, GPIO_MODE_INPUT);
    // GPIO设置中断触发类型
    gpio_set_intr_type(gpio01, GPIO_INTR_ANYEDGE);
    // 下降沿监听
    gpio_pulldown_en(gpio01);
    // 设置输出高电平
    gpio_set_level(gpio01, 1);

    gpio_set_direction(gpio02, GPIO_MODE_OUTPUT);
    gpio_set_level(gpio02, 1);

    // 创建一个新的队列实例,并返回一个句柄,通过该句柄可以引用新队列。
    gpioEventQueue = xQueueCreate(10, sizeof(uint32_t));
    // 创建一个新任务并将其添加到准备运行的任务列表中。
    xTaskCreate(gpioTaskExample, "ExampleTask", 2048, NULL, 10, NULL);

    /*
    安装 GPIO 驱动程序的 ETS_GPIO_INTR_SOURCE ISR 处理程序服务,该服务允许每个引脚的 GPIO 中断处理程序。
    此函数与 gpio_isr_register() 不兼容 - 如果使用该函数,则为所有 GPIO 中断注册单个全局 ISR。
    如果使用此函数,则 ISR 服务将提供全局 GPIO ISR,并通过 gpio_isr_handler_add() 函数注册单个引脚处理程序。
    */
    gpio_install_isr_service(0);
    /*
    为相应的 GPIO 引脚添加 ISR 处理程序。
    使用 gpio_install_isr_service() 安装驱动程序的 GPIO ISR 处理程序服务后调用此函数。
    引脚 ISR 处理程序不再需要使用 IRAM_ATTR 声明,除非在 gpio_install_isr_service() 中分配 ISR 时传递 ESP_INTR_FLAG_IRAM 标志。
    此 ISR 处理程序将从 ISR 调用。因此,存在堆栈大小限制(可在 menuconfig 中配置为“ISR 堆栈大小”)。与全局 GPIO 中断处理程序相比,此限制较小,因为间接级别更高。
    */
    gpio_isr_handler_add(gpio01, intrHandler, (void*)18);
    printf("finished\n");
    while (1) {
        printf("mian function is running!%d \n", sta);
        gpio_set_level(gpio02, sta);
        // 延时
        vTaskDelay(750 / portTICK_PERIOD_MS);
    }
}

ESP32 GPIO 可能无法正确触发中断。

描述:
  如果多个 GPIO 管脚配置了沿中断,则 ESP32 硬件可能⽆法正确触发中断。
  
解决方案原文:

在这里插入图片描述


标题:[ESP-IDF] GPIO端口中断
作者:llilei
地址:http://solo.llilei.work/articles/2024/02/11/1707654386034.html