Giáo trình Vi điều khiển - Chương 11: Lập trình các ngắt
Một ngắt là một sự kiện bên trong hoặc bên ngoài làm ngắt bộ vi điều khiển
để báo cho nó biết rằng thiết bị cần dịch vụ của nó. Trong chương này ta tìm hiểu
khái niệm ngắt và lập trình ngắt.
11.1 Các ngắt của 8051.
11.1.1 Các ngắt ngược với thăm dò.
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)
để báo cho nó biết rằng thiết bị cần dịch vụ của nó. Trong chương này ta tìm hiểu
khái niệm ngắt và lập trình ngắt.
11.1 Các ngắt của 8051.
11.1.1 Các ngắt ngược với thăm dò.
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)
Bạn đang xem tài liệu "Giáo trình Vi điều khiển - Chương 11: Lập trình các ngắt", để tải tài liệu gốc về máy hãy click vào nút Download ở trên.
File đính kèm:
- giao_trinh_vi_dieu_khien_chuong_11_lap_trinh_cac_ngat.pdf
Nội dung text: Giáo trình Vi điều khiển - Chương 11: Lập trình các ngắt
- CHƯƠNG 11 Lập trình các ngắt Một ngắt là một sự kiện bên trong hoặc bên ngoài làm ngắt bộ vi điều khiển để báo cho nó biết rằng thiết bị cần dịch vụ của nó. Trong chương này ta tìm hiểu khái niệm ngắt và lập trình ngắt. 11.1 Các ngắt của 8051. 11.1.1 Các ngắt ngược với thăm dò. 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). Mỗi thiết bị có thể nhận được sự chú ý của bộ vi điều khiển dựa trên mức ưu tiên được gán cho nó. Đối với phương pháp thăm dò thì không thể gán mức ưu tiên cho các thiết bị vì nó kiểm tra tất cả mọi thiết bị theo kiểu hơi vòng. Quan trọng hơn là trong phương pháp ngắt thì bộ vi điều khiển cũng còn có thể che hoặc làm lơ một yêu cầu dịch vụ của thiết bị. Điều này lại một lần nữa không thể thực hiện được trong phương pháp thăm dò. Lý do quan trọng nhất là phương pháp ngắt được ưu chuộng nhất là vì phương pháp thăm dò làm lãng phí thời gian của bộ vi điều khiển bằng cách hỏi dò từng thiết bị kể cả khi chúng không cần đến dịch vụ. Nhằm để tránh thì người ta sử dụng phương pháp ngắt. Ví dụ trong các bộ định thời được bàn đến ở chương 9 ta đã dùng lệnh “JNB TF, đích” và đợi cho đến khi bộ định thời quay trở về 0. Trong ví dụ đó, trong khi chờ đợi thì ta có thể làm việc được gì khác có ích hơn, chẳng hạn như khi sử dụng phương pháp ngắt thì bộ vi điều khiển có thể đi làm các việc khác và khi cờ TF bật lên nó sẽ ngắt bộ vi điều khiển cho dù nó đang làm bất kỳ điều gì. 11.1.2 Trình phục vụ ngắt. Đối với mỗi ngắt thì phải có một trình phục vụ ngắt ISR hay trình quản lý ngắt. khi một ngắt được gọi thì bộ vi điều khiển phục vụ ngắt. Khi một ngắt được gọi thì bộ vi điều khiển chạy trình phục vụ ngắt. Đối với mỗi ngắt thì có một vị trí cố định trong bộ nhớ để giữ địa chỉ ISR của nó. Nhóm các vị trí nhớ được dành riêng để gửi các địa chỉ của các ISR được gọi là bảng véc tơ ngắt (xem hình 11.1). 11.1.3 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:
- Bảng 11.1: Bảng véc tơ ngắt của 8051. Ngắt Địa chỉ ROM Chân Bật lại nguồn (RESET) 0000 9 Ngắt phần cứng ngoài (INT0) 0003 12 (P3.2) Ngắt bộ Timer0 (TF0) 000B Ngắt phần cứng ngoài 1 (INT1) 0013 13 (P3.3) Ngắt bộ Timer1 (TF1) 001B Ngắt COM nối tiếp (RI và TI) 0023 11.1.5 Cho phép và cấm ngắt. Khi bật lại nguồn thì tất cả mọi ngắt đều bị cấm (bị che) có nghĩa là không có ngắt nào sẽ được bộ vi điều khiển đáp ứng nếu chúng được kích hoạt. Các ngắt phải được kích hoạt bằng phần mềm để bộ vi điều khiển đáp ứng chúng. Có một thanh ghi được gọi là cho phép ngắt IE (Interrupt Enable) chịu trách nhiệm về việc cho phép (không che) và cấm (che) các ngắt. Hình 11.2 trình bày thanh ghi IE, lưu ý rằng IE là thanh ghi có thể đánh địa chỉ theo bít. Từ hình 11.2 ta thấy rằng D7 của thanh ghi IE được gọi là bít cho phép tất cả các ngắt EA (Euable All). Bít này phải được thiết lập lên 1 để phần còn lại của thanh ghi hoạt động được. Bít D6 chưa được sử dụng. Bít D54 được dành cho 8051, còn bít D4 dùng cho ngắt nối tiếp v.v 11.1.6 Các bước khi cho phép ngắt. Để cho phép một ngắt ta phải thực hiện các bước sau: 1. Bít D7 của thanh ghi IE là EA phải được bật lên cao để cho phép các bít còn lại của thanh ghi nhận được hiệu ứng. 2. Nếu EA = 1 thì tất cả mọi ngắt đều được phép và sẽ được đáp ứng nếu các bít tương ứng của chúng trong IE có mức cao. Nếu EA = 0 thì không có ngắt nào sẽ được đáp ứng cho dù bít tương ứng của nó trong IE có giá trị cao. Để hiểu điểm quan trong này hãy xét ví dụ 11.1. Hình 11.2: Thanh ghi cho phép ngắt IE. D7 D0 EA ET2 ES ET1 EX1 ET0 EX0 EA IE.7 Nếu EA = 0 thì mọi ngắt bị cấm Nếu EA = 1 thì mỗi nguồn ngắt được cho phép hoặc bị cấm bằng các bật hoặc xoá bít cho phép của nó. - - IE.6 Dự phòng cho tương lai ET2 IE.5 Cho phép hoặc cấm ngắt tràn hoặc thu của Timer2 (8051) ES IE.4 Cho phép hoặc cấm ngắt cổng nối tiếp ET1 IE.3 Cho phép hoặc cấm ngắt tràn của Timer1 EX1 IE.2 Cho phép hoặc cấm ngắt ngoài 1
- Hình 11.3: Ngắt bộ định thời TF0 và TF1. Hãy để những điểm chương trình dưới đây của chương trình trong ví dụ 11.2. 1. Chúng ta phải tránh sử dụng không gian bộ nhớ dành cho bảng véc tơ ngắt. Do vậy, ta đặt tất cả mã khởi tạo tại địa chỉ 30H của bộ nhớ. Lệnh LJMP là lệnh đầu tiên mà 8051 thực hiện khi nó được cấp nguồn. Lệnh LJMP lái bộ điều khiển tránh khỏi bảng véc tơ ngắt. 2. Trình phục vụ ISR của bộ Timer0 được đặt ở trong bộ nhớ bắt đầu tự địa chỉ 000BH và vì nó quá nhỏ đủ cho vào không gian nhớ dành cho ngắt này. 3. Chúng ta cho phép ngắt bộ Timer0 với lệnh “MOV IE, #1000 010H” trong chương trình chính MAIN. 4. Trong khi dữ liệu ở cổng P0 được nhận vào và chuyển liên tục sang công việc P1 thì mỗi khi bộ Timer0 trở về 0, cờ TF0 được bật lên và bộ vi điều khiển thoát ra khỏi vòng lặp BACK và đi đến địa chỉ 000BH để thực hiện ISR gắn liền với bộ Timer0. 5. Trong trình phục vụ ngắt ISR của Timer0 ta thấy rằng không cần đến lệnh “CLR TF0” trước khi lệnh RETI. Lý do này là vì 8051 xoá cờ TF bên trong khi nhảy đến bảng véc tơ ngắt. Ví dụ 11.2: Hãy viết chương trình nhân liên tục dữ liệu 8 bít ở cổng P0 và gửi nó đến cổng P1 trong khi nó cùng lúc tạo ra một sóng vuông chu kỳ 200μs trên chân P2.1. Hãy sử dụng bộ Timer0 để tạo ra sóng vuông, tần số của 8051 là XTAL = 11.0592MHz. Lời giải: Ta sử dụng bộ Timer0 ở chế độ 2 (tự động nạp lại) giá trị nạp cho TH0 là 100/1.085μs = 92. ; - - Khi khởi tạo vào chương trình main tránh dùng không gian. ; Địa chỉ dành cho bảng véc tơ ngắt. ORG 0000H CPL P2.1 ; Nhảy đến bảng véc tơ ngắt. ; ; - - Trình ISR dành cho Timer0 để tạo ra sóng vuông. ORG 0030H ; Ngay sau địa chỉ bảng véc-tơ ngắt MAIN: TMOD, #02H ; Chọn bộ Timer0, chế độ 2 tự nạp lại MOV P0, #0FFH ; Lấy P0 làm cổng vào nhận dữ liệu MOV TH0, # - 92 ; Đặt TH0 = A4H cho – 92 MOV IE, #82H ; IE = 1000 0010 cho phép Timer0 SETB TR0 ; Khởi động bộ Timer0 BACK: MOV A, P0 ; Nhận dữ liệu vào từ cổng P0 MOV P1, A ; Chuyển dữ liệu đến cổng P1 SJMP BACK ; Tiếp tục nhận và chuyển dữ liệu ; Chừng nào bị ngắt bởi TF0 END
- ORG 0 LJMP MAIN ORG 000BH ; Chương trình con phục vụ ngắt cho Timer0 CPL P1.2 MOV TL0, # 00 MOV TH0, # 0DCH RETI ORG 30H ; main program for initialization MAIN: MOV TMOD, # 00000001B ; Chọn Timer0 chế độ 1 MOV TL0, # 0DCH MOV IE, # 82H ; Cho phép ngắt Timer0 SETB TR0 HERE: SJMP HERE END 805 P1. 50Hz square 11.3 Lập trình các ngắt phần cứng bên ngoài. Bộ vi điều khiển 8051 có hai ngắt phần cứng bên ngoài là chân 12 (P3.2) và chân 13 (P3.3) dùng cho ngắt INT0 và INT1. Khi kích hoạt những chân này thì 8051 bị ngắt tại bất kỳ công việc nào mà nó đang thực hiện và nó nhảy đến bảng véc tơ ngắt để thực hiện trình phục vụ ngắt. Level - INTO 0 0003 (Pin 1 32) IE0 (TCON.1 Edge - ) Level - INTO 0 IT1 0013 (Pin 1 33) IE0 (TCON. Edge - ) 11.3.1 Các ngắt ngoài INT0 và INT1.
- Trong chương trình này bộ vi điều khiển quay vòng liên tục trong vòng lặp HERE. Mỗi khi công tắc trên chân P3.3 (INT1) được kích hoạt thì bộ vi điều khiển thoát khỏi vòng lặp và nhảy đến bảng véc tơ ngắt tại địa chỉ 0013H. Trình ISR cho INT1 bật đèn LED lên giữ nó một lúc và tắt nó trước khi trở về. Nếu trong lúc nó thực hiện lệnh quay trở về RET1 mà chân INT1 vẫn còn ở mức thấp thì bộ vi điều khiển khởi tạo lại ngắt. Do vậy, để giải quyết vấn đề này thì chân INT1 phải được đưa lên cao tại thời điểm lệnh RET1 được thực hiện. 11.3.3 Trích mẫu ngắt theo mức. Các chân P3.2 và P3.3 bình thường được dùng cho vào - ra nếu các bít INT0 và INT1 trong thanh ghi IE không được kích hoạt. Sau khi các ngắt phần cứng trong thanh gi IE được kích hoạt thì bộ vi điều khiển duy trì trích mẫu trên chân INTn đối với tín hiệu mức thấp một lần trong một chu trình máy. Theo bảng dữ liệu của nhà sản xuất của bộ vi điều khiển thì “chân ngắt phải được giữ ở mức thấp cho đến khi bắt đầu thực hiện trình phục vụ ngắt ISR. Nếu chân INTn được đưa trở lại mức cao trước khi bắt đầu thực hiện ISR thì sẽ chẳng có ngắt nào xảy ra”. Tuy nhiên trong quá trình kích hoạt ngắt theo mức thấp nên nó lại phải đưa lên mức cao trước khi thực hiện lệnh RET1 và lại theo bảng dữ liệu của nhà sản xuất thì “nếu chân INTn vẫn ở mức thấp sau lệnh RETI của trình phục vụ ngắt thì một ngắt khác lại sẽ được kích hoạt sau khi lệnh RET1 được thực hiện”. Do vậy, để bảo đảm việc kích hoạt ngắt phần cứng tại các chân INTn phải khẳng định rằng thời gian tồn tại tín hiệu mức thấp là khoảng 4 chu trình máy và không được hơn. Điều này là do một thực tế là ngắt theo mức không được chốt. Do vậy chân ngắt phải được giưa ở mức thấp cho đến khi bắt đầu thực hiện ISR. 1 chu trình máy 1.085μs đến chân INT0 4 chu trình máy (4MC) hoặc INT1 4 × 1.085μs Ghi chú: Khi bật lại nguồn (RESET) thì cả hai chân INT0 và INT1 đều ở mức thấp tạ o các ngắt ngoài theo mức. Hình 11.5: Thời gian tối thiểu của ngắt theo mức thấp (XTAL = 11.0592MHz) 11.3.4 Các ngắt theo sườn. Như đã nói ở trước đây trong quá trình bật lại nguồn thì 8051 làm các chân INT0 và INT1 là các ngắt theo mức thấp. Để biến các chân này trở thành các ngắt theo sườn thì chúng ta phải viết chưnơg trình cho các bít của thanh ghi TCON. Thanh thi TCON giữ các bít cờ IT0 và IT1 xác định chế độ ngắt theo sườn hay ngắt theo mức của các ngắt phần cứng IT0 và IT1 là các bít D0 và D2 của thanh ghi
- đang được nối tới đèn LED (hoặc một còi báo). Hay nói cách khác, đèn LED được bật và tắt cùng tần số với các xung được cấp tới chân INT1. Đây là phiên bản ngắt theo sườn xung của ví dụ 11.5 đã trình bày ở trên. Lời giải: ORG 0000H LJMP MAIN ; - - Trình phục vụ ngắt ISR dành cho ngắt INT1 để bật đèn LED ORG 0013H ; Nhảy đến địa chỉ của trình phục vụ ngắt INT1 SETB P1.3 ; Bật đèn LED (hoặc còi) MOV R3, #225 BACK: DJNZ R3, HERE ; giữ đèn LED (hoặc còi) một lúc CLR P1.3 ; Tắt đèn LED (hoặc còi) RETI ; Quay trở về từ ngắt ; - - Bắt đầu chương trình chính ORG 30H SETB TCON.2 ; Chuyển ngắt INT1 về kiểu ngắt theo sườn xung MOV IE, #10001B ; Cho phép ngắt ngoài INT1 HERE: SJMP HERE ; Dừng ở đây cho đến khi bị ngắt END 11.3.5 Trình mẫu ngắt theo sườn. Trước khi kết thúc phần này ta cần trả lời câu hỏi vậy thì ngắt theo sườn được trích mẫu thường xuyên như thế nào? Trong các ngắt theo sườn, nguồn ngoài phải giữ ở mức cao tối thiểu là một chu trình máy nữa đê đảm bảo bộ vi điều khiển nhìn thấy được sự chuyển dịch từ cao xuống thấp của sườn xung. 1M 1.085μs 1.085μs 1M Thời hạn xung tối thiểu để phát hiện ra các ngắt theo sườn xung với tần số XTAL = 11.0592MHz Sườn xuống của xung được chốt bởi 8051 và được giữa bởi thanh ghi TCON. Các bít TCON.1 và TCON.3 giữ các sườn được chốt của chân INT0 và INT1 tương ứng. TCON.1 và TCON.3 cũng còn được gọi là các bít IE0 và IE1 như chỉ ra trên hình 11.6. Chúng hoạt động như các cờ “ngắt đang được phục vụ” (Interrupt-in- server). Khi một cờ “ngắt đang được phục vụ” bật lên thì nó báo cho thế giới thực bên ngoài rằng ngắt hiện nay đang được xử lý và trên chân INTn này sẽ không có ngắt nào được đáp ứng chừng nào ngắt này chưa được phục vụ xong. Đây giống như tín hiệu báo bận ở máy điện thoại. Cần phải nhấn mạnh hạt điểm dưới đây khi quan tâm đến các bít IT0 và IT1 của thanh ghi TCON. 1. Khi các trình phục vụ ngắt ISR kết thúc (nghĩa là trong thanh ghi thực hiện lệnh RETI). Các bít này (TCON.1 và TCON.3) được xoá để báo rằng ngắt được hoàn tất và 8051 sẵn sàng đáp ứng ngắt khác trên chân đó. Để ngắt khác được nhận và
- Trong khi 8051 thực hiện ISR thì không có một sườn xung nào được ghi nhận trên chân INT0 (hay INT1) để ngăn mọi ngắt trong ngắt. Chỉ trong khi thực hiện lệnh RETI ở cuối trình phục vụ ngắt ISR thì các bít IEx mới bị báo rằng một sườn xung cao xuống thấp mới trên chân INT0 (hay INT1) sẽ kích hoạt ngắt trở lại. Từ phần trình bày trên ta thấy rằng các bít IE0 và IE1 được 8051 sử dụng bên trong để báo có một ngắt đang được xử lý hay không. Hay nói cách khác là lập trình viên không phải quan tâm đến cá bít này. 11.3.6.3 Các bít TR0 và TR1. Đây là những bít D4 và D6 (hay TCON.4 và TCON.6) của thanh ghi TCON. Các bít này đã được giới thiệu ở chương 9 chúng được dùng để khởi động và dừng các bộ định thời Timer0 và Timer1 tương ứng. Vì thanh ghi TCON có thể đánh địa chỉ theo bít nên có thể sử dụng các lệnh “SETB TRx” và “CLR TRx” cũng như các lệnh “SETB TCON.4” và “CLR TCON.4”. 11.3.6.4 Các bít TF0 và TF1. Các bít này là D5 (TCON.5) và D7 (TCON.7) của thanh ghi TCON mà đã được giới thiệu ở chương 9. Chúng ta được sử dụng bởi các bộ Timer0 và Timer1 tương ứng để báo rằng các bộ định thời bị tràn hay quay về không. Mặc dù ta đã dùng các lệnh “JNB TFx, đích” và “CLR TFx” nhưng chúng ta cũng không thể sử dụng các lệnh như “SETB TCON.5, đích” và “CLR TCON.5” vì TCON là thanh ghi có thể đánh địa chỉ theo bít. 11.4 Lập trình ngắt truyền thông nối tiếp. Trong chương 10 chúng ta đã nghiên cứu về truyền thông nối tiếp của 8051. Tất cả các ví dụ trong chương ấy đều sử dụng phương pháp thăm dò (polling). ậ chương này ta khám phá truyền thông dựa trên ngắt mà nó cho phép 8051 làm việc rất nhiều việc ngoài việc truyền và nhận dữ liệu từ cổng truyền thông nối tiếp. 11.4.1 Các cờ RI và TI và các ngắt. Như đã nói ở chương 10 thì cờ ngắt truyền TI (Transfer interrupt) được bật lên khi bít cuối cùng của khung dữ liệu, bít stop được truyền đi báo rằng thanh ghi SBUF sẵn sàng truyền byte kế tiếp. Trong trường hợp cờ RI (Receive Interrupt) thì nó được bật lên khi toàn bộ khung dữ liệu kể cả bít stop đã đươc nhận. Hay nói cách khác khi thanh ghi SBUF đã có một byte thì cờ RI bật lên báo rằng byte dữ liệu nhận được cần lấy đi cất vào nơi an toàn trước khi nó bị mất (bị ghi đè) bởi dữ liệu mới nhận được. Chừng nào còn nói về truyền thông nối tiếp thì tất cả mọi khái niệm trên đây đều áp dụng giống như nhau cho dù sử dụng phương pháp thăm dò hay sử dụng phương pháp ngắt. Sự khác nhau duy nhất giữa hai phương pháp này là ở cách phục vụ quá trình truyền thông nối tiếp như thế nào. Trong phương pháp thăm dò thì chúng ta phải đợi cho cờ (TI hay RI) bật lên và trong lúc chờ đợi thì ta không thể làm gì được cả. Còn trong phương pháp ngắt thì ta được báo khi 8051 đã nhận được một byte hoặc nó sẵn sàng chuyển (truyền) byte kế tiếp và ta có thể làm các công việc khác trong khi truyền thông nối tiếp đang được phục vụ. Trong 8051 chỉ có một ngắt dành riêng cho truyền thông nối tiếp. Ngắt này được dùng cho cả truyền và nhận dữ liệu. Nếu bít ngắt trong thanh gi IE (là bít IE.4) được phép khi RI và TI bật lên thì 8051 nhận được ngắt và nhảy đến địa chỉ trình phục vụ ngắt dành cho truyền thông nối tiếp 0023H trong bảng véc tơ ngắt để thực
- TRANS: CLR TI ; Xoá cờ TI vì CPU không làm điều này RETI ; Trở về từ ISR END Trong vấn đề trên thấy chú ý đến vai trò của cờ TI và RI. Thời điểm một byte được ghi vào SBUF thì nó được đóng khung và truyền đi nối tiếp. Kết quả là khi bít cuối cùng (bít stop) được truyền đi thì cờ TI bật lên cao và nó gây ra ngắt nối tiếp được gọi khi bít tương ứng của nó trong thanh ghi IE được đưa lên cao. Trong trình phục vụ ngắt nối tiếp, ta phải kiểm tra cả cờ TI và cờ RI vì cả hai đều có thể 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á
- 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). D7 D0 PT2 PS PT1 PX1 PT0 PX0 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
- 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.