Arduino – Timer – Interrupt – Unicloud Blogs

Giới thiệu

Trong quá trình làm việc, bỗng nhiên bạn nhận được một yêu cầu gấp, cần phải thực hiện ngay lập tức. Lúc này, bạn buộc phải dừng công việc hiện tại để thực hiện yêu cầu đó và chỉ có thể tiếp tục công việc đang dở dang khi hoàn thành song yêu câu. Tương tự vậy, trong lập trình, chúng ta có một khái niệm, đó chính là ngắt (Interrupt).

interrupt

Hình 1. Ngắt

Ngắt là khi một tín hiệu khẩn cấp được gửi tới bộ xử lý, yêu cầu bộ xử lý tạm dừng tức khắc các hoạt động hiện tại để nhảy đến một nơi khác thực hiện một nhiệm vụ khẩn cấp nào đó, nhiệm vụ này được gọi là trình phục vụ ngắt – ISR (Interrupt Service Routine). Sau khi kết thúc trình phục vụ ngắt – ISR, bộ đếm chương trình sẽ trả về giá trị trước đó để bộ xử lý quay về thực hiện chương trình đang dang dở.

Vì sao cần sử dụng ngắt

Quay trở lại ví dụ về button đã đề cập ở phần Hello world, chúng ta phải liên tục đọc trạng thái của nút nhấn bằng hàm digitalRead() trong chương trình loop.

void loop() {
  // Đọc trạng thái của nút nhấn
  buttonState = digitalRead(buttonPin);

  // Kiểm tra nếu nút được nhấn, tức buttonState ở trạng thái LOW:
  if (buttonState == LOW) {
    // Bật LED
    digitalWrite(ledPin, HIGH);
  } else {
    // Tắt LED
    digitalWrite(ledPin, LOW);
  }
}

Điều này sẽ cực kì khó khăn khi số lượng các câu lệnh trong chương trình loop tăng lên, lúc này tốc độ đáp ứng của chương trình khi chúng ta nhấn nút sẽ không còn nhanh nữa bởi vì chương trình loop phải thực hiện song tất cả các lệnh rồi mới quay trở lại đọc trạng thái nút nhấn. Ngắt sẽ giải quyết những vấn đề này cho bạn. Lúc này, chương trình vẫn chạy liên tục những lệnh có trình chương trình loop và chỉ khi có ngắt xảy ra khi ta ấn nút nhấn thì chương trình mới thực hiện các lệnh trong chương trình phục vụ ngắt và sau đó quay trở lại thực hiện tiếp chương trình trong loop.

Điều này sẽ giúp tốc độ đáp ứng của chương trình đối với các thao tác của bạn được nhanh hơn và việc quản lý chương trình của bạn được dễ dàng và hiệu quả hơn.

Vector ngắt

Trong thực tế trên mỗi bộ xử lý đều có rất nhiều ngắt khác nhau, vậy điều gì sẽ xảy ra khi cùng một lúc có hai ngắt xuất hiện? Cũng như ví dụ đầu bài, nhưng bây giờ bạn nhận đến 2 yêu cầu cần thực hiện gấp, vậy bạn sẽ thực hiện yêu cầu nào? Tất nhiên là sẽ ưu tiên yêu cầu cấp thiết nhất, sau khi hoàn thành thì mới thực hiện yêu cầu tiếp theo và cuối cùng là trở lại công việc đang làm dở. Cũng như trong lập trình, mỗi ngắt đều được quy định một mức ưu tiên khác nhau, được gọi là vector ngắt (vector ngắt có giá trị càng nhỏ thì độ ưu tiên càng cao), Reset là ngắt có mức ưu tiên cao nhất.

Ngắt trong Arduino

Trong khuôn khổ của Arduino và mục tiêu của sách là đơn giản hóa mọi vấn đề để các bạn mới bắt đầu dễ dàng tiếp cần thì chúng ta sẽ không đi sâu vào vấn đề này.

Trong Arduino, chúng ta được hỗ trợ 2 loại ngắt như sau:

  • Ngắt số 0 được nối với chân số 2.

  • Ngắt số 1 được nối với chân số 3.

Để sử dụng ngắt chúng ta cần phải kết nối nút nhấn hoặc cảm biến vào hai chân này để tạo tín hiệu ngắt cho bộ xử lý.

Tùy thuộc vào vi điều khiển trên board mà mỗi dòng Arduino có số lượng các ngắt khác nhau. Bạn có thể tham khảo bảng sau:

Bảng 1. Số lượng ngắt trên các Board Arduino

Board
Int.0
Int.1
Int.2
Int.3
Int.4
Int.5

Uno. Ehternet

2

3

.

.

.

.

Mega2560

2

3

21

20

19

18

Leonardo

2

3

0

1

7

.

Arduino hỗ trợ 2 lệnh giúp ta khai báo và hủy một ngắt bất kì một cách dễ dàng đó là attachInterrupt()detachInterrupt().

Lệnh attachInterrupt()

  • Mục đích: Giúp khai báo một ngắt.

  • Cú pháp lệnh: attachInterrupt(interrupt, ISR, mode).

  • Các đối số:

    • interrupt: Lựa chọn ngắt mà bạn muốn dùng, với Arduino Uno có 2 lựa chọn là:

      • 0: Ứng với ngắt số 0 trong Arduino (chân số 2).

      • 1: Ứng với ngắt số 1 trong Arduino (chân số 3).

    • ISR: Chương trình phục vụ ngắt. Chương trình này sẽ được thực hiện khi có ngắt xảy ra.

    • mode: Kiểu kích hoạt ngắt:

      • LOW: Ngắt sẽ được kích hoạt khi trạng thái chân ở mức thấp.

      • HIGH: Ngắt sẽ được kích hoạt khi trạng thái chân ở mức cao.

      • CHANGE: Ngắt khi có sự thay đổi trạng thái trên chân ngắt (trạng thái thay đổi từ mức điện áp thấp lên mức điện áp cao hoặc ngược lại, từ mức điện áp cao xuống mức điện áp thấp.

      • RISING: Ngắt sẽ được 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: Ngắt sẽ được 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.

Trong mode LOW và HIGH, chương trình ngắt sẽ được gọi liên tục khi chân digital vẫn còn giữ ở mức điện áp thấp hoặc cao.

  • Giá trị trả về: Không có giá trị trả về

Lệnh detachInterrupt()

  • Mục đích: Tắt ngắt hiện tại.

  • Cú pháp lệnh: detachInterrupt(pin).

  • Các đối số:

    • pin: Lựa chọn ngắt mà bạn muốn tắt, dùng board Arduino Uno có 2 lựa chọn là:

      • 0: Tắt ngắt số 0 trong Arduino ( chân số 2).

      • 1: Tắt ngắt số 1 trong Arduino ( chân số 3).

  • Giá trị trả về : Không có giá trị trả về.

Rate this post

Viết một bình luận