在本教程中,我将讨论Arduino中断,以及如何使用Arduino中的中断来处理各种实时事件和多任务。
Arduino代码正常执行
到目前为止,我们实现的所有Arduino项目都非常简单,即在void setup{}函数中编写的代码将初始化所有引脚,变量和其他重要函数(如Serial或LCD),而在void loop{}函数中编写的代码将一遍又一遍地执行。
我们在所有Arduino项目中都实现了这种方法;从闪烁led灯到用安卓手机控制机械手臂。
如果你只是想让你的Arduino按顺序执行一系列指令,比如简单的led闪烁,这种机制很好。
在此代码中,设置函数只在Arduino上电时运行一次,并将数字I/O引脚12初始化为输出引脚。
Arduino现在将进入循环功能,在那里它打开LED,等待一秒钟,关闭LED,等待一秒钟,重复这个过程。
按钮的例子
现在,考虑将按钮与Arduino连接在一起的相同情况。在这个简单的草图中,我将一个按钮与Arduino连接,以便切换LED的状态,即按一次将LED打开,再按一次将LED关闭。
这是投票!
在这种情况下,Arduino(或ATmega328p微控制器,具体地说)会不断检查循环功能中按钮的状态。这种检查设备或引脚是否需要处理器(微控制器)的服务的方法称为轮询。
这种方法的主要问题是,控制器不断地从事一个活动(在这种情况下检查按钮的状态),不能执行任何其他任务。这里出现了中断救援的概念。
什么是中断?
中断是一种机制,通过这种机制,处理器被告知停止当前指令的执行,执行一个特殊的事件或进程,然后返回到原来的执行。
Arduino(或任何微控制器或处理器)中中断的主要优势是处理器不需要连续地轮询设备是否需要关注。每当需要服务时,设备本身就会“中断”处理器,直到处理器可以执行一些其他任务。
如果你再次以按钮为例,最初,控制器会持续检查按钮的状态。但是在这种情况下引入中断的概念,控制器可以做任何它想做的事情(我的意思是除了检查按钮的状态之外,根据你的代码),每当按钮被按下时,它会自动停止当前的执行,并将其全部注意力放在按钮按下事件上。
在中断时,我说处理器执行一个特殊的进程,这个特殊进程只是一组被称为中断服务例程的指令。中断服务例程(ISR)的结构类似于任何用户定义的void函数。
Arduino中的中断
Arduino有三种不同的中断来源:
- 定时器中断
- 外部中断
- Pin-Change中断
注意:Arduino中的定时器中断,顾名思义,是由Arduino定时器引起的,而Pin-Change中断可以在检测到一组引脚的状态变化时启用。
关于Arduino定时器,定时器中断和Pin-Change中断的讨论有点超出了本教程的范围,所以我将继续外部中断。
外部中断
顾名思义,Arduino中的外部中断是由于外部事件,即任何外部中断引脚的状态变化。例如,当你接收到来自水流量传感器的脉冲时,就像在这个项目中一样。Arduino水流量传感器教程或者当你按下按钮时。
Arduino UNO有两个外部中断引脚INT0和INT1。在内部,INT0映射到数字I/O引脚2,INT1映射到数字I/O引脚3。
如何在Arduino上启用中断?
Arduino中有一个特殊的函数叫做attachInterrupt(),使用它配置外部中断。
attachInterrupt()函数的语法如下。
这个函数还有另外两种语法,但Arduino参考指南推荐使用这个语法。
现在让我们来理解这个函数的参数。
- digitalPinToInterrupt(pin) "用于指定中断引脚号。
- ISR是中断服务例程函数调用。
- Mode用于指示何时触发中断。
- CHANGE:当引脚值发生变化时触发中断。
- RISING:当引脚值从LOW上升到HIGH时触发中断。
- 下降:触发中断时,引脚值从高下降到低。
- LOW:当引脚值变为LOW时触发中断。
带有中断的按钮示例
现在,让我们通过将Interrupt连接到按钮引脚来回顾前面的按钮示例。下面是带有按钮中断的新代码。
在上面的代码中,按钮连接到Arduino的引脚2 (INT0),并且在按钮引脚的值发生变化并触发名为button_ISR的ISR事件时,该引脚附加了一个中断。
关于这段代码需要注意的是,尽管这里实现了Interrupt,但它仍然不是最好的执行。下面是一个更适合中断的代码,它甚至考虑按钮反弹。
从上述实现中需要注意的要点是:
- ISR中使用的变量必须声明为Volatile。
- ISR应该尽可能小。
- 在ISR中没有延迟()。
一个回应
谢谢你!
简单明了。