ESP32入门七(中断)

中断用于处理在程序正常执行期间通过外部事件或者响应软件指令触发时发生的事件。比如,在一段呼吸灯的代码中,正常运行时的结果为LED从暗到亮,再从亮到暗持续地运行。我们可以通过一个中断来控制呼吸灯的运行和停止。使用中断功能,我们就不需要不停地监控一个引脚的状态,当中断被触发,内部控制器停止执行主程序,并调用中断服务例程 (ISR) 。

中断服务例程 (ISR)

中断服务例程 (ISR)是特殊类型的函数,它有一些特殊的特点和规则:

1、将部分内部 SRAM0 区域分配给IRAM,可以显著减少运行的迟延。

2、必须将中断服务例程 (ISR)放入 IRAM。

3、中断服务例程 (ISR)不能有任何参数,也不返回任何值。

4、因为中断服务例程 (ISR)会中断主程序的运行,运行时间过长会对主程序形成阻塞,所以中断服务例程 (ISR)尽可能短和快。

在IRAM中放置代码,可以使用 IRAM_ATTR 宏在源代码中指定该函数放置到IRAM中,如:

void IRAM_ATTR ISR_function()
{// ...
}

我们在使用中断功能时,会使用一个名为attachInterrupt()的函数个设置引脚中断。

函数:attachInterrupt

作用:用于将中断附加到定义的引脚。

格式:attachInterrupt(uint8_t pin, voidFuncPtr handler, int mode);

参数:

        pin                         -定义监控的GPIO 引脚号。

        handler                  -设置中断服务例程 (ISR)

        mode                     -设置中断模式
                LOW                 -低电平触发
                CHANGE          -管脚电平变化,触发
                HIGH                -高电平触发
                RISING            -管脚从低电平变化高电平触发,即上升沿触发
                FALLING         -下降沿触发,电平从高变低

示例代码

我们需要定义一个引脚来用于中断服务,这里选择4号引脚:

int interrupt_pin = 4;          //引脚号

 下面需要要定义一个计数器来记录中断的次数,默认设为0:

int interrupt_counter = 0;      //中断次数计数器

定义一个开关标记来记录中断时的开关状态:

bool press_down;                //中断标记开关

定义一个ISR函数,放置到IRAM:

void  IRAM_ATTR ISR_function(){interrupt_counter++;          //中断次数计数器累加press_down = true;            //中断标记开关设为开
}

我们需要使用上面所介绍的attachInterrupt函数来把中断服务附加到指定的引脚:

attachInterrupt(interrupt_pin, ISR_function, FALLING);  //中断附加到引脚

以下为硬件的连接和完整的代码:

int interrupt_pin = 4;          //引脚号
int interrupt_counter = 0;      //中断次数计数器
bool press_down;                //中断标记开关void  IRAM_ATTR ISR_function(){interrupt_counter++;          //中断次数计数器累加press_down = true;            //中断标记开关设为开
}void setup() {Serial.begin(115200);pinMode(interrupt_pin,INPUT_PULLUP);  //引脚初始化为输入上拉模式attachInterrupt(interrupt_pin, ISR_function, FALLING);  //中断附加到引脚
}void loop() {if(press_down){                       //如果中断标记开关为开状态Serial.print("发生中断事件:");        Serial.println(interrupt_counter);  //串口输出计数器的值press_down = false;                 //中断标记开关设为关}
}

代码说明

在该例程中,我们设置监控4号引脚来触发中断服务。

我们把4号引脚设置为输入上拉模式,当开机时,4号引脚为高电平状态。

4号引脚通过一个开关与GND引脚连接,当开关按下时,4号引脚由高电平变为低电平状态。

这时,触发中断,主程序中断,进入ISR_function函数,函数功能包括给计数器累加中断次数和中断标记开关设置为开。

中断标记为开时满足if(press_down)条件,进入分支,串口此时输出计数器的值,并设置中断标记开关为关闭状态。

测试代码

运行该代码,打开串口监视器,按下开关,可以观察到计数器的变化:

同时,我们也会发现,有时即使只按一次开关,也会出现计数据多次增加。这是同于硬件生产工艺的原因造成的,我们在直观上感觉只按了一次开关,但在十分微小的时间里,开关的接触弹片可能进行了多次的接触。释放按钮时也会发生同样的事情。在生产中,工艺上是无法达到理想的完美状态的。以致产生了这种名为"开关抖动"的现象。我们可以通过硬件或软件的方式来消除这种抖动。

消除开关抖动

我们在上面的例程中加入添加代码,以软件的方式来消除开关抖动。实现每按一次开只允许动行一次ISR程序:

int interrupt_pin = 4;          //引脚号
int interrupt_counter = 0;      //中断次数计数器
bool press_down = false  ;                //中断标记开关void  IRAM_ATTR ISR_function(){static unsigned long lastInterruptTime = 0;unsigned long interruptTime = millis();if(interruptTime - lastInterruptTime >200){press_down = true;                //中断标记开关设为开interrupt_counter++;}lastInterruptTime = interruptTime;
}void setup() {Serial.begin(115200);pinMode(interrupt_pin,INPUT_PULLUP);  //引脚初始化为输入上拉模式attachInterrupt(interrupt_pin, ISR_function, FALLING);  //中断附加到引脚
}void loop() {if(press_down){                       //如果中断标记开关为开状态Serial.print("发生中断事件:");        Serial.println(interrupt_counter);  //串口输出计数器的值press_down = false;                 //中断标记开关设为关}
}

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

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

相关文章

OpenCV-11颜色通道的分离与合并

本次我们使用两个比较重要的API split(mat)将图像的通道进行分割。 merge((ch1,ch2,ch3))将多个通道进行融合。 示例代码如下: import cv2 import numpy as npimg np.zeros((480, 640, 3),…

uni-app App.vue生命周期全局样式全局存储globalData

锋哥原创的uni-app视频教程: 2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中..._哔哩哔哩_bilibili2023版uniapp从入门到上天视频教程(Java后端无废话版),火爆更新中...共计23条视频,包括:第1讲 uni…

Docker之网络配置

目录 1.网络概念 网络相关的有ip,子网掩码,网关,DNS,端口号 1.1 ip是什么? ip是唯一定位一台网上计算机 Ip地址的分类: IPV4: 4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数 【例…

windows server 2022 启用SYN攻击保护

2023.12.28 SYN攻击是什么: SYN攻击是黑客攻击的常用手段,也是最容易被利用的一种攻击手法,属于DDoS攻击的一种。它利用TCP协议缺陷,通过发送大量的半连接请求,耗费CPU和内存资源。 SYN攻击包括大量TCP连接的第一个包&…

HTML5+CSS3②——图像、超链接、音频、视频

目录 图像 超链接 音频 视频 图像 作用&#xff1a;在网页中插入图片 单标签&#xff1a; 标签名&#xff1a;<img src"图片的URL"> <img src"图片的URL" alt"替换文本" title"提示文本"> 属性写在尖括号里面&#xff0c;…

【Redis-02】Redis数据结构与对象原理 -上篇

Redis本质上是一个数据结构服务器&#xff0c;使用C语言编写&#xff0c;是基于内存的一种数据结构存储系统&#xff0c;它可以用作数据库、缓存或者消息中间件。 我们经常使用的redis的数据结构有5种&#xff0c;分别是&#xff1a;string(字符串)、list(列表)、hash(哈希)、s…

多环境及SpringBoot项目部署

1、多环境 2、项目部署上线 原始前端 / 后端项目宝塔Linux容器容器平台 3、前后端联调 4、项目扩展和规划 多环境 程序员鱼皮-参考文章 本地开发&#xff1a;localhost&#xff08;127.0.0.1&#xff09; 多环境&#xff1a;指同一套项目代码在把不同的阶段需要根据实际…

将数据“0x0f“写入AT24C02再读出送P1口显示

#include <reg51.h> // 包含51单片机寄存器定义的头文件 #include <intrins.h> //包含_nop_()函数定义的头文件 #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写入…

win10系统gpu本地部署chatglm3-6b,从0开始安装

开源地址&#xff1a; GitHub - THUDM/ChatGLM3: ChatGLM3 series: Open Bilingual Chat LLMs | 开源双语对话语言模型 前言&#xff1a;ChatGLM2与ChatGLM3区别 ChatGLM2与ChatGLM3模型架构是完全一致的&#xff0c;ChatGLM与后继者结构不同。可见ChatGLM3相对于ChatGLM2没…

付费进群系统源码带定位完整独立版(12月30日)再次修复首发

搭建教程 nginx1.2 php5.6–7.2均可 最好是7.2 第一步上传文件程序到网站根目录解压 第二步导入数据库&#xff08;shujuku.sql&#xff09; 第三步修改/config/database.php里面的数据库地址 第四步修改/config/extra/ip.php里面的域名 第四步设置伪静态thinkphp 总后台账号&…

ArkUI中自定义组件的生命周期

文章概叙 本文主要是介绍下在作为page以及component的时候的生命周期&#xff0c;以及调用API等应该在哪个生命周期使用。 书接上回 之前的博客已经结束了对底部栏的操作&#xff0c;现在开始需要关注到具体内容的对接了。 而开发的第一步&#xff0c;我们对页面的生命周期…

最后一次纪念在泰山OFFICE的日子,明年开源量子OFFICE

今天去泰山在无锡的办公地点&#xff0c;给门卫送了一点零食表示感谢。送了之后&#xff0c;我也没进去怀旧&#xff0c;然后就去附近的南山&#x26e50;礼佛求福。 2021年的最后一天&#xff0c;公司举办了迎新活动。看了恍如隔世。我怀念泰山OFFICE&#xff0c;是因为在这里…

上海周边公路骑行路线分享,维乐带你抓住秋天的小尾巴

路线一&#xff1a;松江郊里骑行      在魔都上海&#xff0c;藏着一条自然风景适宜&#xff0c;能眺望黄浦江的美丽骑行路线。导航到华长路杨家角就能到达起点&#xff0c;一路向西&#xff0c;这里路况非常好&#xff0c;只有一条小道&#xff0c;没有汽车的障碍&#xf…

25、WEB攻防——通用漏洞SQL读写注入MYSQLMSSQLPostgreSQL

文章目录 Mysql-root高权限读写注入PostgreSQL——dba高权限读写注入Mssql-sa高权限读写注入 Access无高权限注入点——只能猜解&#xff0c;而且是暴力猜解&#xff1b; MYSQL&#xff0c;PostgreSQL&#xff0c;MSSQL(SQL server)高权限注入点——可升级读写&#xff08;文件…

学习体系结构 - AArch64 异常模型

学习体系结构 - AArch64 异常模型 Learn the architecture - AArch64 Exception Model version 1.3 根据DeepL翻译 校准 1、Overview AArch64异常模型指南&#xff0c;介绍了Armv8-A和Armv9-A中的异常和特权模型。它涵盖了Arm架构中不同类型的异常以及处理器在处理异常时的行…

12/31

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;用于密集预测的多路径视觉Transformer1、研究背景2、方法提出3、相关方法3.1、Vision Transformers for dense predictions3.2、C…

GAMES101:作业4记录

文章目录 总览算法编写代码&#xff1a;recursive_bezier()的实现Bezier()函数的实现提高部分&#xff1a;反走样 总览 Bzier 曲线是一种用于计算机图形学的参数曲线。在本次作业中,你需要实现 de Casteljau 算法来绘制由 4 个控制点表示的 Bzier 曲线 (当你正确实现该算法时,…

亚信安慧AntDB数据库两项目分别入选2023“星河”标杆、优秀案例

近日&#xff0c;由中国信息通信研究院、中国通信标准化协会大数据技术标准推进委员会&#xff08;CCSA TC601&#xff09;共同组织的第七届大数据“星河&#xff08;Galaxy&#xff09;”案例评选结果公示&#xff0c;亚信安慧AntDB数据库两项目入选&#xff0c;其中“基于Ant…

国图公考:研究生可以考选调生吗?

研究生可以报考选调生吗?当然是可以的&#xff0c;但是同样需要满足一定的条件才可以。 除本科生外&#xff0c;具有硕士、博士学位的考生均可申请考试。但是&#xff0c;除了满足应届毕业生的身份&#xff0c;还需要满足年龄限制。一般来说&#xff0c;本科生不超过25岁&…

Kubernetes集群部署Rook Ceph实现文件存储,对象存储,块存储

Kubernetes集群部署Rook Ceph部署Ceph集群 1. Rook Ceph介绍 Rook Ceph是Rook项目中的一个存储方案&#xff0c;专门针对Ceph存储系统进行了优化和封装。Ceph是一个高度可扩展的分布式存储系统&#xff0c;提供了对象存储、块存储和文件系统的功能&#xff0c;广泛应用于提供…