当前位置: 首页 > article >正文

【ESP32】ESP-IDF开发 | 中断矩阵+按键输入中断例程

1. 简介

        ESP32的中断是十分灵活的,依靠中断矩阵,ESP32可以将任一外部中断源单独分配到每个 CPU的任一外部中断上。

        ESP32总共有71个外部中断源每个CPU可以链接26个外部中断源,因此总共可以生成52个外部中断(双核)。 但是外部中断源中有4个是不能任意分配的,只能分配给指定的CPU,像上图的PRO_CPU或APP_CPU。

        ESP32的每个CPU有32个中断,其中编号6、7、11、15、16、29为内部中断,其余都属于外部中断。具体的外部中断源和内部中断可以查看官方的参考手册。

2. 例程

        例程中实现一个按键检测,只不过采用中断的方式去判断。

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

#define TAG "app"

static SemaphoreHandle_t sem;

static void IRAM_ATTR gpio_isr_fn(void *args)
{
    if (sem) {
        /* 释放信号量 */
        xSemaphoreGiveFromISR(sem, NULL);
    }
}

void app_main()
{
    gpio_config_t gpio_cfg = {0};

    gpio_cfg.mode = GPIO_MODE_INPUT;
    gpio_cfg.pull_down_en = GPIO_PULLDOWN_DISABLE;
    gpio_cfg.pull_up_en = GPIO_PULLUP_ENABLE;  // 上拉
    gpio_cfg.intr_type = GPIO_INTR_POSEDGE;  // 上升沿触发
    gpio_cfg.pin_bit_mask = (1 << GPIO_NUM_0);
    /* 初始化GPIO */
    gpio_config(&gpio_cfg);
    /* 注册二值信号量 */
    vSemaphoreCreateBinary(sem);
    xSemaphoreTake(sem, 0);
    /* 注册中断处理函数 */
    gpio_install_isr_service(0);
    gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_fn, NULL);

    while (1) {
        /* 等待信号量 */
        if (pdTRUE == xSemaphoreTake(sem, portMAX_DELAY)) {
            ESP_LOGI(TAG, "Key pressed");
        }
    }
}

         我使用的按键是连接到IO0上的,带外部上拉;因此GPIO设置成上升沿中断,这样当释放按键的时候才会触发中断。

        使用gpio_install_isr_service函数注册GPIO的中断服务,可以传一个注册标志,一般保持默认,即0;接下来就可以使用gpio_isr_handler_add向服务注册中断处理函数,传入管脚号、处理函数和处理函数的参数。中断处理函数可以加一个IRAM_ATTR标志,这样这个函数会被放到内部SDRAM中运行,可以提高运行速度,凡是中断处理函数都可以考虑加这个标志。

        以往为了调试我们喜欢在中断处理函数中调用printf,原则上是不允许的,但对于STM32单片机来说没啥影响;ESP32的话就千万不能这样写,会导致系统崩溃。所以这里我使用了二值信号量去实现,在中断处理函数中去释放信号量,在主循环中等待这个信号量,如果获取到了信号量才去打印log。

 


http://www.kler.cn/news/308341.html

相关文章:

  • 发送成绩的app或小程序推荐
  • PTrade量化服务器连接openapi的地址、key等配置涉及哪些文件?
  • 【学习笔记】SSL密码套件之哈希
  • 【目标检测】labelimg图像标注软件的使用流程
  • 清华镜像源的使用说明
  • 文心一言 VS 讯飞星火 VS chatgpt (349)-- 算法导论23.2 8题
  • AI教你学Python :详解Python元组与集合、字典基础和字符串操作(补充)
  • JavaSE:8、包装类
  • seafaring寻找漏洞
  • 算法入门-贪心1
  • 【React】MobX
  • CI/CD持续集成和持续交付(git工具、gitlab代码仓库、jenkins)
  • DL/T645-2007 通信库(C#版本)
  • 裸金属服务器怎么实现算力共享,裸金属服务器提供者怎么做,租户怎样使用,共享平台需要搭建什么
  • C++11新增特性:lambda表达式、function包装器、bind绑定
  • 在Windows系统中管理苹果磁盘实用工具-使用磁盘,读取磁盘中的文件-供大家学习研究参考
  • 深入解析代理模式:静态代理、JDK 动态代理和 CGLIB 的全方位对比!
  • 开源模型应用落地-qwen模型小试-调用Qwen2-VL-7B-Instruct-更清晰地看世界(一)
  • 魔方财务安装指南
  • Qt6编译达梦8数据库驱动插件
  • 92、K8s之ingress下集
  • 遍历指定的目录a中的所有子目录及所有文件os.walk(root_dir)
  • Java进阶13讲__补充2/2
  • 初始爬虫6
  • PostgreSQL15.x安装教程
  • Vert.x初探
  • react native(expo)选择图片/视频并上传阿里云oss
  • Java数据存储结构——二叉查找树
  • 在linux注册服务并开机启动springboot程序
  • 使用canal.deployer-1.1.7和canal.adapter-1.1.7实现mysql数据同步