说明
带中断的数字引脚
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 array用法及代码示例
- Arduino analogRead()用法及代码示例
- Arduino analogReadResolution()用法及代码示例
- Arduino abs()用法及代码示例
- Arduino analogWriteResolution()用法及代码示例
- Arduino analogWrite()用法及代码示例
- Arduino long用法及代码示例
- Arduino Arduino_EMBRYO_2 - setLengthXY()用法及代码示例
- Arduino ~用法及代码示例
- Arduino ArduinoBLE - bleDevice.advertisedServiceUuidCount()用法及代码示例
- Arduino const用法及代码示例
- Arduino Ethernet - server.begin()用法及代码示例
- Arduino ArduinoBLE - BLEService()用法及代码示例
- Arduino digitalWrite()用法及代码示例
- Arduino ArduinoBLE - bleCharacteristic.subscribe()用法及代码示例
- Arduino Servo - attach()用法及代码示例
- Arduino write()用法及代码示例
- Arduino Arduino_LSM9DS1 - readGyroscope()用法及代码示例
- Arduino ArduinoSound - FFTAnalyzer.input()用法及代码示例
- Arduino MKRGSM - gprs.attachGPRS()用法及代码示例
- Arduino WiFiNINA - WiFi.config()用法及代码示例
- Arduino MKRGSM - sms.read()用法及代码示例
- Arduino MKRNB - getCurrentCarrier()用法及代码示例
- Arduino Scheduler - Scheduler.startLoop()用法及代码示例
- Arduino Arduino_LSM9DS1 - magneticFieldAvailable()用法及代码示例
注:本文由纯净天空筛选整理自arduino.cc大神的英文原创作品 attachInterrupt()。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。