中斷用于處理在程序正常執(zhí)行期間不發(fā)生但在特定觸發(fā)發(fā)生時發(fā)生的事件。例如,如果我們編寫一個使 LED 閃爍的程序,微控制器將一個一個地執(zhí)行每個命令。但是如果我們想監(jiān)控一個開關(guān)來開始或停止閃爍,只有在所有其他任務(wù)完成之后才能完成檢查,即它不會是實時的。這就是中斷發(fā)揮作用的地方。有了中斷,我們就不需要不斷地檢查數(shù)字輸入引腳的狀態(tài)。當(dāng)發(fā)生中斷時,控制器停止執(zhí)行主程序,并調(diào)用稱為 ISR 或中斷服務(wù)程序的函數(shù)。然后控制器執(zhí)行 ISR 內(nèi)部的任務(wù),然后在 ISR 執(zhí)行完成后返回主程序。
ESP32 的每個內(nèi)核共有 32 個中斷。每個中斷都有一定的優(yōu)先級,大多數(shù)(但不是全部)中斷都連接到中斷多路復(fù)用器。因為中斷源比中斷多,所以有些中斷是與多個中斷源共享的。
ESP32中的中斷類型
ESP32 中中斷的主要分類是基于中斷源。它們是硬件中斷和軟件中斷。
外部或硬件中斷
硬件中斷響應(yīng)外部硬件事件而發(fā)生。例如,當(dāng)檢測到觸摸時會發(fā)生觸摸中斷,而當(dāng) GPIO 引腳的狀態(tài)發(fā)生變化時會發(fā)生 GPIO 中斷。GPIO 中斷和觸摸中斷屬于這一類。
軟件中斷
當(dāng)觸發(fā)軟件事件(例如定時器溢出)時,會發(fā)生這種類型的中斷。定時器中斷是軟件中斷的一個例子。我們將在即將發(fā)布的 ESP32 定時器專用教程中討論有關(guān)定時器的更多信息。
ESP32 GPIO 中斷
使用 ESP32,我們可以將所有 GPIO 引腳配置為硬件中斷源。我們可以通過將這些 GPIO 引腳連接到相應(yīng)的 ISR 來啟用中斷。要附加中斷,我們將使用attchInterrupt() 宏。attachInterrupt() 宏的用法如下-
附加中斷(GPIOpin,ISR,事件);
attachInterrupt() 函數(shù)接受三個參數(shù):
GPIOpin:此參數(shù)指示要附加中斷的 GPIO 引腳號。
ISR:第二個參數(shù)是每次觸發(fā)中斷時會調(diào)用的函數(shù)名。
事件:第三個參數(shù)表示應(yīng)該在哪個事件觸發(fā)中斷。五個可能的事件如下。
LOW:當(dāng)引腳為低電平時觸發(fā)中斷
HIGH:當(dāng)引腳為高電平時觸發(fā)中斷
CHANGE:每當(dāng)引腳改變值時觸發(fā)中斷,從 HIGH 到 LOW 或 LOW 到 HIGH
FALLING:當(dāng)引腳從 HIGH 變?yōu)?LOW 時觸發(fā)中斷
RISING:當(dāng)引腳從 LOW 變?yōu)?HIGH 時觸發(fā)中斷
因此,例如,要在 GPIO4 的狀態(tài)發(fā)生變化時觸發(fā)中斷,我們可以使用attachInterrupt函數(shù),如下所示:
附加中斷(4,ISR,改變);
如何禁用中斷?
在某些情況下,我們將不得不暫時禁用中斷。對于這種情況,我們可以使用detachInterrupt函數(shù)。一旦為特定引腳調(diào)用此函數(shù),附加到該引腳的中斷將被禁用,直到再次調(diào)用 attachInterrupt 函數(shù)或系統(tǒng)重新啟動。使用它的語法如下 -
分離中斷(GPIOPin);
中斷服務(wù)程序或 ISR
這將是觸發(fā)特定中斷時調(diào)用的函數(shù)。語法如下:
void IRAM_ATTR ISR() {
語句;
}
其中ISR是函數(shù)名,語句是調(diào)用這個函數(shù)時應(yīng)該完成的任務(wù)。由于 ISR 正在阻塞主程序,因此建議使用它來執(zhí)行盡可能小的任務(wù)。參數(shù)IRAM_ATTR將確保 ISR 功能放置在 IRAM 區(qū)域而不是閃存區(qū)域。這將確保 ISR 函數(shù)加載速度更快。
硬件示例——打開或關(guān)閉 LED
在此示例中,我們將使用按鈕開關(guān)打開和關(guān)閉 LED。但我們將使用 GPIO 中斷,而不是使用輪詢。為此,請在面包板上進(jìn)行連接,如下圖所示。
這是根據(jù)電路圖連接在面包板上的實際電路。
#define pushButton_pin 33
#define LED_pin 32
void IRAM_ATTR toggleLED()
{
digitalWrite(LED_pin, !digitalRead(LED_pin));
}
void setup()
{
pinMode(LED_pin, OUTPUT);
pinMode(pushButton_pin,INPUT_PULLUP);
attachInterrupt(pushButton_pin,toggleLED,RISING);
}
無效循環(huán)()
{
}
只要按下按鈕,GPIO33 的電壓就會下降到 0V。當(dāng)松開按鈕時,電壓會上升到 VCC。當(dāng)電壓上升時,將觸發(fā)中斷并調(diào)用相應(yīng)的 ISR toggleLED。因為 ISR 只會在上升沿觸發(fā),所以去抖會被消除。
ESP32 觸摸中斷
就像 GPIO 中斷一樣,ESP32 在其 10 個觸摸輸入上支持觸摸中斷。使用觸摸中斷也類似。要附加觸摸中斷,我們將使用touchAttachInterrupt函數(shù)。它的語法如下:
touchAttachInterrupt(GPIOPin,ISR,閾值)
這里的GPIOPin是支持觸摸輸入的引腳,ISR 是 ISR 功能,Threshold 是應(yīng)該觸發(fā)中斷的觸摸值。其他一切都與 GPIO 中斷示例相同。
評論
查看更多