Cấu hình & xử lý ngắt GPIO ESP32 trong Arduino IDE
Interrupts trên ESP32
* ESP32 tích hợp 32 interrupt, mỗi interrupt đều có cấu hình độ ưu tiên nhất định. Có thể chia làm 2 loại interrupt.
Hardware Interrupts – Được kích hoạt từ các sự kiện bên ngoài thông qua GPIO, ví dụ: GPIO, Touch ( ngắt khi chạm).
Software Interrupts – Được kích hoạt từ các sự kiện bên trong, ví dụ:Timer, Watchdog.
Attaching Interrupt to a GPIO Pin.
Trong Arduino IDE, chúng ta sử dụng một hàm có tên là attachmentInterrupt () để đặt ngắt trên cơ sở từng chân.
Hàm này nhận ba tham số:
GPIOPin - Đặt chân GPIO làm chân ngắt, cho ESP32 biết chân nào cần giám sát.
ISR - Là tên của hàm sẽ được gọi mỗi khi ngắt được kích hoạt
Mode - Xác định khi nào ngắt nên được kích hoạt.
Mode : Ta chọn những Mục sau.
LOW : Interrupt Hoạt động (kích hoạt) Mức Thấp 0 .
HIGH : Interrupt Hoạt động (kích hoạt) Mức Cao 1.
CHANGE : Interrupt Kích hoạt ngắt bất cứ khi nào chân thay đổi giá trị, từ CAO thành THẤP hoặc THẤP đến CAO
FALLING : Interrupt Kích hoạt ngắt khi chân đi từ CAO xuống THẤP
RISING : Interrupt Kích hoạt ngắt khi chân đi từ THẤP đến CAO
Detaching Interrupt from a GPIO Pin
( Xóa Interrupt trên PIN).
Hàm xóa Interrupt: detachInterrupt(GPIOPin);
- Giả sử bạn đang xử dụng chân số 15 sử dụng interrupt. bây giờ bạn không muốn nó là chân interrupt nữa bạn dùng hàm sau :detachInterrupt(15);
Chương trình con Interrupt.
- Khi có Interrupt xãy ra ( ngắt xảy ra ) niếu được chấp thuận, nó sẽ nhãy vào chương trình con.
void IRAM_ATTR ISR() {
Statements;
}
attachInterrupt(GPIOPin, ISR, Mode);
ISR : VỊ TRÍ CHƯƠNG TRÌNH CON.
KẾT NỐI PHẦN CỨNG NHƯ SAU:
Ví dụ: Ngắt đơn giản
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
Button button1 = {18, 0, false};
void IRAM_ATTR isr() {
button1.numberKeyPresses += 1;
button1.pressed = true;
}
void setup() {
Serial.begin(115200);
pinMode(button1.PIN, INPUT_PULLUP);
attachInterrupt(button1.PIN, isr, FALLING);
}
void loop() {
if (button1.pressed) {
Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses);
button1.pressed = false;
}
//Detach Interrupt after 1 Minute
static uint32_t lastMillis = 0;
if (millis() - lastMillis > 60000) {
lastMillis = millis();
detachInterrupt(button1.PIN);
Serial.println("Interrupt Detached!");
}
}
KẾT QUẢ:
Giải thích code
Ban đầu, chúng ta khai báo một struct có tên Button. Struct này lưu các biến là thứ tự GPIO, số lần nút nhấn và trạng thái nút nhấn.
struct Button {
const uint8_t PIN;
uint32_t numberKeyPresses;
bool pressed;
};
Tiếp theo chúng ta khải báo một biến struct Button, thứ tự GPIO là 18, số lần nút nhấn là 0 và trạng thái nút nhấn là false.
Button button1 = {18, 0, false};
Chúng ta khai báo một hàm ISR với thuốc tính IRAM_ATTR
Trong hàm ISR, thực hiện tăng dần số lần nhấn và thay đổi trạng thái nút nhấn thành true
void IRAM_ATTR isr() {
button1.numberKeyPresses += 1;
button1.pressed = true;
}
Trong hàm Setup(), chúng ta khởi tạo giao tiếp Serial và GPIO thứ 18 là ngõ vào có điện trở kéo lên.
Tiếp đó, ta báo cho ESP32 biết rằng khi có interrupt FALLING tại chân D18 hàm isr sẽ được gọi.
Serial.begin(115200); pinMode(button1.PIN, INPUT_PULLUP); attachInterrupt(button1.PIN, isr, FALLING);
Trong Loop(), chúng ta đơn giản chỉ kiểm tra trạng thái nút đã được nhấn và in ra số lần nút được nhấn.
if (button1.pressed) { Serial.printf("Button 1 has been pressed %u times\n", button1.numberKeyPresses); button1.pressed = false; }
Trong Loop(), chúng ta kiểm tra thời gian chương trình đã chạy millis()
, nếu thời gian này lớn hơn 1 phút thì chân D18 sẽ bị xóa interrupt detachInterrupt()
.
static uint32_t lastMillis = 0; if (millis() - lastMillis > 60000) { lastMillis = millis(); detachInterrupt(button1.PIN); Serial.println("Interrupt Detached!"); }