Lập trình ngắt vi điều khiển 8051
Chào các bạn, do một thời gian bận làm mấy cái project lên hôm nay mình mới có thời gian viết bài, mong mọi người thông cảm.
Hôm nay chúng ta sẽ tìm hiểu về ngắt vi điều khiển, thực ra trên club đã có tài liệu rồi nhưng một số bạn vẫn còn bỡ ngỡ về viết code ntn thì hôm nay m sẽ hướng dẫn code và tìm hiểu xem ngắt là cái quái gì mà nó lại quan trọng vậy :)
Đầu tiên các bạn sẽ thắc mắc ngắt là gì.... nếu mà cứ theo cái định nghĩa của nó chắc chẳng ai hình dung rõ lên m sẽ chuẩn bị một ví dụ để minh họa cho cái định nghĩa thô cứng đó:
VD như bạn đang vặt rau sauđó rửa rau rùi cho vào luộc, công việc có vẻ rất trôi chảy nhưng trong lúc đang vặt rau bỗng nhiên mama gọi "Con ơi đi ra ngoài tạp hóa mua cho mẹ gói bột nêm" Thế là ngay lập tức bạn dừng công việc vặt rau lại cất gọn vào một chỗ nào đó rồi chạy ngay ra cửa hàng để mua đồ cho mẹ, khi bạn mua xong gói bột nêm về thì bạn lại quay lại công việc đang dang dở đó là vặt rau và cứ như vậy... =>> Đó chính là ngắt
Trong vi điều khiển cũng vậy, chương trình dc chạy từ trên xuống dưới trong hàm main() - Hàm ctr chính. Bình thường (đang vặt rau) thì như vậy nhưng khi có ngắt xảy ra (mẹ sai đi mua bột nêm), tức sẽ có ngoại lệ, sẽ ra lệnh cho VDK biết là đang có một ngắt xuất hiệu và yêu cầu VDK phải xử lý nó, thế là VDK bảo “Biết rồi khổ lắm nói mãi” rồi thực hiện xong nốt câu lệnh đang chạy dở =>> Cất dữ liệu địa chỉ của câu lệnh tiếp theo vào một chỗ nào đó gọi là ngăn xếp (ô nhớ trên RAM) xong quay sang phục vụ chương trình ngắt (Chính là việc chạy đi mua bột nêm đó) khi phục vụ xong rồi thì nó lại vào ngăn xếp lấy cái địa chỉ của ô nhớ tiếp theo cần được xử lý. Công việc của VDK là như vậy khi có ngắt xảy ra.
Bình thường thì vi điều khiển chỉ xử lý dc một lệnh duy nhất, thực hiện xong thì nhảy đến lệnh kế tiếp, ko có khái niệm 3 đầu 6 tay đâu nha chỉ làm dc duy nhất một việc trong 1 khoảng thời gian, đó chính là chu kì máy dc định bởi bộ dao động, thường thấy là thạch anh(như quả tim vậy nó mà ngừng đập là VDK sẽ chết), VDK sẽ chia 12 lần xung nhịp thạch anh để ra chu kì máy VD sd thạch anh 12Mhz thì ta có chu kỳ máy là 1us (1/1.000.000 giây). Thế là đã hiểu sơ sơ rồi, thế là đủ cho ngôn ngữ C ko cần lắm quá nhiều về cấu trúc VDK lên việc học lập trình rất nhanh, tôi đảm bảo với bạn sẽ dễ hơn với ASM vì ASM là hợp ngữ còn C là ngôn ngữ bậc cao gần với con ng hơn.
Trước khi đi vào phần code ta sẽ tìm hiểu xem con VDK của ta có những gì để sài: Họ 8051 có tất cả 5 ngắt và 1 ngắt Reset và 2 bộ định thời Timer0 và Timer1, riêng chíp 8052 là có thêm Timer 2. Để lắm rõ hơn bạn vui lòng tải tài liệu về bộ định thời về ở trên club
Ngắt reset là ngắt phần cứng khi ta kích mức cao vào chân Reset, còn 5 ngắt kia gồm: Ngắt Timer0, Timer 1, Ngắt ngoài 0, Ngắt ngoài 1, Ngắt UART ta sẽ xét từng ngắt một:
-Ngắt timer: Cơ bản timer0 và timer1 như nhau chỉ khác khai báo lên nhóm chung vào một mục
Ta xét thanh ghi hoạt động của timer: Thanh ghi 8bit TMOD: | GATE | C/T | M1 | M0 | GATE | C/T | M1 | M0 |
Bôi đỏ là của Timer1 và còn lại là của Timer0, nhưng ta chỉ quan tâm tới bit M0 và M1 – đây là bit set chế độ hoạt động cho timer
M1 M0 Chế độ
0 0 Định thời 13bit
0 1 Định thời 16bit
1 0 Định thời 8bit tự nạp lại
1 1 Định thời chia sẻ
Nhưng để cho nhanh ta có thể khai báo tắt như sau:
TMOD=0x01; Tương đương TMOD=0000 0001 là chọn timer0 và chế độ 16bit TMOD=0x10; Tương đương TMOD=0001 0000 là chọn timer1 và chế độ 16bit
TMOD=0x21; Tương đương TMOD=0010 0001 là chọn timer0 chế độ 16bit và timer1 chế độ 8bit nạp lại tự động
.v.v..
Thanh ghi TH0, TL0(timer0), TH1,TL1(timer1) nạp giá trị ban đầu để đếm, bộ định thời sẽ đếm lên 1 với mỗi chu kì máy, như vậy ta phải tính toán giá trị nạp vì khi bộ định thời tràn tức đã đếm đủ 8bit, 16bit thì ngắt mới xảy ra
Chú ý thanh ghi TH0, TH1 có tác dụng khi ở chế độ 16bit vì nó lưu 8bit cao
Thanh ghi IE(thanh ghi khai báo ngắt) có 2 bit ET0 và ET1 tương ứng ngắt timer0 và ngắt timer1
Bảng vector ngắt:
0 - Ngắt ngoài 0 1 - Ngắt timer 0 2 - Ngắt ngoài 1 3 - Ngắt timer 1