Giáo trình Vi điều khiển 8051 Assembly - Chương 11: Lập trình các ngắt

Một bộ vi điều khiển có thể phục vụ một vài thiết bị, có hai cách để thực hiện

điều này đó là sử dụng các ngắt và thăm dò (polling). Trong phương pháp sử dụng

các ngắt thì mỗi khi có một thiết bị bất kỳ cần đến dịch vụ của nó thì nó bao cho bộ

vi điều khiển bằng cách gửi một tín hiệu ngắt. Khi nhận được tín hiệu ngắt thì bộ vi

điều khiển ngắt tất cả những gì nó đang thực hiện để chuyển sang phục vụ thiết bị.

Chương trình đi cùng với ngắt được gọi là trình dịch vụ ngắt ISR (Interrupt Service

Routine) hay còn gọi là trình quản lý ngắt (Interrupt handler). Còn trong phương

pháp thăm dò thì bộ vi điều khiển hiển thị liên tục tình trạng của một thiết bị đã cho

và điều kiện thoả mãn thì nó phục vụ thiết bị. Sau đó nó chuyển sang hiển thị tình

trạng của thiết bị kế tiếp cho đến khi tất cả đều được phục vụ. Mặc dù phương pháp

thăm dò có thể hiển thị tình trạng của một vài thiết bị và phục vụ mỗi thiết bị khi các

điều kiện nhất định được thoả mãn nhưng nó không tận dụng hết cộng dụng của bộ

vi điều khiển. Điểm mạnh của phương pháp ngắt là bộ vi điều khiển có thể phục vụ

được rất nhiều thiết bị (tất nhiên là không tại cùng một thời điểm).

pdf18 trang | Chuyên mục: Kiến Trúc Máy Tính | Chia sẻ: dkS00TYs | Lượt xem: 8634 | Lượt tải: 1download
Tóm tắt nội dung Giáo trình Vi điều khiển 8051 Assembly - Chương 11: Lập trình các ngắt, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
hể gọi ngắt 
hay nói cách khác là chỉ có một ngắt cho cả truyền và nhận. 
Ví dụ 11.9: 
 Hãy viết chương trình trong đó 8051 nhận dữ liệu từ cổng P1 và gửi liên tục 
đến cổng P2 trong khi đó dữ liệu đi vào từ cổng nối tiếp COM được gửi đến cổng P0. 
Giả thiết tần số XTAL là 11.0592MHz và tốc độ baud 9600. 
Lời giải: 
 ORG 0 
 LJMP MAIN 
 ORG 23H 
LJMP SERIAL ; Lấy cổng P1 là cổng đầu vào 
ORG 03H 
 MAIN: MOV P1, # FFH 
 MOV TMOD, # 20H ; Chọn Timer và chế độ hai tự nạp lại 
 MOV TH1, # 0FDH ;Khung dữ liệu: 8 bít dữ liệu, 1 stop, cho phép REN 
 MOV SCON, # 50H ; Cho phép ngắt nối tiếp 
 MOV IE, # 10010000B ; Khởi động Timer1 
 SETB TR1 ; Đọc dữ liệu từ cổng P1 
 BACK: MOV A, P1 ; Gửi dữ liệu đến cổng P2 
 MOV P2, A ; ở lại trong vòng lặp 
 SJMP BACK 
 ; -------------------------Trình phục vụ ngắt cổng nối tiếp. 
 ORG 100H 
 SERIAL: JB TI, TRANS ; Nhảy nếu Ti cao 
 MOV A, SBUF ; Nếu không tiếp tục nhận dữ liệu 
 MOV P0, A ; Gửi dữ lệu đầu vào đến cổng P0 
 CLR RI ; Xoá vờ RI vì CPU không xoá cờ này 
 RETI ; Trở về từ ISR 
 TRANS: CLS TI ; Xoá cờ TI và CUP không xoá cờ này. 
 RETI ; ; trở về từ ISR 
 END 
11.4.3 Xoá cờ RI và TI trước lệnh RETI. 
 Để ý rằng lệnh cuối cùng trước khi trở về từ ISR là RETI là lệnh xoá các cờ 
RI và TI. Đây là điều cần thiết bởi vì đó là ngắt duy nhất dành cho nhận và truyền 
8051 không biết được nguồn gây ra ngắt là nguồn nào, do vậy trình phục vụ ngắt 
phải được xoá các cờ này để cho phép các ngắt sau đó được đáp ứng sau khi kết thúc 
ngắt. Điều này tương phản với ngắt ngoài và ngắt bộ định thời đều được 8051 xoá 
các cờ. Các lệnh xoá các cờ ngắt bằng phần mềm qua các lệnh “CLR TI” và “CLR 
RI”. Hãy xét ví dụ 11.10 dưới đây và để ý đến các lệnh xoá cờ ngắt trước lệnh RETI. 
Ví dụ 11.10: 
 Hãy viết một chương trình sử dụng các ngắt để thực hiện các công việc sau: 
a) Nhận dữ liệu nối tiếp và gửi nó đến cổng P0. 
b) Lấy cổng P1 đọc và truyền nối tiếp và sao đến cổng P2. 
c) Sử dụng Timer0 tạo sóng vuông tần số 5kHz trên chân P0.1 giảt thiết tần số 
XTAL = 11.0592MHz và tốc độ baud 4800. 
Lời giải: 
 ORG 0 
LJMP MAIN 
 ORG 000BH ; Trình phục vụ ngắt dành cho Timer0 
 CPL P0.1 : Tạo xung ở chân P0.1 
 RETI ; Trở về từ ISR 
 ORG 23H ; Nhảy đến địa chỉ ngắt truyền nối tiếp 
 LJMP SERIAL ; Lấy cổng P1 làm cổng đầu vào 
 ORG 30H 
 MAIN : MOV P1, # 0FFH ; Chọn Timer0 và Timer1 chế độ 2 tự nạp lại 
 MOV TMOD, # 22H ; Chọn Timer0 và Timer1 chế độ 2 tự nạp lại 
 MOV TH1, # 0F6H ; Chọn tốc độ baud 4800 
 MOV SCON, # 50H ; Khung dữ liệu: 8 bít dữ liệu, 1 stop, cho phép REN 
 MOV TH0, # - 92 ; Tạo tần số 5kHz 
 MOV IE, # 10010010B ; Cho phép ngắt nối tiếp 
 SETB TR1 ; Khởi động Timer1 
 SETB TR0 ; Khởi động Timer0 
 BACK: MOV A, P1 ; Đọc dữ liệu từ cổng P1 
 MOV SBUF, A ; Lấy một lần bản sao dữ liệu 
 MOV P2, A ; Ghi nó vào cổng P2 
 SJMP BACK ; ở lại trong vòng lặp 
 ; ---------------------- Trình phục vụ ngắt cổng nối tiếp. 
 ORG 100H 
 SERIAL: JB TI, TRANS ; Nhảy nếu TI vào 
 MOV A, SBUF ; Nếu không tiếp tục nhận dữ liệu 
 MOV P0, A ; Gửi dữ liệu nối tiếp đến P0 
 CLR RI ; Xoá cờ RI vì 8051 không làm điều này 
 RETI ; Trở về từ ISR 
 TRANS: CLR TI ; Xoá cờ TI vì 8051 không xoá 
 RETI ; Trở về từ ISR. 
 END 
 Trước khi kết thúc phần này hãy để ý đến danh sách tất cả mọi cờ ngắt được 
cho trong bảng 11.2. Trong khi thanh thi TCON giữ 4 cờ ngắt còn hai cờ TI và RI ở 
trong thanh ghi SCON của 8051. 
 Bảng 11.2: Các bít cờ ngắt. 
Ngắt Cờ Bít của thanh ghi SFR 
Ngắt ngoài 0 IE0 TCON.1 
Ngắt ngoài 1 IE1 TCON.3 
Ngắt Timer0 TF0 TCON.5 
Ngắt Timer1 TF1 TCON.7 
Ngắt cổng nối tiếp T1 SCON.1 
Ngắt Timer2 TF2 T2CON.7 (TA89C52) 
Ngắt Timer2 EXF2 T2CON.6 (TA89C52) 
11.5 Các mức ưu tiên ngắt trong 8051. 
11.5.1 Các mức ưu tiên trong quá trình bật lại nguồn. 
 Khi 8051 được cấp nguồn thì các mức ưu tiên ngắt được gán theo bảng 11.3. 
Từ bảng này ta thấy ví dụ nếu các ngắt phần cứng ngoài 0 và 1 được kích hoạt cùng 
một lúc thì ngắt ngoài 0 sẽ được đáp ứng trước. Chỉ sau khi ngắt INT0 đã được phục 
vụ xong thì INT1 mới được phục vụ vì INT1 có mức ưu tiên thấp hơn. Trong thực tế 
sơ đồ mức ưu tiên ngắt trong bảng không có ý nghĩa gì cả mà một quy trình thăm dò 
trong đó 8051 thăm dò các ngắt theo trình tự cho trong bảng 11.3 và đáp ứng chúng 
một cách phù hợp. 
 Bảng 11.3: Mức ưu tiên các ngắt trong khi cấp lại nguồn. 
Mức ưu tiên cao xuống thấp 
Ngắt ngoài 0 INT0 
Ngắt bộ định thời 0 TF0 
Ngắt ngoài 1 INT1 
Ngắt bộ định thời 1 TF1 
Ngắt truyền thông nối tiếp (RI + TI) 
Ví dụ 11.1: 
 Hãy bình luận xem điều gì xảy ra nếu các ngắt INT0, TF0 và INT1 được kích 
hoạt cùng một lúc. Giả thiết rằng các mức ưu tiên được thiết lập như khi bật lại 
nguồn và các ngắt ngoài là ngắt theo sườn xung. 
Lời giải: 
 Nếu ba ngắt này được kích hoạt cùng một thời điểm thì chúng được chốt và 
được giữ ở bên trong. Sau đó kiểm tra tất cả năm ngắt theo trình tự cho trong bảng 
11.3. Nếu một ngắt bất kỳ được kích hoạt thì nó được phục vụ theo trình tự. Do vậy, 
khi cả ba ngắt trên đây cùng được kích hoạt một lúc thì ngắt ngoài 0 (IE0) được phục 
vụ trước hết sau đó đến ngắt Timer0 (TF0) và cuối cùng là ngắt ngoài 1 (IE1). 
 Hình 11.8: Thanh ghi mức ưu tiên ngắt IP, bít ưu tiên = 1 là mức ưu tiên cao, 
bít ưu tiên = 0 là mức ưu tiên thấp. 
- Bít D7 và D6 hay IP.7 và IP.6 - chưa dùng. 
- Bít D5 hay IP.5 là bít ưu tiên ngắt Timer2 (dùng cho 8052) 
- Bít D4 hay IP.4 là bít ưu tiên ngắt cổng nối tiếp 
- Bít D3 hay IP.3 là bít ưu tiên ngắt Timer1 
- Bít D2 hay IP.2 là mức ưu tiên ngắt ngoài 1 
- Bít D1 hay IP.1 là mức ưu tiên ngắt Timer 0 
- Bít D0 hay IP.0 là mức ưu tiên ngắt ngoài 0 
Người dùng không được viết phần mềm ghi các số 1 vào các bít chưa dùng vì 
chúng dành cho các ứng dụng tương lại. 
11.5.2 Thiết lập mức ưu tiên ngắt với thanh ghi IP. 
 Chúng ta có thể thay đổi trình tự trong bảng 11.3 bằng cách gán mức ưu tiên 
cao hơn cho bất kỳ ngắt nào. Điều này được thực hiện bằng cách lập trình một thanh 
ghi gọi là thanh ghi mức ưu tiên ngắt IP (Interrupt Priority). Trên hình 11.8 là các bít 
của thanh ghi này, khi bật lại nguồn thanh thi 1P chứa hoàn toàn các số 0 để tạo ra 
trình tự ưu tiên ngắt theo bảng 11.3. Để một ngắt nào đó mức ưu tiên cao hơn ta thực 
hiện đưa bít tương ứng lên cao. Hãy xem ví dụ 11.12. 
 Một điểm khác nữa cần được làm sáng tỏ là mức ưu tiên ngắt khi hai hoặc 
nhiều bít ngắt trong thanh ghi IP được đặt lên cao. Trong trường hợp này thì trong 
khi các ngắt này có mức ưu tiên cao hơn các ngắt khác chúng sẽ được phục vụ theo 
trình tự cho trong bảng 11.3. Xem ví dụ 11.13. 
Ví dụ 11.12: 
a) Hãy lập trình thanh ghi IP để gán mức ưu tiên cao nhất cho ngắt INT1 (ngắt 
ngoài 1) sau đó. 
b) Hãy phân tích điều gì xảy ra khi INT0, INT1 và TF0 được kích hoạt cùng lúc. 
Giả thiết tất cả các ngắt đều là các ngắt theo sườn. 
Lời giải: 
a) MOV IP, #0000 0100B ; Đặt bít IP.2 = 1 để gán INT1 mức ưu tiên cao nhất. 
Lệnh “SETB IP.2” cũng tác động tương tự bởi vì IP là thanh ghi có thể đánh địa 
chỉ theo bít. 
b) Lệnh trong bước a) gán mức ưu tiên cao hơn INT1 so với các ngắt khác, do vậy 
khi INT0, INT1 và TF0 được kích hoạt cùng lúc thì trước hết INT1 được phục vụ 
 -- -- PT2 PS PT1 PX1 PT0 PX0 
D0 D7 
trước rồi sau đó đến INT0 và cuối cùng là TF0. Điều này là do INT1 có mức ưu 
tiên cao hơn hai ngắt kia ở bước a). Sau khi thực hiện song ngắt INT1 thì 8051 trở 
về phục vụ ngắt còn lại theo trình tự ưu tiên trong bảng 11.3. 
Ví dụ 11.13: 
 Giả thiết rằng sau khi bật lại nguồn thì mức ưu tiên ngắt được thiết lập bởi 
lệnh “MOV IP, #0000 1100B”. Hãy bình luận về quá trình các ngắt được phục vụ 
như thế nào? 
Lời giải: 
 Lệnh “MOV IP, #0000 1100B” (chữ B là giá trị thập phân) thiết lập ngắt 
ngoài (INT1) và ngắt bộ Timer1 (TF1) có mức ưu tiên cao hơn các ngắt khác. Tuy 
nhiên, vì chúng được thăm dò theo bảng 11.3 nên chúng sẽ được phục vụ theo trình 
tự sau: 
 Mức ưu tiên cao nhất: Ngắt ngoài 1 (INT1) 
 Ngắt bộ Timer 1 (TF1) 
 Ngắt ngoài 0 (INT0) 
 Ngắt bộ Timer0 (TF0) 
 Mức ưu tiên thấp nhất: Ngắt cổng truyền thông nối tiếp (RI + RT). 
11.5.3 Ngắt trong ngắt. 
 Điều gì xảy ra nếu 8051 đang thực hiện một trình phục vụ ngắt thuộc một 
ngắt nào đó thì lại có một ngắt khác được kích hoạt? Trong những trường hợp như 
vậy thì một ngắt có mức ưu tiên cao hơn có thể ngắt một ngắt có mức ưu tiên thấp 
hơn. Đây gọi là ngắt trong ngắt. Trong 8051 một ngắt ưu tiên thấp có thể bị ngắt bởi 
một ngắt có mức ưu tiên cao hơn chứ không bị ngắt bởi một ngắt có mức ưu tiên thấp 
hơn. Mặc dù tất cả mọi ngắt đều được chốt và gửi bên trong nhưng không có ngắt 
mức thấp nào được CPU quan tâm ngay tức khắc nếu 8051 chưa kết thúc phục vụ các 
ngắt mức cao. 
11.5.4 Thu chộp ngắt bằng phần mềm (Triggering). 
 Có nhiều lúc ta cần kiểm tra một trình phục vụ ngắt bằng con đường mô 
phỏng. Điều này có thể được thực hiện bằng các lệnh đơn giản để thiết lập các ngắt 
lên cao và bằng cách đó buộc 8051 nhảy đến bảng véc tơ ngắt. Ví dụ, nếu bít IE 
dành cho bộ Timer1 được bật lên 1 thì một lệnh như “SETB TF1” sẽ ngắt 8051 
ngừng thực hiện công việc đang làm bất kỳ và buộc nó nhảy đến bảng véc tơ ngắt. 
Hay nói cách khác, ta không cần đợi cho Timer1 quay trở về 0 mới tạo ra ngắt. 
Chúng ta có thể gây ra một ngắt bằng các lệnh đưa các bít của ngắt tương ứng lên 
cao. 
 Như vậy ở chương này chúng ta đã biết ngắt là một sự kiện bên trong hoặc 
bên ngoài gây ra ngắt bộ vi điều khiển để báo cho nó biết rằng thiết bị cần được phục 
vụ. Mỗi một ngắt có một chương trình đi kèm với nó được gọi là trình phục vụ ngắt 
ISR. Bộ vi điều khiển 8051 có sáu ngắt, trong đó năm ngắt người dùng có thể truy 
cập được. Đó là hai ngắt cho các thiết bị phần cứng bên ngoài INT0 và INT1, hai 
ngắt cho các bộ định thời là TF0 và TF1 và ngắt lành cho truyền thông nối tiếp. 
 8051 có thể được lập trình cho phép hoặc cấm một ngắt bất kỳ cũng như thiết 
lập mức ưu tiên cho nó theo yêu cầu của thuật toán ứng dụng. 

File đính kèm:

  • pdfVi_dieu_khien_8051_ Assembly_11_LapTrinhCacNgat.pdf
Tài liệu liên quan