I. Ngắt trong 8051.
Ngắt (Interrupt) có thể hiểu nôm na là 1 tín hiệu khẩn cấp gửi đến bộ vi xử lý, yêu cầu bộ vi xử lý tạm dừng các công việc đang thực hiện để nhảy đến 1 nơi khác thực hiện một chương trình khác (công việc khác). Chương trình này được gọi là trình phục vụ ngắt (ISR: Interrupt Service Routine). Sau khi kết thúc chương trình trong ngắt. Bộ đếm chương trình được trả về vị trí trước đó để thực hiện tiếp nhiệm vụ còn đang dang dở.Các tín hiệu dẫn đến ngắt (hay còn gọi là nguồn ngắt) có thể do bên trong (UART, Timer) hoặc bên ngoài chíp ( ngắt ngoài, reset).
1).Trong 8051 có 6 nguồn ngắt bao gồm:
- Reset: Khi chân reset được kích hoạt (đưa lên mức cao) Chip sẽ reset.
- Hai ngắt dành cho bộ định thời Timer 0 và Timer 1. Với 8052 thì có thêm ngắt dành cho bộ định thời Timer 2.
- Hai ngắt ngoài bao gồm ngắt ngoài 0 (chân P3.2) và ngắt ngoài 1 (chân P3.3)
- Ngắt truyền thông nối tiếp UART.
Trong bài viết này, mình sẽ trình bày về cấu hình cho vi điều khiển 8051 để sử dụng ngắt ngoài.
II. Cấu hình sử dụng ngắt ngoài với 8051.
1.Các thanh ghi điều khiển ngắt.
Để cấu hình và sử dụng được ngắt ngoài trong 8051, chúng ta cần hiểu được chức năng các bit trong thanh ghi điều khiển ngắt của 8051.
Trong 8051, có 2 thanh ghi được sử dụng để cấu hình ngắt ngoài.
Đầu tiên, chúng ta quan tâm đến thanh ghi cho phép ngắt/cấm ngắt: IE (Interrupt Enable).
Thanh ghi này có các bit như sau.
1).Chức năng các bit:
- EA: Bit cho phép ngắt/cấm ngắt toàn cục. Khi EA = 0 thì không một tín hiệu ngắt nào được chấp nhận. Khi EA = 1 thì các tín hiệu ngắt sẽ được chấp nhận nếu như bit điều khiển ngắt của các nguồn ngắt đó được bật.
- ET2: Bit điều khiển ngắt tràn Timer 2. Nếu ET2 = 0, ngắt tràn Timer 2 bị cấm, nếu ET2 = 1, ngắt tràn Timer 2 được chấp nhận.
- ES: Bit điều khiển ngắt UART.
- ET1: Bit điều khiển ngắt tràn Timer 1.
- EX1: Bit điều khiển ngắt ngoài 1.
- ET0: Bit điều khiển ngắt tràn Timer 0.
- EX0: Bit điều khiển ngắt ngoài 0.
2).Trong phạm vi bài viết về cấu hình sử dụng ngắt ngoài này, chúng ta chỉ quan tâm đến các bit: EA, EX1, EX0 của thanh ghi IE.
- Thanh ghi tiếp theo chúng ta cần quan tâm là thanh ghi TCON. Thanh ghi này bao gồm 8 bit như trong hình sau.
- Để cấu hình sử dụng ngắt ngoài, chúng ta chỉ cần quan tâm đến 2 bit IT0, IT1, trong thanh ghi TCON. Đây là 2 bit dùng để cài đặt chế độ ngắt cho ngắt ngoài.
- Trong 8051 có 2 chế độ ngắt cho ngắt ngoài là ngắt kích phát sườn và ngắt kích phát mức.
- Ngắt kích phát sườn nghĩa là khi có một xung từ cao xuống thấp (falling edge) trên chân ngắt ngoài 0, hoặc ngắt ngoài 1 thì sẽ xảy ra ngắt.
- Ngắt kích phát mức nghĩa là khi các chân ngắt ngoài 0, hoặc 1 được đưa về mức thấp (mức 0) thì sẽ xảy ra ngắt.
- Bit IT0, dùng để cài đặt cho ngắt ngoài 0: Khi IT0 = 0, ngắt kích phát mức được chọn. Khi IT0 = 1, ngắt kích phát sườn được chọn.
- Tương tự như trên, bit IT1 dùng để cài đặt chế độ cho ngắt ngoài 1.
III. Các bước cấu hình sử dụng ngắt ngoài trong 8051.
1).Để sự dụng ngắt ngoài trong 8051, chúng ta cấu hình theo các bước sau.
- Bật các bit cho phép ngắt ngoài 0 (EX0 = 1), hoặc 1 (EX1 = 1), hoặc bật cả hai nếu sử dụng cả 2 ngắt ngoài.
- Cấu hình chế độ ngắt kích phát sườn hoặc kích phát mức cho ngắt ngoài 0, hoặc 1 bằng cách bật hoặc xóa các bit IT0, hoặc IT1.
- Bật bit cho phép ngắt toàn cục (EA = 1).
2).Viết chương trình phục vụ ngắt. Chương trình ngắt cho 8051 trong Keil C được viết theo cú pháp sau.
Trong đó: “ten_ham_ngat” do các bạn tự đặt, nhưng mình khuyên các bạn nên đặt tên hàm có tính gợi nhớ, khi người khác đọc code sẽ biết bạn đang sử dụng ngắt nào. Ví dụ sử dụng ngắt ngoài 0, mình thường viết tên hàm: “ISR_EX0”.
“x”: được gọi là số thứ tự ngắt (Interrupt number), khi các bạn sử dụng ngắt nào thì bạn phải điền số thứ tự ngắt của ngắt đó. Các bạn có thể xem số thứ tự ngắt trong bảng sau.
Ví dụ, để sử dụng ngắt ngoài 0 thì mình phải điền x là 0, và ngắt ngoài 1 điền x là 2 (dựa theo bảng trên). Ví dụ chương trình ngắt phục vụngắt ngoài 0 mình thường viết như sau.
IV. Bài toán ví dụ
1.Đề bài
Viết chương trình sử dụng 2 nút nhấn để điều khiển hiển thị số có 1 chữ số trên led 7 thanh 1 số như sau:
Mặc định khi bắt đầu, trên led 7 hiển thị số 0.
Mỗi lần nhấn nút 1, giá trị trên led 7 thanh tăng 1 đơn vi. Khi giá trị trên led 7 thanh lớn hơn 9, thì led 7 thanh sẽ hiển thị sẽ quay trở lại số 0.
Mỗi lần nhấn nút 2, giá trị trên led 7 thanh giảm 1 đơn vị, khi giá trị trên led 7 thanh nhỏ thua 0, thì led 7 thanh sẽ hiển thị số 9.
2. Phân tích bài toán.
Với bài toán như trên chúng ta có thể sử dụng kiểu hỏi vòng kiểm tra nút nhấn như cách đã sử dụng ở bài 3 để thực hiện. Nhưng trong phạm vi bài viết viết về ngắt ngoài, do vậy mình sẽ viết chương trình thực hiện yêu cầu bài toán trên sử dụng ngắt ngoài.
Mình sẽ sử dụng 2 nút nhấn nối vào 2 chân ngắt ngoài: Nút 1 nối vào chân ngắt ngoài 0 (chân P3.2), nút 2 nối vào chân ngắt ngoài 1 (chân P3.2). Port 2 được sử dụng để xuất giá trị hiển ra led 7 thanh. Sơ đồ mô phỏng được vẽ như sau.
Trong chương trình, mình sẽ sử dụng biến x, kiểu có dấu(signed), để sử dụng làm biến tăng giảm hiển thị ra led 7 thanh. Một mảng gồm 10 phần tử chứa mã led 7 anot chung của các số từ 0->9 cũng sẽ được khai báo ở đầu chương trình.
3.Viết chương trình.
Đoạn đầu chương trình, include thư viện và khai báo biến cần sử dụng.
Tiếp theo, trong hàm main, chúng ta cấu hình sử dụng 2 ngắt ngoài 0 và 1. Do yêu cầu bài toán mỗi làn nhấn nút tăng 1 giá trị của biến, nên chúng ta sẽ sử dụng ngắt kích phát mức. bit IT1 =1, IT0 =1.
Trong vòng lặp vô tận while(1), chúng ta chỉ cần xuất giá trị của biến x ra led 7, việc tăng giảm biến sẽ được thực hiện trong chương trình phục vụ ngắt ngoài 0 và 1.
Chương trình thực hiện ngắt được viết như sau.
Các điểm cần lưu ý trong chương trình này là phần cấu hình ngắt trong phần đầu hàm main. Các bạn cần chú ý để cấu hình đúng theo yêu cầu mình cần. Điểm thứ 2 nữa là viết chương trình phục vụ ngắt. Trong 2 chương trình phục vị ngắt trên, mình thực hiện các công việc đơn giản theo yêu cầu bài toán là tăng giảm biến và kiểm tra giới hạn của biến.
Việc còn lại trong vòng lặp khá đơn giản, chỉ cần 1 dòng lệnh để xuất giá trị của biến ra led 7 thanh.
Các bạn hãy thử vẽ lại mạch mô phỏng, tạo project mới và code lại theo bài toán trên xem kết quả nhé.
Cảm ơn các bạn đã theo dõi bài viết, chúc các bạn thành công !