說明
帶中斷的數字引腳
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()。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。