Home Internet of Things - IoT attachInterrupt() – Ngắt trong Arduino

attachInterrupt() – Ngắt trong Arduino

by Khanh Tran

Ngắt (interrupt) là gì? Đó là khi hệ thống sinh ra một sự kiện, lúc đó chương trình sẽ gọi một hàm một cách tự động. Những sự kiện này được nhà sản xuất vi điều khiển thiết lập bằng phần cứng và được cấu hình trong phần mềm bằng những funtions có tên gọi cố định (attachInterrupt()).

Vì ngắt hoạt động độc lập và tự sinh ra khi được cấu hình nên nó sẽ tức thời và không bị ảnh hưởng bởi chương trình chính, chương trình chính sẽ đơn giản hơn. Một ví dụ điển hình về ngắt là hàm millis(). Hàm này tự động chạy cùng với chương trình và trả về 1 con số tăng dần theo thời gian mặc dù chúng ta không cài đặt nó.

Ý nghĩa và tác dụng của ngắt là gì? Tại sao chúng ta cần dùng đến ngắt?

Ngắt giúp chương trình gọn nhẹ và xử lý nhanh hơn. Chẳng hạn, khi kiểm tra 1 nút nhấn có được nhấn hay không, thông thường bạn cần kiểm tra trạng thái nút nhấn bằng hàm digitalRead() trong đoạn chương trình loop(). Cách này sẽ gây ra độ trễ lớn nếu chương trình loop() phức tạp và sử dụng nhiều delay(). Gây ra sai số nếu chúng ta nhấn nút liên tiếp.

Với việc sử dụng ngắt attachInterrupt(), bạn chỉ cần nối nút nhấn đến đúng chân có hỗ trợ ngắt. Sau đó cài đặt ngắt sẽ sinh ra khi trạng thái nút chuyển từ HIGH->LOW. Thêm 1 tên hàm sẽ gọi khi ngắt sinh ra. Vậy là xong, biến trong đoạn chương trình ngắt sẽ cho ta biết trạng thái nút nhấn một cách tức thời và chuẩn xác.

Digital Pins With Interrupts

Tham số đầu tiên attachInterrupt()là số thứ tự của ngắt. Thông thường, bạn nên sử dụng digitalPinToInterrupt(pin)để dịch chân digital thực tế thành số thứ tự ngắt cụ thể. Ví dụ: nếu bạn kết nối với chân 3, hãy sử dụng digitalPinToInterrupt(3)làm tham số đầu tiên attachInterrupt().

BOARDDIGITAL PINS USABLE FOR INTERRUPTS
Uno, Nano, Mini, other 328-based2, 3
Uno WiFi Rev.2, Nano Everyall digital pins
Mega, Mega2560, MegaADK2, 3, 18, 19, 20, 21
Micro, Leonardo, other 32u4-based0, 1, 2, 3, 7
Zeroall digital pins, except 4
MKR Family boards0, 1, 4, 5, 6, 7, 8, 9, A1, A2
Nano 33 IoT2, 3, 9, 10, 11, 13, 15, A5, A7
Nano 33 BLE, Nano 33 BLE Senseall pins
Dueall digital pins
101all digital pins (Only pins 2, 5, 7, 8, 10, 11, 12, 13 work with CHANGE)

Lưu ý:

Bên trong attached function, delay()sẽ không hoạt động và giá trị được trả về millis()sẽ không tăng lên. Serial data nhận được khi ở trong function có thể bị mất. Bạn nên khai báo dưới dạng volatile cho bất kỳ biến nào mà bạn sửa đổi trong attached function. Xem phần ISR bên dưới để biết thêm thông tin.

Sử dụng ngắt

Syntax

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode) (recommended)
attachInterrupt(interrupt, ISR, mode) (not recommended)
attachInterrupt(pin, ISR, mode) (Not recommended. Additionally, this syntax only works on Arduino SAMD Boards, Uno WiFi Rev2, Due, and 101.)

Đây là nguyên văn trong trang chủ của Arduino.cc.

Giải thích các thông số trong attachInterrupt():

interrupt: Số thứ tự của ngắt. Trên Arduino Uno, bạn có 2 ngắt với số thứ tự là 0 và 1. Ngắt số 0 nối với chân digital số 2 và ngắt số 1 nối với chân digital số 3. Muốn dùng ngắt bạn phải gắn nút nhấn hoặc cảm biến vào đúng các chân này thì mới sinh ra sự kiện ngắt. Nếu dùng ngắt số 0 mà gắn nút nhấn ở chân digital 4 thì không chạy được rồi.

pin: Arduino pin number.

ISR: tên hàm sẽ gọi khi có sự kiện ngắt được sinh ra.

mode: kiểu kích hoạt ngắt, bao gồm:

  • LOW: kích hoạt liên tục khi trạng thái chân digital có mức thấp
  • HIGH: kích hoạt liên tục khi trạng thái chân digital có mức cao.
  • RISING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp thấp sang mức điện áp cao.
  • FALLING: kích hoạt khi trạng thái của chân digital chuyển từ mức điện áp cao sang mức điện áp thấp.

Lưu ý: với mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital còn giữ mức điện áp tương ứng.

Example Code attachInterrupt()

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() {
  state = !state;
}
Hình 1: interrupt trong Arduino

attachInterrupt() sẽ rất hữu dụng trong một project arduino. Hãy sử dụng nó một cách linh hoạt bạn nhé.

You may also like

Leave a Comment