65.9K
CodeProject 正在变化。 阅读更多。
Home

Arduino 平台 - 中断介绍

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (25投票s)

2010 年 2 月 24 日

CPOL

5分钟阅读

viewsIcon

99101

downloadIcon

729

Arduino 中断介绍

引言

这是我关于 Arduino 微处理器平台的第二篇文章。第一篇是使用 Arduino 实现了一个简单的 SIMON 游戏。该文章可以在这里找到。
有关 Arduino 硬件的介绍,请参阅 jeffb42 的优秀文章,因为在这里重复就没有意义了。

本文是关于什么的?

在本文中,我将介绍硬件中断,以及它们如何成为 Arduino 平台的重要特性。

什么是中断?

中断是一种向微处理器发出信号,告知发生了某事的方法。然而,您可能会问自己,这不就是您使用数字输入等时发生的事情吗?简单来说,不是。

当您使用数字输入等时,通常会通过发出指令来读取其值,然后使用某种形式的逻辑根据读取的值进行操作,即代码正在轮询一个值。根据例程的复杂性以及输入状态变化的持续时间,完全有可能根本看不到输入的任何变化。

通过使用中断,代码实际上会被中断,并被迫分支并执行其他操作,即输入的状y态变化不会被“错过”。因此,中断就像硬件触发器。

有什么好处?

中断可以帮助解决您的代码/硬件设置中可能出现的时序问题。您可能已经遇到过时序问题,只是不明白发生了什么。您有多少次对自己说过:“为什么那个没触发?”或者“上次运行的时候它工作得好好的。这次有什么不同?”

开始正题

我将使用 Arduino Duemilanove 板作为本例的示例,并将使用开发 IDE 的 Release 18 版本。可以从 Arduino.cc 直接下载。

如果您使用的是不同类型的 Arduino 板,您需要查看规格以了解哪些引脚是哪个,因为不同类型的板可能具有不同的中断/数字引脚/模拟引脚等的分配和数量。

在 Duemilanove 上,有两个硬件中断可用。它们位于数字引脚 2 和 3 上。在本演示中,我们将使用引脚 2,并使用数字引脚 4 作为输出以控制 LED。其原理图如下所示

arduino_interrupts

标准数字输入和输出 - 无中断

根据原理图设置 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 日 - 文章的第一个版本
© . All rights reserved.