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