Arduino 平台 - 中断介绍
Arduino 中断介绍
引言
这是我关于 Arduino 微处理器平台的第二篇文章。第一篇是使用 Arduino 实现了一个简单的 SIMON 游戏。该文章可以在这里找到。
有关 Arduino 硬件的介绍,请参阅 jeffb42 的优秀文章,因为在这里重复就没有意义了。
本文是关于什么的?
在本文中,我将介绍硬件中断,以及它们如何成为 Arduino 平台的重要特性。
什么是中断?
中断是一种向微处理器发出信号,告知发生了某事的方法。然而,您可能会问自己,这不就是您使用数字输入等时发生的事情吗?简单来说,不是。
当您使用数字输入等时,通常会通过发出指令来读取其值,然后使用某种形式的逻辑根据读取的值进行操作,即代码正在轮询一个值。根据例程的复杂性以及输入状态变化的持续时间,完全有可能根本看不到输入的任何变化。
通过使用中断,代码实际上会被中断,并被迫分支并执行其他操作,即输入的状y态变化不会被“错过”。因此,中断就像硬件触发器。
有什么好处?
中断可以帮助解决您的代码/硬件设置中可能出现的时序问题。您可能已经遇到过时序问题,只是不明白发生了什么。您有多少次对自己说过:“为什么那个没触发?”或者“上次运行的时候它工作得好好的。这次有什么不同?”
开始正题
我将使用 Arduino Duemilanove 板作为本例的示例,并将使用开发 IDE 的 Release 18 版本。可以从 Arduino.cc 直接下载。
如果您使用的是不同类型的 Arduino 板,您需要查看规格以了解哪些引脚是哪个,因为不同类型的板可能具有不同的中断/数字引脚/模拟引脚等的分配和数量。
在 Duemilanove 上,有两个硬件中断可用。它们位于数字引脚 2 和 3 上。在本演示中,我们将使用引脚 2,并使用数字引脚 4 作为输出以控制 LED。其原理图如下所示
标准数字输入和输出 - 无中断
根据原理图设置 Arduino,并将以下代码上传到微处理器。这里您读取输入的值,进行条件比较,运行一个耗时的例程,然后重复。
由于耗时过程处于输入按钮触发时间的不确定点,这将导致 LED 输出不可预测。有时 LED 会立即改变状态,有时则什么都不发生,有时您需要按住按钮一段时间才能识别状态更改。[这是下载的源代码文件中的代码 PART A。]
int pbIn = 2; // Digital input on pin 2
int ledOut = 4; // The output LED pin
int state = LOW; // The input state
void setup()
{
// Set up the digital Pin 2 to an Input and Pin 4 to an Output
pinMode(pbIn, INPUT);
pinMode(ledOut, OUTPUT);
}
void loop()
{
state = digitalRead(pbIn); //Read the button
digitalWrite(ledOut, state); //write the LED state
//Simulate a long running process or complex task
for (int i = 0; i < 100; i++)
{
// do nothing but waste some time
delay(10);
}
}
利用中断
我们将使用相同的原理图并修改代码以利用硬件中断。现在,当您上传代码时,LED 会在每次按下按钮时改变状态,即使代码仍在主循环中运行相同的长延迟。[这是下载的源代码文件中的代码 PART B。]
int pbIn = 0; // Interrupt 0 is on DIGITAL PIN 2!
int ledOut = 4; // The output LED pin
volatile int state = LOW; // The input state toggle
void setup()
{
// Set up the digital pin 2 to an Interrupt and Pin 4 to an Output
pinMode(ledOut, OUTPUT);
//Attach the interrupt to the input pin and monitor for ANY Change
attachInterrupt(pbIn, stateChange, CHANGE);
}
void loop()
{
//Simulate a long running process or complex task
for (int i = 0; i < 100; i++)
{
// do nothing but waste some time
delay(10);
}
}
void stateChange()
{
state = !state;
digitalWrite(ledOut, state);
}
volatile
关键字被添加到 state
变量中,这会使编译器使用 RAM 而不是存储寄存器。这样做是因为如果存储寄存器被主线程以外的区域修改,它可能会暂时不准确。在 Arduino 中,这与由中断触发的代码有关。
attachInterrupt(param1, param2, param3)
需要三个参数,它们是:
param1
= 要监听的中断。这是中断编号,而不是数字输入编号param2
= 要调用的代码函数,它必须是一个不带参数且不返回值的函数。param3
= 要监视的条件。
Arduino 可以监听 4 种类型的条件变化。它们是
LOW
= 输入为LOW
状态RISING
= 输入状态从LOW
变为HIGH
FALLING
= 输入状态从HIGH
变为LOW
CHANGE
= 输入状态从HIGH
变为LOW
或从LOW
变为HIGH
,即状态已改变
重新分配中断
可以通过使用 attachInterrupt()
方法随时更改中断。一旦完成,之前在该关联引脚上分配的任何中断都会被移除。
开始/停止中断
Arduino 还可以暂时忽略所有中断。如果您有一些必须不间断执行的敏感代码,您可能需要这样做。在这种情况下,您将调用 noInterrupts()
。一旦您的敏感代码块完成,可以通过调用 interrupts()
来重新启动中断。
移除中断
还可以使用 detachInterrupt(interrupt_number)
方法移除中断。
就这样,这是对 Arduino 平台上的硬件中断的一个快速基本介绍。现在,您只需要看看它们如何融入您的项目中,以及如何利用它们。
相关链接
- Arduino 主页 - 所有关于 Arduino 和 IDE 下载的参考资料
- 我的网站 - 那里有更多关于 Arduino 的操作指南和信息
历史
- 2010 年 2 月 20 日 - 文章的第一个版本