基礎教程11 Arduino中斷介紹

基礎教程11 Arduino中斷介紹

來自專欄 Arduino 魔法書1 人贊了文章

我是潘,曾經是個工程師。這是為 Ardui.Co 製作的 「Arduino 公開課」 系列的入門教程。前面我們已經學會了Arduino最基本的使用,現在要介紹一些更高級的玩法:中斷,看看怎樣打斷 Arduino loop() 的循環,去執行其他任務。有任何疑問請在評論區提出,我會逐一回答。

日常生活中,中斷是一個很容易理解的概念。比如,正在寫這篇教程稿,突然間手機響了,我去接電話,通話完畢,繼續寫。這個過程就是「中斷」和「中斷處理」。鈴聲讓我中斷當前的工作,去處理更緊急的事情,處理完後,再回頭原來的工作。

電話鈴響叫做「中斷請求」,暫停寫稿稱為「中斷響應」,接電話過程就是「中斷處理」。Arduino 執行任務過程中,出現某個事件,轉而執行這一事件的程序,執行完後,再回到中斷點繼續原來的任務,就是中斷程序。

為什麼要使用中斷呢?再舉個例子,你來拜訪我,但我不知道你何時到達,你到達門口就只能在外面等著。如果門口裝個門鈴,你按一下門鈴,我就會中斷當下的工作(比如準備晚餐)去開門,這就避免了等待和浪費時間,提高處理器的執行效率。

產生中斷請求的方式,一般有三類:

  1. 程序或硬體出現異常或故障,稱為「異常中斷」;
  2. 程序執行了設定好的中斷指令(即定時器),稱為「內部中斷」;
  3. 感測器、按鈕等外部設備提出中斷請求,稱為「外部中斷」;(沒錯!開發板上 Reset 按鈕就是其一)

這三類中斷裡面,外部中斷最常用也最好理解,內部中斷講起來有點複雜,處理異常中斷則是一個嚴肅的難題。所以遵從從易到難的原則,我們先從外部中斷開始介紹。

對大部分 Arduino 來說,要促發外部中斷,就要用特定的引腳,不同版本 Arduino 的中斷埠的位置、編號也不同。我們一直使用的 Uno ,規定 D2、D3 是中斷觸發埠,在中斷函數的參數裡面,編號分別為 0、1。而 Due、101 等版本最厲害,所有埠都可以能觸發中斷:

更多 Arduino 版本可以參考官方文檔。

要使用中斷程序,可以直接調用 :

attachInterrupt(interrupt, ISR, mode)

參數含義如下:

interrupt:中斷埠編號,Uno 只有0、1(即D2、D3)兩個埠

ISR:中斷服務程序,即中斷後要執行的程序

mode:中斷請求的方式,可以設置成下面4種:

LOW 當引腳為低電平時,觸發中斷

CHANGE 當引腳電平發生改變時,觸發中斷

RISING 當引腳由低電平變為高電平時,觸發中斷

FALLING 當引腳由高電平變為低電平時,觸發中斷

使用 attachInterrupt() 時要注意以下幾點:

1、中斷函數不能帶參數,也沒有返回值;

2、中斷函數中,delay函數不能使用;

3、讀取串口數據的話,可能會丟失(原因後面的課程講);

4、中斷函數裡面,使用的變數需要定義為 volatile 型。

這是官方給出的例子:

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()//改變LED的狀態,如果是LOW,則改為HIGH,反之亦然{ state = !state;}

根據官方文檔建議,採用 digitalPinToInterrupt(pin) 可以自動識別不同版本的 Arduino,自動映射中斷埠。比如,interruptPin 設置為 D2,在 Uno 上自動映射為中斷埠 0,在 Leonardo 上自動映射為1,非常方便,且提高了程序兼容性。

在下一節課,我們將以實際例子來介紹外部中斷的應用。


推薦閱讀:

OpenMV機器視覺-視頻教程01-介紹
構建開源硬體的 5 個關鍵點
無顯示器照樣玩樹莓派——VNC伺服器搭建

TAG:開源硬體 | 單片機 | Arduino |