Bài viết này sẽ cung cấp cho bạn một cái nhìn toàn diện về ngắt ngoài (External Interrupts) trên nền tảng Arduino. Bạn sẽ được tìm hiểu về cơ chế hoạt động, cách cấu hình, các chế độ kích hoạt và các ví dụ thực tế để ứng dụng ngắt ngoài vào các dự án của mình, giúp tăng độ chính xác và hiệu quả trong việc đo thời gian và xử lý các sự kiện.
Ngắt (Interrupt) là một cơ chế cho phép một sự kiện bên ngoài hoặc bên trong vi điều khiển tạm dừng việc thực thi chương trình chính và chuyển quyền điều khiển cho một đoạn mã đặc biệt gọi là trình xử lý ngắt (Interrupt Service Routine - ISR). Sau khi ISR hoàn thành, vi điều khiển sẽ tiếp tục thực thi chương trình chính từ vị trí bị gián đoạn.
Cơ chế hoạt động của ngắt trên Arduino (sử dụng Atmega328p) diễn ra như sau:
Bạn có thể hình dung ngắt như một cuộc gọi khẩn cấp. Khi cuộc gọi đến, bạn tạm dừng mọi việc đang làm để trả lời, sau đó quay lại công việc ban đầu.
Trên Arduino, chúng ta có hai loại ngắt chính:
Bài viết này tập trung vào ngắt ngoài Arduino, một công cụ mạnh mẽ để phản ứng nhanh chóng với các sự kiện từ thế giới bên ngoài.
Để sử dụng ngắt ngoài trên Arduino, chúng ta cần hiểu rõ về các chân ngắt ngoài, các chế độ kích hoạt và các hàm liên quan.
Số lượng và vị trí của các chân ngắt ngoài khác nhau tùy theo từng loại bo mạch Arduino. Ví dụ, trên Arduino UNO, chúng ta có chân số 2 và 3 tương ứng với ngắt INT0 và INT1. Dưới đây là bảng tổng hợp các chân ngắt ngoài trên một số bo mạch Arduino phổ biến:
Khi sử dụng, hãy lưu ý rằng số hiệu vector ngắt khác với số hiệu chân IO. Để chuyển đổi giữa hai giá trị này, bạn có thể sử dụng hàm digitalPinToInterrupt()
.
Arduino cho phép bạn cấu hình chế độ kích hoạt ngắt để xác định khi nào ngắt sẽ được gọi. Các chế độ kích hoạt phổ biến bao gồm:
Việc lựa chọn chế độ kích hoạt phù hợp phụ thuộc vào yêu cầu cụ thể của ứng dụng.
attachInterrupt()
Hàm attachInterrupt()
được sử dụng để gán một hàm ISR (Interrupt Service Routine) cho một chân ngắt ngoài. Cú pháp của hàm như sau:
attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);
pin
: Số hiệu chân ngắt ngoài.ISR
: Tên của hàm ISR (không có tham số và không trả về giá trị).mode
: Chế độ kích hoạt ngắt (RISING
, FALLING
, CHANGE
, hoặc LOW
).detachInterrupt()
Hàm detachInterrupt()
được sử dụng để vô hiệu hóa ngắt ngoài đã được kích hoạt trước đó. Cú pháp của hàm như sau:
detachInterrupt(digitalPinToInterrupt(pin));
Việc tắt ngắt khi không cần thiết giúp giảm tải cho CPU và cải thiện hiệu suất hệ thống.
Dưới đây là một ví dụ đơn giản về cách sử dụng ngắt ngoài để đo thời gian giữa hai lần nhấn nút:
volatile unsigned long startTime, endTime, duration;
volatile bool measuring = false;
int interruptPin = 2;
void setup() {
Serial.begin(9600);
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), buttonPressed, FALLING);
}
void loop() {
if (measuring == false && endTime > startTime) {
duration = endTime - startTime;
Serial.print("Thời gian: ");
Serial.print(duration);
Serial.println(" ms");
startTime = 0;
endTime = 0;
}
}
void buttonPressed() {
if (measuring == false) {
startTime = millis();
measuring = true;
} else {
endTime = millis();
measuring = false;
}
}
Trong ví dụ này, chúng ta sử dụng ngắt ngoài để ghi lại thời điểm nhấn nút và tính toán khoảng thời gian giữa hai lần nhấn. Hàm buttonPressed()
là ISR được gọi mỗi khi nút được nhấn. Lưu ý rằng các biến được chia sẻ giữa ISR và chương trình chính phải được khai báo là volatile
.
volatile
cho các biến được truy cập từ cả chương trình chính và ISR.Ngắt ngoài Arduino là một công cụ mạnh mẽ cho phép bạn tạo ra các ứng dụng phản ứng nhanh chóng và hiệu quả với các sự kiện bên ngoài. Bằng cách hiểu rõ về cơ chế hoạt động, cách cấu hình và các ví dụ thực tế, bạn có thể tận dụng tối đa khả năng của ngắt ngoài để nâng cao chất lượng và hiệu suất của các dự án Arduino của mình.
Bài viết liên quan