这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【换取逻辑分析仪】Arduino系列教程【外部中断】

共5条 1/1 1 跳转至

【换取逻辑分析仪】Arduino系列教程【外部中断】

助工
2024-09-17 20:41:32   被打赏 30 分(兑奖)     打赏

简介

本章节我们将学习Arduino中的中断相关的API函数. 那么在我们正式可以学习API之前呢,让我来简单的介绍一下中断相关的概念.


中断

中断是单片机中实现实时操作的关键机制。没有中断的系统往往依赖程序在主循环中不断运行,无法及时响应外部事件。我们用一个电梯的例子来说明:想象一部扶手电梯在正常运行时,如果发生紧急情况,比如一个小孩被卡住,而电梯没有中断机制,那么唯一能做的就是切断电源来停下电梯。然而,切断电源可能耗费一定的时间,小孩的处境会变得非常危险。

引入中断后,情况就完全不同了。如果有小孩遇到危险,按下电梯的急停按钮,电梯立即停止,但仍保持通电状态,系统可以在处理完紧急情况后将电梯恢复到之前的状态。这就是中断的本质:当发生紧急事件时,暂停当前的工作,优先处理紧急事件,之后再回到之前的任务。


中断优先级

单片机通常提供多种中断资源,例如系统中断、定时器中断、串口中断和外部中断等。不同的中断可以根据应用场景进行配置。

那么,当多个中断同时发生时该如何处理呢?这时就涉及到中断优先级。假如你在写代码,突然有几个人同时来给你捏肩膀,那么你肯定会选择优先接受最舒服的一个。同样道理,优先级高的中断会优先被处理,低优先级的中断则会被延后。


中断嵌套

另一个常见的情况是中断嵌套。假如低优先级的中断A正在执行,突然有一个高优先级的中断B发生。由于中断B的优先级较高,单片机会暂停中断A的处理,先执行中断B,待中断B处理完成后再返回处理中断A。

比方说你正在吃美女A送来的水果,此时美女B送来了你更喜欢的水果。你会停下吃A的水果,优先享用B的水果,等B的水果吃完了再去继续吃A的。


中断的注意事项

中断函数一般不要包含复杂逻辑或耗时的操作,比如延时操作。这样可能导致一个中断还未处理完,新的中断又到来,影响系统的实时性。

经过这样简化,中断机制变得更容易理解。它的核心就在于实时处理紧急事件,优先处理高优先级任务,并及时返回原先的工作


Arduino 中断相关API函数

根据Arduino的官方API文档(https://www.arduino.cc/reference/en/)得知,Arduino的中断相关函数一共有以下五个.

image.png


让我们来逐一介绍和使用上面的API. 在interrupts下面一共有两个API

1- interrupts()

2- noInterrupts()

这两个API分别用于开启中断和关闭中断, 例如我们在操作某些时序相关的传感器的时候,并不希望和需要去他的应用进入中断函数来打断当前的时序,那么我们便可以在开始传感器操作之前调用noInterrupts() 方法来关闭中断. 然后在完成时序操作后再调用interrupts()开启中断.

对于外部中断,这里一共有三个方法, 分别是

1-  attachInterrupt()
2- detachInterrupt()
3- digitalPinToInterrupt()


image.png


第一个API attachInterrupt() 主要用于绑定某一个IO的引脚到外部中断上. 同时设置对应的中断方法以及触发中断的方式. 但是需要注意的是,并不是所有的PIN都可以被绑定作为外部中断的触发PIN. Adruino uno r4 wifi 支持的触发Pin 如下所示


image.png


用法的话则按照Arduino推荐的调用方式进行使用即可. 按下图所示


image.png

在我们继续之前,让我们看一下推荐调用方式中设计到的另一个API digitalPinToInterrupt()

digitalPunToInterrupt() 这个API主要用于确定当前的PIN是否可以被绑定作为中断的引脚. 比如说在Arduino uno r4 wifi中支持的PIN 为 2 和 3 , 那么将这两个PIN作为参数传入的时候, 这个方法将会返回1, 即当前的PIN支持绑定外部中断, 如果当前的PIN并不支持外部中断的话则返还0.

那么我们继续看上面的attachInterrupt() API 的第二个参数, ISR, 即Interrupt service routine 可以理解为call back function (回掉函数), 即中断处罚之后触发的函数(用户可以自定义). 

第三个参数则为外部中断的触发方式, 那么它支持的触发方式一共有四种(五种), 分别是:

image.png

1- 低电平触发

2-IO状态切换的时候触发

3-上升沿触发

4-下降沿触发

同时在Due, Zero 和MKR1000开发版上还支持高电平触发.

而最后的一个API则是 detachInterrupt() 这个API主要是用于,当某一个PIN被绑定成了外部中断的PIN的话,解绑它. 那么至此我们便看完了Arduino的所有API. 接下来我们看下代码部分.




代码Demo演示


const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;
 
void setup() 
{   
    //配置PIN
    pinMode(ledPin, OUTPUT);
    pinMode(interruptPin, INPUT_PULLUP);
    //绑定中断PIN和中断服务以及中断的触发方式
    attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
} 

//主循环
void loop() 
{   
    digitalWrite(ledPin, state); 
} 

//回掉函数
void blink()
{
   state = !state; 
}


在上述代码中我们初始化了LED灯的PIN, 和中断的PIN,并且为中断的PIN绑定了中断服务, 且在主循环中一直调用digitalWrite向LED灯的PIN写低(关闭LED) 同时定义了一个回掉函数,那么当中断PIN发生状态切换的时候,那么当前LED灯的状态将触发中断服务,同时反转LED灯的状态.


总结

在本章节我们学习了如何使用Arduino的中断函数及其相关的API, 相信通过近期这几个帖子大家也能意识到如果不考虑底层实现, 仅仅使用Arduino来快速开发或者验证产品是十分快速方便的, 让我们继续期待下面的教程吧





专家
2024-09-18 00:03:56     打赏
2楼

感谢楼主分享


专家
2024-09-18 10:15:21     打赏
3楼

Arduino的程序开发,相对容易很多。学会基础知识和找到适当的库支持,开发就会变得简单。


专家
2024-09-18 20:58:42     打赏
4楼

感谢分享


专家
2024-09-19 20:33:31     打赏
5楼

感谢楼主分享


共5条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]