17 C
Hanoi
Thứ Sáu, Tháng Mười Hai 3, 2021
Home LẬP TRÌNH VI ĐIỀU KHIỂN ARDUINO Ngắt ngoài trên Arduino

Ngắt ngoài trên Arduino

Ngắt là gì?

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ở.

Ngắt là một trong 2 kỹ thuật “bắt” sự kiện cơ bản là hỏi vòng (Polling) và ngắt.

Xét ví dụ:

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);
  }
}

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(). Đ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.

So sánh hỏi vòng và ngắt

Đối với cơ chế hỏi vòng, VI ĐIỀU KHIỂN liên tục thực thi một đoạn mã lệnh để kiểm tra xem I/O module đã sẵn sàng chưa, nếu sẵn sàng rồi thì bắt đầu tương tác.

  • Ưu điểm: VI ĐIỀU KHIỂN nhanh chóng tương tác với I/O module ngay khi I/O module đã sẵn sàng. Cơ chế này phù hợp với các I/O module tốc độ cao, ví dụ I/O module trong các bộ chuyển mạch/định tuyến của mạng lõi.
  • Nhược điểm: Đối với các I/O module làm việc ở tốc độ thấp, nếu áp dụng cơ chế này thì VI ĐIỀU KHIỂN phải đợi mất nhiều thời gian trước khi I/O module sẵn sàng, nên không hiệu quả.

Đối với cơ chế ngắt, VI ĐIỀU KHIỂN cứ việc thực thi các công việc khác. Khi nào I/O module muốn tương tác với VI ĐIỀU KHIỂN, nó sẽ gửi một tín hiệu đến VI ĐIỀU KHIỂN. VI ĐIỀU KHIỂN sẽ tạm dừng công việc đang làm, lưu lại trạng thái của công việc đó, rồi chuyển sang tương tác với I/O module. Sau khi tương tác xong, VI ĐIỀU KHIỂN sẽ khôi phục lại công việc đang làm dở.

  • Ưu điểm: Đối với các I/O module làm việc ở tốc độ thấp, nếu áp dụng cơ chế này thì thời gian của VI ĐIỀU KHIỂN được sử dụng hiệu quả. VI ĐIỀU KHIỂN có thể chuyển qua thực hiện công việc khác trong lúc I/O module chưa sẵn sàng.
  • Nhược điểm: Do mỗi lần ngắt, VI ĐIỀU KHIỂN mất một khoảng thời gian để lưu lại công việc đang làm dở, nên không thể tương tác với I/O module ngay được. Với các I/O module tốc độ cao, khoảng thời gian giữa những lần ngắt có thể còn nhỏ hơn cả khoảng thời gian lưu/khôi phục công việc đang làm dở. Khi đó, cơ chế này không còn hiệu quả nữa.

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 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:

Cấu trúc của hàm ngắt trong Arduino

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() và detachInterrupt().

Lệnh attachInterrupt(): Giúp khai báo một ngắt

attachInterrupt(interrupt, ISR, mode)

hay attachInterrupt(thứ tự ngắttên chương trình con thực hiện ngắtchế độ ngắt)
trong đó:thứ tự ngắt: có kiểu (int), ta điền số 0 đối với ngắt 0, số 1 đối với ngắt 1. Tên chương trình con thực hiện ngắt: khai báo một chương trình con, để khi sự kiện ngắt xảy ra thì sẽ thực hiện chương trình con đó.Chế độ ngắt: khai báo kiểu ngắt, có 4 kiểu ngắt.

  • LOW: ngăt mức thấp, thực hiện chương trình ngắt khi chân ngắt ở mực thấp (0v)
  • CHANGE: Ngắt khi có thay đổi, thực hiện chương trình ngắt khi có thay đổi trên chân ngắt, từ thấp lên cao, từ cao xuống thấp (cạnh lên, cạnh xuống)
  • RISING: Ngắt cạnh lên, thực hiện chương trình ngắt khi chân ngắt từ mức thấp lên mức cao.
  • FALLING: Ngắt cạnh xuống, thực hiện chương trình ngắt khi chân ngắt từ mức cao lên mức thấp.

Chú ý: Hàm ngắt không có thông số trả về. Khi sử dụng ngắt thì một số hàm như delay() có thể sẽ bị sai vài mili giây, vì trong quá trình thực hiện lệnh delay thì xảy ra ngắt cũng có ảnh hưởng tương tự đối với các hàm truyền nhận UAR,…

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ề.

Ứng dụng của ngắt.

Ngắt thường được sử dụng để giúp vi điều khiển thực hiện chương trình chính xác và thông minh hơn, có thể giúp bạn giải một số khó khăn về thời gian. Một số chức năng thường dùng ngắt như: Đếm encoder, quản lý các ngõ vào hiệu quả hơn.Dễ dàng nhận thấy được rằng để đọc xung của encoder, mà không mất xung nào thì chương trình của bạn không thể làm gì khác vì phải kiểm tra liên tục. Nhưng đối với ngắt thì khác, giúp bạn chủ động hơn trong việc bắt sự khi khi có cạnh lên hoặc cạnh xuống ở chân ngắt.

Ví dụ về ngắt ngoài

Đảo trạng thái LED đơn khi phím nhấn ở chân số D2 của Arduino Uno.

int led = 13;
volatile int trangthai = LOW; // khai báo biến kiểu volatile, tránh sai số trong quá trình thực hiện ngắt.
void setup()                           // đoạn chương trình cài đặt
{ 
    pinMode(led, OUTPUT); // khai báo led là ngõ ra
    digitalWrite(2, HIGH);    // Treo chân ngắt 0, chân số 2 lên mức cao.
    attachInterrupt(0, daoled, CHANGE); // khai báo ngắt 0, chương trình con daoled, chế độ có sự 
                                                                 //  thay đổi là sinh ngắt
} 
void loop()                           // đoạn chương trình chính, vòng lặp vô tận.
{
    digitalWrite(led, trangthai);           // gán trạng thái cho chân led.
 } 
void daoled()                       // chương trình con ngắt, khi có ngắt xảy ra sẽ thực hiện chương trình này.
{ 
    trangthai = !trangthai;   // đảo trang thái.
}

Vài vấn đề với ngắt

Vấn đề ngắt chồng ngắt

Khi các bạn sử dụng nhiều ngắt như ngắt ngoài, ADC, I2C, UART, Timer… trong một chương trình và không lường trước được vấn đề interrupt nesting (ngắt chồng ngắt – đang ngắt thì có một ngắt khác), dẫn đến không có các biện pháp bảo vệ cần thiết cho biến, hay cho luồng xử lý của các ISR có quyền ưu tiên thấp. Để khắc phục được vấn đề này, các bạn cần nắm rõ các ưu tiên ngắt của vi điều khiển trong interrupt Vector Table, áp dụng bật tắt ngắt để bảo vệ biến, trong một số trường hợp, bạn có thể thay đổi thứ tự ưu tiên ngắt nếu vi điều khiển có hỗ trợ.

Vấn đề thời gian chiếm dụng

Các xử lý trong ngắt cần lưu ý về thời gian chiếm dụng, thời gian chiếm dụng càng lâu thì nguy cơ bị các vấn đề về interrupt nesting (ngắt lồng nhau => cần NVIC – Nested vectored interrupt controller ), các vấn đề về overload CPU càng lớn, vì vậy nếu có thể hãy để các xử lý ra hết ngoài chương trình chính, ngắt chỉ là nơi để thông báo cần phải xử lý một sự kiện (signal ra chương trình chính).

Vấn đề chờ trong ngắt

Dead-lock đơn giản được hiểu là quá trình chờ đợi các state khác của hệ thống, các thay đổi giá trị trong hệ thống phù hợp cho xử lý, trong trường hợp như vậy rất có thể đoạn chương trình đang chờ thực hiện sẽ không bao giờ được thực hiện.

Tham khảo: Arduino.vn, Tapit.vn

7 COMMENTS

  1. Write more, thats all I have to say. Literally,
    it seems as though you relied on the video to make your point.
    You clearly know what youre talking about, why throw away your intelligence on just posting videos to your site when you could be giving us something enlightening
    to read?

  2. İnstagram takipçi hilesi genel olarak müşterilerin memnun olduğu bir
    hizmet seçeneği olarak karşımıza çıkıyor. ,
    takipçi satın alişlemlerinde müşteri memnuniyeine çok
    önem vermekte olan megatakip
    Bu hizmet sayesinde bireyler hem hesaplarının geniş
    bir kitle tarafından takip edildiğini müşterilerine gösterme fırsatı buluyor aynı zamanda
    işletmelerinizi daha geniş bir kitleye sahip olmanızı sağlıyor eğerki sizde instagram da takipçi yada beğeni
    gibi işlem satın almak istersiniz hemen megatakip e bekliyoruz.

  3. This design is incredible! You obviously know how to keep a reader entertained.
    Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Fantastic job.
    I really loved what you had to say, and more than that, how you
    presented it. Too cool!

LEAVE A REPLY

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Tắt kính lúp hình vuông trong Altium

Tắt kính lúp của sổ PCB  trên Altium Sử dụng phím tắt: Shift+M Tham khảo thêm một số phím tắt khác trên phần mềm Altium Designer: Thiết...

Tổng hợp trang web liên quan thiết kế phần cứng điện tử

4 trang web tải thư viện SCH/PCB và 3D https://www.ultralibrarian.com/ https://componentsearchengine.com/ https://octopart.com/ https://www.snapeda.com/ https://componentsearchengine.com/ 2 trang tìm 3D cho thư viện của các bạn bao gồm: https://www.3dcontentcentral.com/ https://grabcad.com/library 4 trang cung cấp các...

Mạch đóng ngắt Relay sử dụng Transistor

Giới thiệu về Relay Rơ le (Relay) là một công tắc chuyển đổi hoạt động bằng điện. Dòng điện chạy qua cuộn dây của rơ...

Nạp Bootloader cho Arduino Pro Micro

Bootloader là một chương trình nhỏ được nạp sẵn vào chip vi điều khiển trên Arduino, nhờ đó bạn lập trình cho Arduino một...

Recent Comments