Arduino 中的中斷
什麼是中斷?
顧名思義,中斷是打斷正常程式碼流程的例程。中斷例程包含一段程式碼,當發生事件時,板上的微控制器應該執行這段程式碼。以空調為例。假設它有以下溫度控制設定:當溫度達到 18 攝氏度時,關閉冷卻功能。現在,將有一個溫度感測器不斷測量溫度。每當它報告溫度為 18 攝氏度時,空調微控制器上執行的正常程式碼就會被中斷,它會執行關閉冷卻功能的程式碼,然後恢復正常程式碼。
中斷何時觸發?
觸發中斷的方法有很多。您可以透過按下按鈕來觸發中斷(基本上是當引腳狀態從高電平到低電平或從低電平到高電平發生變化時)。您可以使用基於定時器的中斷,這些中斷以固定的時間間隔觸發,您可以透過 UART、SPI 或 Wire 等接收資料時觸發中斷,等等。可用的中斷列表可以在這裡找到:http://gammon.com.au/interrupts
定義中斷服務例程
每當發生中斷事件時執行的程式碼儲存在一個特殊型別的函式中,稱為中斷服務例程。它們有以下限制:
- 它們不應接收任何引數/引數
- 它們不能返回任何內容
如果程式碼中有多箇中斷,每個中斷都有自己的中斷服務例程 (ISR),那麼一次只能執行一個 ISR。另外,請注意以下內容(來自 Arduino 文件):
- millis() 在 ISR 內部不會遞增,因為它依賴於中斷來遞增自身。由於兩個 ISR 不能同時執行,因此 millis 不能在 ISR 內部遞增
- 同樣,delay() 也不適用於中斷,因為它需要中斷才能工作
- delayMicroseconds() 不需要中斷才能工作,因此它將在中斷內正常工作
- micros() 最初可以工作,但在 1-2 毫秒後行為不可預測
在 ISR 內更改變數
如果希望在 ISR 內更改變數的值,則需要將變數宣告為 volatile。
因此,
int p1 = 1;
變成
volatile int p1 = 1;
示例實現
我們將考慮按鈕中斷。更具體地說,是在檢測到某個引腳上的上升沿或下降沿時觸發的中斷。現在,並非板的所有引腳都可以用於中斷程式碼。每個板都有一些特定的引腳保留用於外部中斷。列表可以在這裡找到:https://www.arduino.cc/reference/en/language/functions/external-interrupts/attachinterrupt/
從上面的連結可以看出,Arduino Uno 的引腳 2 和 3 可用於外部中斷。
現在,中斷應該非常快地執行。因此,我們在中斷內部要做的只是設定一個標誌。然後在迴圈中,每當標誌被設定時,我們都會列印一個語句,然後將標誌重新設定為 0。
最重要的主要函式是 attachInterrupt()。
語法如下:
語法
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode)
這裡,引腳是引腳號,ISR 是 ISR 函式的名稱,並且模式可以是以下之一:
- RISING:每當在引腳上看到低電平到高電平的轉換時
- FALLING:每當在引腳上看到高電平到低電平的轉換時
- LOW:每當引腳處於低電壓時
- CHANGE:每當引腳看到電壓變化(高電平到低電平或低電平到高電平)時
在某些開發板上(Due、MKR1000 和 Zero),您也可以使用 HIGH 模式:每當引腳處於高電壓時。
電路圖和示例程式碼如下所示。
電路圖
從下面的電路圖可以看出,每當按下按鈕開關時,引腳 2 就會連線到 GND,並且會在該引腳上觀察到下降沿(高電平到低電平),因為它通常被上拉(模式 INPUT_PULLUP)。此下降沿將生成中斷。

示例
const int interruptPin = 2;
volatile bool isButtonPressed = false;
void setup() {
Serial.begin(9600);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), button_pressed, FALLING);
}
void loop() {
if(isButtonPressed){
Serial.println("Button Pressed!");
isButtonPressed = false;
}
}
void button_pressed() {
isButtonPressed = true;
}
資料結構
網路
RDBMS
作業系統
Java
iOS
HTML
CSS
Android
Python
C 程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP