Arduino 中斷

2020-10-21 16:49 更新

中斷(interrupt)停止Arduino的當前工作,以便可以完成一些其他工作。

假設你坐在家里和別人聊天。突然電話響了。停止聊天,拿起電話與來電者通話。當你完成電話交談后,你回去和電話響之前的那個人聊天。

同樣,你可以把主程序想象成是與某人聊天,電話鈴聲使你停止聊天。中斷服務程序是在電話上通話的過程。當通話結(jié)束后,你回到你聊天的主程序。這個例子準確地解釋了中斷如何使處理器執(zhí)行操作。

主程序在電路中運行并執(zhí)行一些功能。但是,當發(fā)生中斷時,主程序在另一個程序執(zhí)行時停止。當這個程序結(jié)束時,處理器再次返回主程序。

中斷

重要特征

這里有一些關(guān)于中斷的重要特征:

  • 中斷可以來自各種來源。在這種情況下,我們使用的是由數(shù)字引腳上的狀態(tài)改變觸發(fā)的硬件中斷。

  • 大多數(shù)Arduino設計有兩個硬件中斷(稱為“interrupt0”和“interrupt1”)分別硬連接到數(shù)字I/O引腳2和3。

  • Arduino Mega有六個硬件中斷,包括引腳21,20,19和18上的附加中斷(“interrupt2”到“interrupt5”)。

  • 你可以使用稱為“中斷服務程序”(Interrupt Service Routine,通常稱為ISR)的特殊函數(shù)來定義程序。

  • 你可以定義該程序并指定上升沿,下降沿或兩者的條件。在這些特定條件下,將處理中斷。

  • 每次在輸入引腳上發(fā)生事件時,都可以自動執(zhí)行該函數(shù)。

中斷類型

有兩種類型的中斷:

  • 硬件中斷 - 它們響應外部事件而發(fā)生,例如外部中斷引腳變?yōu)楦唠娖交虻碗娖健?/span>

  • 軟件中斷 - 它們響應于在軟件中發(fā)送的指令而發(fā)生。“Arduino語言”支持的唯一類型的中斷是attachInterrupt()函數(shù)。

在Arduino中使用中斷

中斷在 Arduino 程序中非常有用,因為它有助于解決時序問題。中斷的良好應用是讀取旋轉(zhuǎn)編碼器或觀察用戶輸入。一般情況下,ISR 應盡可能短且快。如果你的草圖使用多個 ISR,則一次只能運行一個。其他中斷將在當前完成之后執(zhí)行,其順序取決于它們的優(yōu)先級。

通常,全局變量用于在 ISR 和主程序之間傳遞數(shù)據(jù)。為了確保在 ISR 和主程序之間共享的變量正確更新,請將它們聲明為 volatile。

Arduino 中主要有時鐘中斷和外部中斷,本文所說的中斷指的是外部中斷。Arduino 中的外部中斷通常是由Pin 口(數(shù)字 Pin 口,不是模擬口)電平改變觸發(fā)的。每種型號的 Arduino 版都有數(shù)個 Pin 口可以用來注冊中斷,具體如下:

開發(fā)板 可以用來注冊中斷的Pin口
Uno, Nano, Mini, other 328-based 2, 3
Uno WiFi Rev.2 所有數(shù)字口
Mega, Mega2560, MegaADK 2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based 0, 1, 2, 3, 7
Zero 除了4號口外的所有數(shù)字口
MKR Family boards 0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Due 所有數(shù)字口
101 所有數(shù)字口 (只有 2, 5, 7, 8, 10, 11, 12, 13數(shù)字口可以使用 ?CHANGE類型中斷,中斷類型在下文有介紹)

注冊中斷主要是通過? attachInterrupt() ?函數(shù)實現(xiàn)的,其原型為:

void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode);
  1. 第一個參數(shù)為中斷號,Arduino上每個可以注冊中斷的Pin口都會被分配一個中斷號,這里需要傳入的是中斷號而不是Pin口號。但是不同的Arduino開發(fā)板上面的中斷號分配并不完全一樣。各個開發(fā)板的Pin口號和中斷號對應關(guān)系如下:
     開發(fā)板  中斷號0  中斷號1  中斷號2  中斷號3  中斷號4  中斷號5
     Uno, Ethernet  PIN 2  PIN 3        
     Mega2560  PIN 2  PIN 3  PIN 21  PIN 20  PIN 19  PIN 18
     基于32u4的開發(fā)板 如 Leonardo, Micro  PIN 3  PIN 2  PIN 0  PIN 1  PIN 7  
    從上表中可以看出同一個 Pin 口在不同的開發(fā)板上可能會有不同的中斷號,這勢必會影響程序的可移植性。幸運的是,Arduino 還提供了另一個函數(shù) digitalPinToInterrupt(int)。從名字就能看出,這個函數(shù)能輸入 Pin 口號并輸出對應的中斷號。需要注意的是,輸入的 Pin 口號需要在上述的支持列表當中。所以,Arduino 官方推薦我們使用 
    attachInterrupt(digitalPinToInterrupt(pin), ISR, mode); 
    這種方式來注冊中斷號。
  2. 第二個參數(shù)是中斷服務例程(ISR)的函數(shù)指針,在 C/C++ 中直接寫該函數(shù)的函數(shù)名即可。在觸發(fā)時,該函數(shù)將會被調(diào)用。該函數(shù)必須沒有任何的參數(shù)也沒有任何的返回值。
  3. 第三個參數(shù)是中斷觸發(fā)條件,由幾個可選的值:
    LOW 當中斷所在 Pin 口處于低電平時觸發(fā)
    CHANGE 當中斷所在 Pin口電平改變時觸發(fā)
    RISING 當中斷所在Pin口從低電平變?yōu)楦唠娖?上升沿)時觸發(fā)
    FALLING 當中斷所在Pin口從高電平變?yōu)榈碗娖?下降沿)時觸發(fā)
    對于 Due,Zero 和 MKR1000開發(fā)板,還有一個 HIGH 表示當中斷所在 Pin 口處于高電平時觸發(fā)

示例

int pin = 2; //define interrupt pin to 2
volatile int state = LOW; // To make sure variables shared between an ISR
//the main program are updated correctly,declare them as volatile.

void setup() {
   pinMode(13, OUTPUT); //set pin 13 as output
   attachInterrupt(digitalPinToInterrupt(pin), blink, CHANGE);
   //interrupt at pin 2 blink ISR when pin to change the value
} 
void loop() { 
   digitalWrite(13, state); //pin 13 equal the state value
} 

void blink() { 
   //ISR function
   state = !state; //toggle the state when the interrupt occurs
}

attachInterrupt語句語法

attachInterrupt(digitalPinToInterrupt(pin),ISR,mode);//recommended for arduino board
attachInterrupt(pin, ISR, mode) ; //recommended Arduino Due, Zero only
//argument pin: the pin number
//argument ISR: the ISR to call when the interrupt occurs; 
   //this function must take no parameters and return nothing. 
   //This function is sometimes referred to as an interrupt service routine.
//argument mode: defines when the interrupt should be triggered.

在 Arduino 中使用中斷需要注意的問題

  1. 由于中斷會打斷正常代碼的運行,因此 ISR 的應該盡可能快地執(zhí)行完畢。
  2. 在 ISR 中修改的全局變量要用 volatile 修飾符修飾以防止編譯器優(yōu)化
  3. 在 ISR 中不能使用其他用中斷實現(xiàn)的函數(shù),如 millis() delay() 等。延時可以使用  delayMicroseconds(),它不是用中斷實現(xiàn)的。





以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號