当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Arduino attachInterrupt()用法及代码示例


[外部中断]

说明

带中断的数字引脚

attachInterrupt() 的第一个参数是中断号。通常您应该使用digitalPinToInterrupt(pin) 将实际的数字引脚转换为特定的中断号。例如,如果您连接到引脚 3,请使用 digitalPinToInterrupt(3) 作为 attachInterrupt() 的第一个参数。

木板 可用于中断的数字引脚

Uno、Nano、Mini、其他基于 328 的

2、3

Uno WiFi Rev.2,Nano Every

所有数字引脚

兆丰,兆丰2560,MegaADK

2、3、18、19、20、21(引脚 20 和 21 在用于 I2C 通信时不可用于中断)

Micro、Leonardo、其他基于 32u4 的

0、1、2、3、7

Zero

所有数字引脚,除了 4

MKR 家族板

0、1、4、5、6、7、8、9、A1、A2

纳米 33 IoT

2、3、9、10、11、13、A1、A5、A7

Nano 33 BLE、Nano 33 BLE Sense

所有引脚

Due

所有数字引脚

101

所有数字引脚(仅引脚 2、5、7、8、10、11、12、13 可用于 CHANGE)

注意事项和警告

注意
在附加的函数内,delay()将不起作用,并且返回的值millis()不会增加。在函数中接收的串行数据可能会丢失。你应该声明为volatile您在附加函数中修改的任何变量。有关详细信息,请参阅下面有关 ISR 的部分。

使用中断

中断对于在微控制器程序中使事情自动发生很有用,并且可以帮助解决时序问题。使用中断的好任务可能包括读取旋转编码器或监视用户输入。

如果您想确保程序始终捕捉到来自旋转编码器的脉冲,这样它就不会错过任何一个脉冲,那么编写一个程序来做其他事情就会变得非常棘手,因为程序需要不断地轮询传感器编码器的线,以便在脉冲发生时捕捉脉冲。其他传感器也有类似的接口动态,例如试图读取试图捕捉点击的声音传感器,或试图捕捉硬币掉落的红外插槽传感器 (photo-interrupter)。在所有这些情况下,使用中断可以让微控制器在不丢失输入的情况下完成一些其他工作。

关于中断服务程序

ISR 是一种特殊的函数,具有大多数其他函数所没有的独特限制。 ISR 不能有任何参数,它们不应该返回任何东西。

通常,ISR 应尽可能短且快。如果您的草图使用多个 ISR,一次只能运行一个,其他中断将在当前中断完成后执行,顺序取决于它们的优先级。 millis() 依靠中断来计数,因此它永远不会在 ISR 内递增。由于delay() 需要中断才能工作,因此如果在 ISR 内调用它将无法工作。 micros() 最初可以工作,但会在 1-2 毫秒后开始表现异常。 delayMicroseconds() 不使用任何计数器,因此它会正常工作。

通常,全局变量用于在 ISR 和主程序之间传递数据。要确保 ISR 和主程序之间共享的变量正确更新,请将它们声明为 volatile

有关中断的更多信息,请参阅Nick Gammon’s notes

用法

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)(推荐的)
attachInterrupt(interrupt, ISR, mode)(不建议)
attachInterrupt(pin, ISR, mode)(不推荐。此外,此语法仅适用于 Arduino SAMD Boards、Uno WiFi Rev2、Due 和 101。)

参数

interrupt: 中断号。允许的数据类型:int.
pin:Arduino 引脚号。
ISR:中断发生时调用的ISR;此函数必须不带任何参数且不返回任何内容。这个函数有时被称为中断服务程序。
mode: 定义何时触发中断。四个常量预定义为有效值:

  • LOW每当引脚为低电平时触发中断,

  • CHANGE每当引脚更改值时触发中断

  • RISING当引脚从低到高时触发,

  • FALLING当引脚从高电平变为低电平时。

Due、Zero 和 MKR1000 板还允许:

  • HIGH 在引脚为高电平时触发中断。

返回

示例代码

const byte ledPin = 13;
const byte interruptPin = 2;
volatile byte state = LOW;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), blink, CHANGE);
}

void loop() {
  digitalWrite(ledPin, state);
}

void blink() {
  state = !state;
}

中断号

通常你应该使用 digitalPinToInterrupt(pin) ,而不是直接在你的草图中放置一个中断号。具有中断的特定引脚及其到中断号的映射因每种类型的板而异。直接使用中断号可能看起来很简单,但是当您的草图在不同的板上运行时,它可能会导致兼容性问题。

但是,较旧的草图通常有直接的中断号。通常使用数字 0(用于数字引脚 2)或数字 1(用于数字引脚 3)。下表显示了各种板上的可用中断引脚。

请注意,在下表中,中断编号是指要传递给 attachInterrupt() 的编号。由于历史原因,这个编号并不总是直接对应于 ATmega 芯片上的中断编号(例如 int.0 对应于 ATmega2560 芯片上的 INT4)。

木板 int.0 int.1 int.2 int.3 int.4 int.5

Uno,以太网

2

3

Mega2560

2

3

21

20

19

18

基于 32u4(例如 Leonardo、Micro)

3

2

0

1

7

对于 Uno WiFiRev.2、Due、Zero、MKR 系列和 101 板,中断号 = 引脚号。

相关用法


注:本文由纯净天空筛选整理自arduino.cc大神的英文原创作品 attachInterrupt()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。