ESP32学习-按键中断

前提知识:freertos消息队列

1.使用流程

1.GPIO配置

2.创建消息队列

3.创建消息队列数据输入线程任务

4.使能中断

5.添加中断处理函数

2.代码示例

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

static QueueHandle_t gpio_evt_queue = NULL;  // 定义队列句柄

// GPIO中断服务函数
static void IRAM_ATTR gpio_isr_handler(void* arg) 
{
    uint32_t gpio_num = (uint32_t) arg;  // 获取入口参数
    xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); // 把入口参数gpio_num值发送到队列钟,NULL表示队列满时返回错误结束
}

// GPIO任务函数,获取队列gpio_evt_queue最老的数据,并输出,队列为空时一直等待
static void gpio_task_example(void* arg)
{
    uint32_t io_num; // 定义变量 表示哪个GPIO
    for(;;) {
        if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {  // 获取队列的值放到io_num变量中,portMAX_DELAY表示为空时一直等待
            printf("GPIO[%"PRIu32"] intr, val: %d\n", io_num, gpio_get_level(io_num)); // 打印相关内容
        }
    }
}

void app_main(void)
{
    // 1.GPIO参数配置
    gpio_config_t io0_conf = {
        .intr_type = GPIO_INTR_NEGEDGE, // 下降沿中断
        .mode = GPIO_MODE_INPUT, // 输入模式
        .pin_bit_mask = 1<

3.问题

1.IRAM_ATTR作用

IRAM_ATTR 是 ESP-IDF 中的一个函数属性宏,全称是 "Instruction RAM Attribute",用于告诉编译器 将该函数放入 ESP32 的 IRAM(指令 RAM)中执行,而不是默认的 flash。

ESP32 正常情况下大多数代码是从 Flash(外部 SPI Flash)中运行的。但当发生中断时,如果中断服务函数(ISR)所在代码段仍在 Flash 中,而此时恰好 Flash 被其他操作占用(比如写 Flash 或 WiFi 使用 SPI Flash),会导致中断函数无法及时执行,从而造成 系统崩溃或响应延迟

4.总结

1.esp32引脚不分组(stm32引脚分为ABCD等多组)

2.esp32所有中断共用一个中断源,所以gpio_install_isr_service使能一次中断就行了,stm32不同引脚需要使能对应的中断。因此ESP32也不能对不同引脚配置不同硬件中断优先级(可通过软件实现不同中断优先级)

你可能感兴趣的:(学习)