Nếu bạn đã được học qua về Vi điều khiển nói chung thì bạn hẳn sẽ được biết thế nào gọi là ngắt, bài hướng dẫn này sẽ điểm qua một tí về thế nào gọi là Ngắt, Ngắt timer và các vi dụ cơ bản để bạn hiểu về nó.
Ngắt là gì ?: Nghe qua bạn đã hình dung sơ bộ về nó, ngắt là hoạt động xảy ra ko thường xuyên, bất chợt mà nằm ngoài sự việc bình thường đang diễn ra. Ví dụ: bạn hẹn giờ đồng hồ, sau đó đi ngủ…bất thình lình đồng hồ reo, thì đó được xem là ngắt. Nó ngắt quảng công việc hiện tại của bạn là đang ngủ. Hay ví dụ khác, Bạn được bạn bè gửi hàng cho mình, bạn đang làm việc, bổng có người gọi điện báo cho bạn biết bạn có hàng và yêu cầu bạn đến lấy, thì đây cũng xem là ngắt.
Tại sao phải có ngắt trong Arduino hay các chip Vi điều khiển ?. Nhìn chung, với Arduino hay các loại vi điều khiển, mỗi lúc chỉ có thể xử lý 1 lệnh, chúng ta không thể xử lý nhiều lệnh 1 lúc, bạn đừng nhầm lẫn ở đây là nhiều lệnh khác nhiều việc nhé. Hình dung thế này, nếu chúng ta có đồng hồ, thay vì nhìn chằm chằm để lấy 1 khoảng thời gian nhất định thì ta đơn giản là đi hẹn giờ. Cài này gọi là lập trình ngắt. Hệ vi điều khiển nói chung có phần cứng phục vụ ngắt thì nó là ngắt phần cứng, giúp cho việc lập trình sẽ không phải liên tục kiểm tra một đầu vào, một dữ liệu nối tiếp truyền đến hay 1 khoảng thời gian mà đơn giản mỗi khi nó có sự kiện ngắt, phần cứng vi điều khiển sẽ báo cho mã lập trình để xử lý, khi đó mọi chuyện sẽ đơn giản hơn.
Đối với Arduino, ngắt Timer chủ yếu được dùng để định các khoảng thời gian nhất định, xuất xung tần số tùy chỉnh ra chân đầu ra số hay định thời gian kiểm tra dự liệu truyền nối tiếp. Tùy theo Board Arduino mà số lượng Timer cũng khác nhau. Với Arduino Mega 2560 thì có 5 Timer, Timer 0, Timer 1, Timer 2, Timer 3, Timer 4, Timer 5. Bài viết này, tôi sẽ chỉ tập trung vào Arduino UNO.
Giới thiệu
Arduino UNO có 3 Timer, Timer 0, 1 và 2. Các timer này sẽ tăng giá trị của nó dựa vào xung nhịp của Arduino.Khi bạn đặt giá trị ngắt, Timer sẽ tăng dần giá trị khi xảy ra xung nhịp và so sánh với giá trị đặt trước, khi bằng nhau nó sẽ xảy ra một ngắt.
Timer 0, 2 là 2 timer 8 bit, hay nói cách khác nó chỉ có thể đếm từ 0 đến 255 và với Timer1 là timer 16 bit, nó có thể đếm từ 0 đến 65535 mà thôi. Arduino UNO có xung nhịp là 16MHz, tương đương 1/16000000s, 63ns. Nếu các Timer đếm các xung nhịp này thì với Timer 0,2 chỉ có thể đếm 256*63ns 16us và với Timer 1 là 4 ms.
Bài hướng dẫn này không đi sâu về ngắt, chỉ hướng dẫn bạn làm sao để lập trình nó dùng thư viện
Thư viện lập trình
Muốn đặt ngắt, bạn phải đặt lệnh trong hàm setup(){}.
Thư viện đính kèm gồm có thư viện timer cho Timer 1, Timer 3. Bạn copy và thư mục thư viện của Arduino IDE.
Gồm có các hàm:
initialize() // Khởi động ngắt Timer.
start() // Khởi động lại sau khi sửa đổi.
startBottom() // Cho Timer bắt đầu đếm lại từ giá trị 0 (Chú ý đây là giá trị đếm của Timer chứ không phải giá trị bạn đặt).
read() // Đọc giá trị hiện tại của Timer
stop() //Dừng Timer.
attachInterrupt() // Thêm địa chỉ hàm để gọi khi xảy ra ngăt và bắt đầu đếm.
detachInterrupt() // Hủy địa chỉ ngắt
pwm(char pin, int duty, long microseconds) // Băm xung ra chân pin với số chu kỳ là duty. Xung có độ rộng là microseconds.
disablePwm(char pin) //Hủy băm xung.
Thư viện TimerOne: https://github.com/PaulStoffregen/TimerOne
Thư viện TimerThree: https://github.com/PaulStoffregen/TimerThree
Ví dụ Ngắt Timer
Ví dự nháy LED 0.15s
// Ví dụ này dùng ngắt Timer để nháy LED
// và sử dụng biến chia sẻ giữa hàm ngắt và chương trình chính
const int led = LED_BUILTIN; // định nghĩa chân LED, Biến LED_BUILTIN dùng để chỉ LED được gắn trên Board mạch.Ví dụ với Arduino UNO thì LED_BUILTIN=13.
void setup(void)
{
pinMode(led, OUTPUT);
Timer1.initialize(150000); //Khởi động ngắt, thời gian đặt cho nó là 150000us=0.15s.
Timer1.attachInterrupt(blinkLED); //Khi xảy ra ngắt chương trình sẽ gọi hàm blinkLED().
Serial.begin(9600);
}
int ledState = LOW;
volatile unsigned long blinkCount = 0; // Biến dùng chung giữa CT chính và CT ngắt.
void blinkLED(void)
{
if (ledState == LOW) {
ledState = HIGH;
blinkCount = blinkCount + 1; // tăng lên 1 mỗi lần LED sáng
} else {
ledState = LOW;
}
digitalWrite(led, ledState);
}
// Xuất số lần sáng ra Serial0.
// to the Arduino Serial Monitor
void loop(void)
{
unsigned long blinkCopy;
noInterrupts(); //Hủy các ngắt trước đó.
blinkCopy = blinkCount;
interrupts(); //Cho phép ngắt
Serial.print(blinkCount = );
Serial.println(blinkCopy);
delay(100);
}