ESP-C3入门24. 使用中断监控GPIO口

ESP-C3入门24. 使用中断监控GPIO口

  • 一、ESP IDF中断概念
    • 1. 一些关键概念:
    • 2. GPIO 触发方式
  • 二、ESP32 IDF 使用中断来处理 GPIO 输入的步骤
    • 1. 引入 ESP32 IDF 头文件:
    • 2. 配置 GPIO 引脚:
    • 3. 定义中断处理函数:
    • 4. 初始化 GPIO 引脚
    • 5. 处理中断事件:
    • 6. 清除中断:
  • 三、中断与任务间传值
    • 1. 消息队列
    • 2. 函数 `xQueueSendFromISR`
  • 四、完整示例

一、ESP IDF中断概念

在 ESP32 IDF(Espressif IoT Development Framework)中,中断是一种用于异步事件处理的重要机制。中断允许微控制器或微处理器在执行主线程代码的同时响应外部事件,而不必等待事件的发生。ESP32 IDF 使用中断来处理各种事件,包括外部硬件触发的事件、定时器事件、通信事件等。

1. 一些关键概念:

  1. 中断源

    • 中断源是指可以触发中断的事件或条件,例如外部硬件引脚的状态变化、定时器溢出、外部设备的通信完成等。
    • ESP32 支持多个不同的中断源,每个中断源都有一个唯一的标识符。
  2. 中断处理函数

    • 中断处理函数是一个特殊的函数,用于处理特定中断源触发的事件。每个中断源通常都有一个与之关联的中断处理函数。
    • 中断处理函数是独立于主程序的,当中断发生时,控制权会立即转移到相应的中断处理函数中执行。
    • 在 ESP32 IDF 中,中断处理函数通常是一个带有 IRAM_ATTR 属性修饰符的函数,以确保它存储在内部 RAM 中,以减少延迟。
  3. 中断控制器

    • ESP32 中有一个中断控制器(Interrupt Controller),负责管理和分发中断请求。它可以将中断请求分派给相应的中断处理函数。
    • 中断控制器允许启用或禁用特定的中断源,以及设置中断优先级。
  4. 中断优先级

    • 中断可以有不同的优先级,允许指定哪个中断应该在发生多个中断时首先得到处理。
    • ESP32 支持优先级抢占,即当一个高优先级的中断正在执行时,可以打断低优先级的中断处理函数。
  5. 中断屏蔽

    • 中断屏蔽是一种机制,可以在需要时禁止或启用中断。这对于防止在关键代码部分中断发生非常有用。
    • ESP32 具有中断屏蔽和解除中断屏蔽的指令,允许在代码中显式地控制中断的启用和禁用。
  6. 中断服务例程

    • 中断服务例程(Interrupt Service Routine,ISR)是指中断处理函数的一般术语,它是用于响应中断的特殊函数。
  7. 中断处理流程

    • 当中断源触发时,ESP32 中断控制器将控制权转移到相应的中断处理函数。
    • 中断处理函数执行完毕后,控制权返回到主程序。
    • 可以在中断处理函数中执行与中断源相关的操作,例如读取传感器数据、处理通信数据、更新定时器计数器等。

2. GPIO 触发方式

函数 gpio_set_intr_type(GPIO_PIN, gpio_int_type_t); 用来设置触发方式, gpio_int_type_t是个枚举值,有以下常量:

  • GPIO_INTR_POSEDGE:上升沿触发,电平由低变高时触发中断。
  • GPIO_INTR_NEGEDGE:下降沿触发,电平由高变低时触发中断。
  • GPIO_INTR_ANYEDGE:任何边沿触发,电平变化时都触发中断。
  • GPIO_INTR_LOW_LEVEL:低电平触发,只有当电平为低电平时触发中断。
  • GPIO_INTR_HIGH_LEVEL:高电平触发,只有当电平为高电平时触发中断。

二、ESP32 IDF 使用中断来处理 GPIO 输入的步骤

1. 引入 ESP32 IDF 头文件:

这些头文件包含了中断和 GPIO 相关的定义和函数。

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

2. 配置 GPIO 引脚:

在代码中配置要使用的 GPIO 引脚,设置其模式为输入,并为该引脚分配一个中断号。

   #define GPIO_PIN            GPIO_NUM_2 // 选择要使用的 GPIO 引脚#define GPIO_INTR           GPIO_INTR_POSEDGE // 触发中断的边沿(上升沿触发)

3. 定义中断处理函数:

创建一个用于处理 GPIO 中断的函数。该函数应该符合以下形式:

   void IRAM_ATTR gpio_isr_handler(void* arg) {// 处理中断事件的代码}

这里的 IRAM_ATTR 属性用于将中断处理函数存储在内部 RAM 中,以减少延迟。

4. 初始化 GPIO 引脚

app_main() 函数或其他入口函数中,初始化 GPIO 引脚,将它们配置为输入模式,并设置中断处理程序。你还需要创建一个用于安装中断服务的句柄。

   void app_main() {// 配置 GPIO 引脚gpio_pad_select_gpio(GPIO_PIN);gpio_set_direction(GPIO_PIN, GPIO_MODE_INPUT);gpio_set_intr_type(GPIO_PIN, GPIO_INTR);// 创建中断句柄gpio_install_isr_service(0);// 注册中断处理函数gpio_isr_handler_add(GPIO_PIN, gpio_isr_handler, NULL);// 主任务继续执行其他操作while (1) {// 在这里执行其他任务vTaskDelay(1000 / portTICK_RATE_MS);}}

5. 处理中断事件:

在中断处理函数 gpio_isr_handler 中,编写处理 GPIO 中断事件的代码。你可以在函数内部执行你需要的操作,例如读取传感器数据、更新状态等。

6. 清除中断:

当完成中断事件的处理后,你可以清除中断标志以准备接收下一个中断事件。

   gpio_intr_enable(GPIO_PIN);

当 GPIO 引脚上的电平发生上升沿(或可以根据配置是下降沿)时,中断处理函数 gpio_isr_handler 将会执行,程序可以在其中执行特定的操作。这使得程序能够实时响应 GPIO 引脚状态的变化,例如传感器的触发、按钮的按下等事件。

中断处理程序应该尽量保持简短和高效,因为中断会在主程序中断执行时立即执行,而且不能执行阻塞操作。
如果需要更复杂的处理,可以使用中断来触发任务,以便在任务中执行耗时的操作。

三、中断与任务间传值

1. 消息队列

在中断处理函数中直接执行业务逻辑,极容易造成程序崩溃。
可以使用队列在中断处理函数、任务之间传递信息,以避免程序可能因为竞态条件而崩溃或产生不可预测的结果。

具体操作是:

  1. 定义 QueueHandle_t 队列

  2. 中断处理函数 gpio_isr_handler 中,当 GPIO 中断被触发时,它会将触发中断的 GPIO 引脚号发送到队列 gpioEventQueue 中,以便任务能够获取该信息。

  3. 任务函数 gpio_task 中,通过调用 xQueueReceive 函数,任务会从队列 gpioEventQueue 中等待并获取触发中断的 GPIO 引脚号。一旦获取到引脚号,任务就会执行相应的操作,例如打印 GPIO 的电平状态。

这种机制确保了中断处理函数和任务之间的同步和通信。

2. 函数 xQueueSendFromISR

该函数作用是在中断中安全地向消息队列传值,其原型是:

BaseType_t xQueueSendFromISR(QueueHandle_t xQueue, const void * pvItemToQueue, BaseType_t * pxHigherPriorityTaskWoken);

参数:

  • xQueue:目标队列的句柄,指示要发送数据的队列。
  • pvItemToQueue:要发送的数据的指针。
  • pxHigherPriorityTaskWoken:一个指向 BaseType_t 变量的指针,用于指示是否唤醒了一个更高优先级的任务。

返回值:

  • 如果成功将数据发送到队列,则返回 pdPASS。
  • 如果队列已满或其他错误发生,则返回 errQUEUE_FULL。

四、完整示例

下面的示例获取GPIO口的电平值,在任务处理中加了 50ms 防抖动逻辑。

#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/gpio.h"
#include "esp_log.h"static const char* TAG = "main";
#define GPIO_PIN            GPIO_NUM_2 // 选择要使用的 GPIO 引脚// 防抖动延迟时间(以毫秒为单位)
#define DEBOUNCE_DELAY_MS   50static volatile bool gpio_int_triggered = false;
QueueHandle_t xQueue;static void IRAM_ATTR gpio_isr_handler(void* arg) {gpio_int_triggered = true;portYIELD_FROM_ISR(); // 唤醒任务以处理中断
}static void gpio_task(void *arg) {uint32_t ioNum;while (1) {if (gpio_int_triggered) {int value = gpio_get_level(GPIO_PIN);vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_DELAY_MS)); // 防抖动延迟if (gpio_get_level(GPIO_PIN) == value) {ioNum = (uint32_t)GPIO_PIN;gpio_int_triggered = false;int gpio_value = gpio_get_level(ioNum);ESP_LOGI(TAG, "GPIO[%lu] 触发中断,电平:%d", ioNum, gpio_value);}}vTaskDelay(10 / portTICK_PERIOD_MS); // 短暂延迟以降低 CPU 负载}
}void app_main(void) {// 配置 GPIO 引脚gpio_set_direction(GPIO_PIN, GPIO_MODE_INPUT);// 任何边沿触发,电平变化时都触发中断gpio_set_intr_type(GPIO_PIN, GPIO_INTR_ANYEDGE);// 创建中断句柄gpio_install_isr_service(0);// 注册中断处理函数gpio_isr_handler_add(GPIO_PIN, gpio_isr_handler, (void*)GPIO_PIN);// 创建任务来处理 GPIO 事件xTaskCreate(gpio_task, "gpio_task", 2048, NULL, 10, NULL);// 主任务继续执行其他操作while (1) {vTaskDelay(1000 / portTICK_PERIOD_MS);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/68480.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

移除链表元素_每日一题

“路虽远&#xff0c;行则将至” ❤️主页&#xff1a;小赛毛 ☕今日份刷题&#xff1a;移除链表元素 题目描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例1&…

真香:Alibaba开源GitHub星标100K微服务架构全彩进阶手册

前言&#xff1a; 微服务架构作为一种高效灵活的应用架构&#xff0c;正在成为企业级应用开发的主流选择。在众多的微服务架构指南中&#xff0c;阿里巴巴开源的GitHub微服务架构全彩进阶手册备受瞩目&#xff0c;其100star更是证明了其在开发者社区中的重要地位。 这本手册汇…

【Yolov5+Deepsort】训练自己的数据集(3)| 目标检测追踪 | 轨迹绘制 | 报错分析解决

&#x1f4e2;前言&#xff1a;本篇是关于如何使用YoloV5Deepsort训练自己的数据集&#xff0c;从而实现目标检测与目标追踪&#xff0c;并绘制出物体的运动轨迹。本章讲解的为第三部分内容&#xff1a;数据集的制作、Deepsort模型的训练以及动物运动轨迹的绘制。本文中用到的数…

PHP旅游管理系统Dreamweaver开发mysql数据库web结构php编程计算机网页

一、源码特点 PHP 旅游管理系统是一套完善的web设计系统&#xff0c;对理解php编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。 PHP 旅游管理系统 源码下载地址&#xff1a; https://download.csdn.net/download/qq_41…

2.4 Vector<T> 动态数组(随机访问迭代器)

C自学精简教程 目录(必读) 该 Vector 版本特点 这里的版本主要是使用模板实现、支持随机访问迭代器&#xff0c;支持std::sort等所有STL算法。(本文对随机迭代器的支持参考了 复旦大学 大一公共基础课C语言的一次作业) 随机访问迭代器的实现主要是继承std::iterator<std:…

LeetCode 46题:全排列

题目 给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a; 输入&#xff1a;…

容器技术简介

引言 随着云计算、大数据、人工智能等技术的不断发展&#xff0c;容器技术作为一种新兴的虚拟化技术&#xff0c;正逐渐成为IT领域的热点。容器技术可以帮助开发者更好地管理、部署和扩展应用程序&#xff0c;提高开发效率和应用程序的可靠性。本文将深入探讨容器技术的概念、…

gerrit 如何提交进行review

前言 本文主要介绍如何使用gerrit进行review。 下述所有流程都是参考&#xff1a; https://gerrit-review.googlesource.com/Documentation/intro-gerrit-walkthrough.html 先给一个commit后但是还没有push上去的一个办法&#xff1a; git reset --hard HEAD^可以多次reset.…

小白学go基础03-了解Go项目的项目结构

我们先来看看第一个Go项目——Go语言自身——的项目结构是什么样的。Go项目的项目结构自1.0版本发布以来一直十分稳定&#xff0c;直到现在Go项目的顶层结构基本没有大的改变。 截至Go项目commit 1e3ffb0c&#xff08;2019.5.14&#xff09;&#xff0c;Go1.0 项目结构如下&am…

VirtualBox7+Ubuntu22集群规划

1. 目的: 新入手了一台小主机&#xff08;8核 / Intel(R) Xeon(R) W-10885M CPU 2.40GHz 2.40 GHz, 16vCpu / 64G RAM / 系统类型 64 位操作系统, 基于 x64 的处理器&#xff09;&#xff0c;原装了一套Win11专业版&#xff0c;打算用VirtualBox 虚拟一个集群。 2. …

Vue2项目练手——通用后台管理项目第四节

Vue2项目练手——通用后台管理项目 数据的请求mock数据模拟实战文件目录src/api/mock.jssrc/api/mockServeData/home.jsmain.js 首页组件布局可视化图表可视化图表布局Home.vue echarts表Home.vue 数据的请求 mock数据模拟实战 mock官方文档 前端用来模拟后端接口的工具&…

UNIX网络编程卷一 学习笔记 第三十章 客户/服务器程序设计范式

开发一个Unix服务器程序时&#xff0c;我们本书做过的进程控制&#xff1a; 1.迭代服务器&#xff08;iterative server&#xff09;&#xff0c;它的适用情形极为有限&#xff0c;因为这样的服务器在完成对当前客户的服务前无法处理已等待服务的新客户。 2.并发服务器&#x…

rxjs之noop操作符(typescript 之占位符)

之前写代码&#xff0c;就在想&#xff0c;如果像python一样有一个 _ 或者pass类似的占位符&#xff0c;代码可读性就会高很多&#xff0c;而且好看的多&#xff0c;后来才发现有个noop。总结下 noop是一个英文缩写&#xff0c;它的全称是no operation&#xff0c;意思是不做任…

SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客

SquirrelMail实现Web方式收发邮件_xionglling的博客-CSDN博客小松鼠实现Web邮件服务SquirrelMail 是一个用PHP开发的Web邮件系统。它内置纯PHP支持的IMAP和SMTP协议&#xff0c;所有页面都遵循 HTML 4.0标准(没有使用任何 JavaScript 代码)&#xff0c;以便最大限度兼容各种多浏…

Qt之事件过滤—筛选处理对象

文章目录 事件过滤完整代码 事件过滤 事件过滤是当事件发生时&#xff0c;可以对不同对象&#xff0c;实现不同操作&#xff0c;以达到筛选的效果。 步骤&#xff1a; 1、首先安装一个事件过滤器&#xff0c;为对象安装事件过滤&#xff0c;指定“谁”来监控这些事件对象 //给…

Go 面向对象(方法)

一、 概述 在面向对象编程中&#xff0c;一个对象其实也就是一个简单的值或者一个变量&#xff0c;在这个对象中会包含一些函数&#xff0c;这种带有接收者的函数&#xff0c;我们称为方法(method)。本质上&#xff0c;一个方法则是一个和特殊类型关联的函数。 一个面向对象的…

vue3+ts+uniapp实现小程序端input获取焦点计算上推页面距离

vue3tsuniapp实现小程序端input获取焦点计算上推页面距离 input获取焦点计算上推页面距离 1.先说我这边的需求2.发现问题3.解决思路4.代码展示 自我记录 1.先说我这边的需求 需求 1.给键盘同级添加一个按钮例如’下一步’ or ‘确认’ 这种按钮 2.初步想法就是获取input焦点时…

【LeetCode-中等题】146. LRU 缓存

文章目录 题目方法一&#xff1a;直接继承LinkedHashMap调用api方法二&#xff1a;自定义LinkedHashMap HashMap ListNode LinkedHashMap 题目 LRU缓存是什么&#xff1a;LRU缓存机制&#xff0c;你想知道的这里都有 实现 LRU 缓存算法 方法一&#xff1a;直接继承Linked…

单臂路由实验:通过Trunk和子接口实现VLAN互通

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. PC 配置 IP 地址2. PC3 属于 Vlan10&#xff0c;PC4 属于 Vlan20&#xff0c;配置单臂路由实现 Vlan10 和 Vlan20 三层互通3. 测试在 PC3 上 Ping PC4 &#xff0c;可以 Ping 通 PC4 摘要&#xff1a; 本文…

数学建模:回归分析

&#x1f506; 文章首发于我的个人博客&#xff1a;欢迎大佬们来逛逛 数学建模&#xff1a;回归分析 文章目录 数学建模&#xff1a;回归分析回归分析多元线性回归案例 多项式回归一元多项式回归多元二项式回归 非线性回归逐步回归 回归分析 多元线性回归 案例 首先进行回归分…