Mục tiêu: Viết được chương trình sử dụng ngắt.
Các bước khi thực hiện một ngắt.
- Khi kích hoạt một ngắt bộ vi điều khiển đi qua các bước sau:
+ Nó kết thúc lệnh đang thực hiện và lưu địa chỉ của lệnh kế tiếp (PC) vào
ngăn xếp.
+ Nó cũng lưu tình trạng hiện tại của tất cả các ngắt vào bên trong (nghĩa là không lưu vào ngăn xếp).
+ Nó nhảy đến một vị trí cố định trong bộ nhớ được gọi là bảng véc tơ ngắt, nơi lưu giữ địa chỉ của một trình phục vụ ngắt.
+ Bộ vi điều khiển nhận địa chỉ ISR từ bảng véc tơ ngắt và nhảy tới đó. Nó bắt đầu thực hiện trình phục vụ ngắt cho đến lệnh cuối cùng của ISR là RETI (trở về từ ngắt).
+ Khi thực hiện lệnh RETI bộ vi điều khiển quay trở về nơi nó đã bị ngắt.
Trước hết nó nhận địa chỉ của bộ đếm chương trình PC từ ngăn xếp bằng cách kéo hai byte trên đỉnh của ngăn xếp vào PC. Sau đó bắt đầu thực hiện các lệnh từ địa chỉ đó.
- Lưu ý ở bước 5 đến vai trị nhạy cảm của ngăn xếp, vì lý do này mà chúng ta phải cẩn thận khi thao tác các nội dung của ngăn xếp trong ISR. Đặc biệt trong ISR cũng như bất kỳ chương trình con CALL nào số lần đẩy vào ngăn xếp (Push) và số lần lấy ra từ nó (Pop) phải bằng nhau.
Thứ tự ưu tiên ngắt
Khi có hai hay nhiều ngắt cùng lúc xảy ra, hoặc một ngắt đang thực hiện, nếu mở ngắt khác yêu cầu thì ngắt nào có độ ưu tiên hơn sẽ được ưu tiên xử lý.
Có 3 cấp độ ưu tiên ngắt trong 8051:
- Ngắt reset là ngắt có mức ưu tiên cao nhất, khi reset xảy ra tất cả các ngắt khác và chương trình đều bị dừng và vi điều khiển trở về chế độ khởi dộng ban đầu.
- Ngắt mức 1, chỉ có reset mới có thể cấm ngắt này.
- Ngắt mức 0, các ngắt mức 1 và reset có thể cấm ngắt này.
Việc đăt chọn mức ưu tiên ngắt là 1 hoặc 0 thông qua thanh ghi IP. Việc xử lý ưu tiên ngắt của 8051 như sau:
- Nếu 1 có độ ưu tiên cao hơn một ngắt đang được xử lý xuất hiện thì, ngắt có ưu tiên thấp ngay lập tức bị dừng để ngắt kia được thực hiện.
- Nếu 2 ngắt cùng yêu cầu vào 1 thời điểm thì ngắt có mức ưu tiên hơn sẽ được xử lý trước.
- Nếu 2 ngắt có cùng mức ưu tiên cùng yêu cầu vào 1 thời điểm thì thứ tự được chọn như sau:
+ INTR 0
+ Timer 0
+ INTR 1
+ Timer 1
+ UART
Mẫu đề nghị cho một chương trình được thực thi độc lập có sử dụng ngắt như sau :
ORG 0000H ; điểm nhập sau khi reset LJMP MAIN
; các điểm nhập của các ISR ORG 0030H ; điểm nhập chương trình chính MAIN: ; chương trình chính bắt đầu END
4.1 Các trình phục vụ ngắt kích thước nhỏ.
Các trình phục vụ ngắt phải được bắt đầu ở gần đáy của bộ nhớ chương trình tại các địa chỉ qui định. Mặc dù chỉ có 8 byte giữa các điểm nhập của các trình phục vụ ngắt, dung lượng này thường đủ để thực hiện các công việc được yêu cầu và quay trở về chương thình chính từ một trình phục vụ ngắt.
Điều này có nghĩa là trình phục vụ ngắt cho các ngắt tương ứng thường không dài quá 8 byte.
Nếu có nhiều ngắt được dùng ta phải cẩn thận để đảm bảo các ISR được bắt đầu đúng vị trí mà không tràn sang ISR kế.
Ví dụ:
ORG 0000H ; điểm nhập reset LJMP MAIN
ORG 000BH ; điểm nhập ngắt bộ định thời 0 T0_ISR : ; bắt đầu ISR cho bộ định thời 0
MOV P2,#00001111B
RETI ; trở về chương trình chính
MAIN : ; chương trình chính
- -
END ; kết thúc chương trình
4.2 Các trình phục vụ ngắt kích thước lớn.
Nếu một trình phục vụ ngắt dài hơn 8 byte được cần đến, ta phải di chuyển phương trình này đến một nơi khác trong bộ nhớ chương trình hoặc ta có thể cho lấn qua điểm nhập của ISR kế. Điển hình là ISR bắt đầu với một lệnh nhảy đến một vùng khác của bộ nhớ chương trình, ở đó ISR được trải rộng nếu cần.
Ví dụ 1:
ORG 0000H ; điểm nhập reset
LJMP MAIN
ORG 000BH ; điểm nhập ngắt do timer 0
LJMP T0_ISR
; điểm nhập các ngắt khác ( nếu có ) ORG 0030H ; địa chỉ phía trên các vector ngắt
MAIN: ; chương trình chính
T0_ISR: ; chương trình con phụ vụ ngắt
; do bộ định thời 0
RETI ; quay về chương trình chính END
Ví dụ 2:
Viết chương trình tạo sóng vuông có tần số 10KHz trên chân P1.0 sử dụng bộ định thời 0 và ngắt do bộ định thời 0.
ORG 0000H ; điểm nhập reset LJMP MAIN
ORG 000BH ; điểm nhập ngắt timer 0
T0_ISR: ; ISR timer 0
CPL P1.0 ; đảo bit P1.0
RETI ; trở về chương trình chính MAIN:
MOV TMOD,#00000010B; timer 0 hoạt động ở chế độ 2 (8 bit) MOV TH0,#-50 ; giá trị nạp lại tương ứng với 50us MOV IE,#10000010B ; cho phép ngắt do bộ định thời 0 SETB TR0 ; bật timer 0
SJMP $ ; nhảy tại chổ
END
Ví dụ 3:Viết chương trình sử dụng các ngắt để tạo ra đồng thời các dạng sóng vuông có tần số là 10KHz trên chân P1.0 và 500Hz trên chân P1.1
ORG 0000H LJMP MAIN ORG 000BH LJMP NGAT_T0
ORG 001BH
LJMP NGAT_T1 ORG 0030H MAIN:
MOV TMOD,#00010010B; timer 1 chế độ 1, timer 0 chế độ 2
MOV TH0,#-50
MOV TH1,#HIGH(-1000) MOV TL1,#LOW(-1000) MOV IE,#10001010B SETB TR0
SETB TR1 SJMP $ NGAT_T0:
CPL P1.0 RETI
NGAT_T1:
CLR TR1
MOV TH1,#HIGH(-1000) MOV TL1,#LOW(-1000) SETB TR1
CPL P1.1 RETI