Báo cáo thí nghiệm Vi xử lý Đại học Bách Khoa Đại học Quốc Gia thành phố Hồ Chí Minh.Bài thí nghiệm 3: Thí nghiệm lập trình ngắt.Thí nghiệm 1: Mục tiêu: Nắm được cách sử dụng ngắt serial port.Yêu cầu: Viết chương trình làm song song 2 công việc sau:Nhận 1 byte từ máy tính và xuất ngược lại (echo) lên màn hình terminal.Bật LED gắn vào P1.1 khi SW 310 (gắn vào P1.0) được nhấn, và tắt LED khi phím được nhả.Hướng dẫn:Sử dụng ngắt serial port, nếu ngắt là ngắt thu (cờ RI bằng 1) thì xóa RI, đọc SBUF và ghi trở lạivào SBUF. Nếu TI bằng 1 thì xóa TI.Tác vụ đọc nút nhấn và hiển thị LED được viết trong chương trình chính.
Trang 1BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MỤC TIÊU
Nắm được cách lập trình ngắt cho 8051
CHUẨN BỊ
Đọc chương 1 và chương 8 của tài liệu hướng dẫn
Viết chương trình và mô phỏng các bài thí nghiệm trên Proteus dựa trên bài thí nghiệm 0
Trang 2BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
THÍ NGHIỆM 1
Mục tiêu: Nắm được cách sử dụng ngắt serial port
Yêu cầu:
Viết chương trình làm song song 2 công việc sau:
Nhận 1 byte từ máy tính và xuất ngược lại (echo) lên màn hình terminal
Bật LED gắn vào P1.1 khi SW 310 (gắn vào P1.0) được nhấn, và tắt LED khi phím được nhả
Hướng dẫn:
Sử dụng ngắt serial port, nếu ngắt là ngắt thu (cờ RI bằng 1) thì xóa RI, đọc SBUF và ghi trở lại vào SBUF Nếu TI bằng 1 thì xóa TI
Tác vụ đọc nút nhấn và hiển thị LED được viết trong chương trình chính
Kiểm tra:
Biên dịch và kiểm tra hoạt động của chương trình
Tại sao phải xét xem cờ TI hay cờ RI là nguồn gây ra ngắt?
Nếu không sử dụng ngắt, có thể viết được chương trình thực thi đầy đủ hai nhiệm vụ như vậy được không?
BÁO CÁO
1 Chương trình:
ORG 0000H LJMP START ORG 0023H LJMP ISR_SerialPort ORG 0030H
START: MOV SCON, #50H
Trang 3BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MOV PCON, #80H MOV TMOD, #21H MOV TH1, #-3 SETB EA ; Cho phép ngắn SETB ES ; Cho phép ngắt serial port SETB TR1
MAIN:
MOV R2, #10 ; Chống rung nút nhấn WAIT: JB P1.0, MAIN
DJNZ R2, WAIT CLR P1.1 ; Bật led P1.1 JNB P1.0, $ ; Chờ nút nhấn được thả SETB P1.1 ; Tắt led P1.1
SJMP MAIN ISR_SerialPort:
JNB RI, TRANSMIT ; Kiểm tra ngắt thu hay ngắt phát
MOV A, SBUF ; Đọc byte từ máy tính về MOV SBUF, A ; Gửi byte lên màn hình RETI
RETI DL10ms:
Trang 4BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MOV TH0, #HIGH(-9216) MOV TL0, #LOW(-9216) SETB TR0
JNB TF0, $ CLR TR0 CLR TF0 RET END
2 Kết quả thí nghiệm
a Kết quả mô phỏng: (Time/div = 0.5s, V/div = 1 V cho Channel A & Channel B)
Channel A: Chân P1.0
Channel B: Chân P1.1
Trang 5BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
b Trả lời câu hỏi
1) Tại sao phải xét xem cờ TI hay cờ RI là nguồn gây ra ngắt?
Vì mỗi nguồn ngắt khác nhau thì cho 1 công việc khác nhau Nếu nguồn ngắt là cờ RI, tức là đã nhận xong 1 byte từ máy tính, ta tiến hành cho xuất ngược lại lên màn hình terminal qua lệnh MOV SBUF, A
Nếu nguồn ngắt là TI, tức là xuất 1 byte lên màn hình terminal đã xong, ta xóa cờ TI để chờ lần xuất tiếp theo
2) Nếu không sử dụng ngắt, có thể viết được chương trình thực thi đầy đủ hai nhiệm vụ
như vậy được không?
Nếu không sử dụng ngắt, không thể viết chương trình thực thi đầy đủ hai nhiệm vụ như vậy Vì tuy có thể luân phiên kiểm tra trạng thái các bit P1.0 (nút nhấn), TI (cờ phát), RI (cờ thu) nhưng nếu đang thực hiện tác vụ khi nút nhấn được nhấn mà có máy xuất xuất 1 byte vào MCU thì MCU không thể nhận được trong khi nếu sử dụng ngắt thì chương trình
sẽ rẽ nhánh để thực hiện công việc nhận và phát ký tự lên màn hình terminal
Trang 6BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
THÍ NGHIỆM 2
Mục tiêu: Nắm được cách sử dụng ngắt timer
Yêu cầu:
Viết chương trình hiển thị lên 4 LED 7 đoạn một số có 4 chữ số, 4 ký số này chứa trong các ô nhớ 20H, 21H, 22H và 23H Ô nhớ 20H chứa số hàng nghìn
Hướng dẫn:
Ở LAB2 ta đã viết chương trình con DisplayLED hiển thị giá trị chứa trong R0, với số thứ tự LED chứa trong R1 Đồng thời, ta đã nắm được cách quét LED bằng cách cho 4 LED lần lượt sáng sau mỗi khoảng thời gian trễ
Ở thí nghiệm này, các LED 7 đoạn được quét sử dụng ngắt timer Để đạt được tần số quét 25 Hz, mỗi LED sẽ được sáng trong thời gian 10 ms
Các bước tiến hành:
Cấu hình timer 0 ở chế độ 1, thời gian tràn là 10 ms Cho phép ngắt timer 0, và cho timer chạy
Sử dụng thanh ghi R1 để xác định LED nào cần được bật Ban đầu R1 bằng 0, R1 tăng lên 1 sau mỗi lần bật LED để chuyển sang LED tiếp theo Khi R1 bằng 3, R3 sẽ quay lại bằng 0
Chương trình con DisplayLED chứa giá trị hiển thị trong R0 Giá trị này là 1 trong các byte ô nhớ 20H, 21H, 22H và 23H, tương ứng giá trị R1 (0-3) Đoạn chương trình sau cho phép lấy giá trị này: MOV A, R0
ADD A, R1
MOV R0, A
MOV A, @R0
MOV R0, A
Trang 7BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
START
Dừng timer, xóa cờ ngắt, đặt lại giá trị timer, cho phép timer chạy
Dừng timer, xóa cờ ngắt, đặt lại giá trị timer, cho phép timer chạy
Lấy giá trị hiển thị LED vào R0 Hiển thị ra LED tương ứng
Cập nhật giá trị R1
END Khi timer tràn, trong chương trình phục vụ ngắt ta cấu hình lại timer, hiển thị giá trị led 7 đoạn tương ứng, và cập nhật giá trị R1 để chỉ đến LED tiếp theo
Kiểm tra:
Biên dịch và kiểm tra hoạt động của chương trình
Cờ ngắt của timer được xóa bằng phần mềm hay phần cứng?
Trong thí nghiệm 2, chương trình chính làm nhiệm vụ gì?
BÁO CÁO
1 Chương trình:
ORG 0000H LJMP MAIN ORG 000BH LJMP ISR_TIMER0
Trang 8BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
ORG 0030H
MOV 20H, #2 MOV 21H, #0 MOV 22H, #2 MOV 23H, #1
SETB ET0 ; Cho phép ngắt timer 0 SJMP $
ISR_TIMER0:
CLR TR0 MOV TH0, #HIGH(-9216) MOV TL0, #LOW(-9216) SETB TR0
ACALL GET_R1 ; Lấy giá trị nạp vào R1 ACALL GET_R0 ; Lấy giá trị nạp vào R0 LCALL DisplayLED ; Hiển thị LED
RETI DisplayLED:
MOV DPTR, #LED MOV A, R1
MOVC A, @A + DPTR ORL A, R0
MOV DPTR, #0
Trang 9BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MOVX @DPTR, A RET
GET_R1:
INC R1 CJNE R1, #4, SKIP ; Nếu R1 = 4
GET_R0:
MOV A, #20H ADD A, R1 ; Lấy vị trí ô nhớ MOV R0, A
MOV A, @R0 MOV R0, A RET
LED: DB 70H, 0B0H, 0D0H, 0E0H
END
2 Kết quả thí nghiệm
a Kết quả mô phỏng:
Trang 10BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
b Trả lời câu hỏi
1) Cờ ngắt của timer được xóa bằng phần mềm hay phần cứng?
Cờ ngắt của timer được xóa bằng phần cứng
2) Trong thí nghiệm 2, chương trình chính làm nhiệm vụ gì?
Trong thí nghiệm 2, chương trình chính làm nhiệm vụ thiết lập cấu hình ban đầu cho chương trình ngắt và timer
Trang 11BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
THÍ NGHIỆM 3
Mục tiêu: Nắm được cách sử dụng ngắt timer phối hợp với chương trình khác
Yêu cầu:
Viết chương trình đếm số lần nhấn phím SW317, hiển thị lên 4 LED 7 đoạn
Hướng dẫn:
Đếm số lần nhấn phím như đã làm ở LAB4 Việc đếm số lần nhấn phím được thực hiện trong chương trình chính Giá trị được cập nhật vào các ô nhớ 20H, 21H, 22H và 23H Ô nhớ 20H chứa
số hàng nghìn
LED 7 đoạn được quét như ở thí nghiệm 2 dùng ngắt timer
Kiểm tra:
Biên dịch và kiểm tra hoạt động của chương trình
Trong thí nghiệm 3, chương trình chính làm nhiệm vụ gì?
Delay tạo cho quá trình chống rung của nút (nếu có) nên được tạo bằng cách nào?
BÁO CÁO
1 Chương trình:
ORG 0000H LJMP BEGIN ORG 000BH LJMP ISR_TIMER0 ORG 0030H
BEGIN:
MOV TMOD, #01H
Trang 12BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
SETB ET0 ; Cho phép ngắt timer 0 MAIN:
WAIT:
JB P1.7, MAIN ACALL DL10us DJNZ R2, WAIT INC 23H
ACALL UPDATE JNB P1.7, $ SJMP MAIN UPDATE: ; Hàm con điều chỉnh các giá trị thanh ghi
MOV A, 23H ; Kiểm tra hàng đơn vị CJNE A, #10, SKIP
MOV 23H, #0 INC 22H
CJNE A, #10, SKIP MOV 22H, #0 INC 21H
CJNE A, #10, SKIP MOV 21H, #0 INC 20H
Trang 13BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
CJNE A, #10, SKIP MOV 20H, #0 RET
ISR_TIMER0:
CLR TR0 MOV TH0, #HIGH(-9216) MOV TL0, #LOW(-9216) SETB TR0
ACALL GET_R1 ; Lấy giá trị nạp vào R1 ACALL GET_R0 ; Lấy giá trị nạp vào R0 LCALL DisplayLED ; Hiển thị LED
RETI DisplayLED:
MOV DPTR, #LED MOV A, R1
MOVC A, @A + DPTR ORL A, R0
MOV DPTR, #0 MOVX @DPTR, A RET
GET_R1:
INC R1 CJNE R1, #4, SKIP ; Nếu R1 = 4
Trang 14BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
SKIP: RET
GET_R0:
MOV A, #20H ADD A, R1 ; Lấy vị trí ô nhớ MOV R0, A
MOV A, @R0 MOV R0, A RET
DL10us:
MOV R5, #4 DJNZ R5, $ RET
LED: DB 70H, 0B0H, 0D0H, 0E0H
END
2 Kết quả thí nghiệm
a Kết quả mô phỏng:
b Trả lời câu hỏi
1) Trong thí nghiệm 3, chương trình chính làm nhiệm vụ gì?
Trong thí nghiệm 3, chương trình chính làm nhiệm vụ đếm số lần nhấn nút và điều chỉnh giá trị trong các thanh ghi chứa số lần đếm
2) Delay tạo cho quá trình chống rung của nút (nếu có) nên được tạo bằng cách nào?
Delay cho quá trình chống rung của nút nhấn nên được tạo bằng phần mềm bằng cách đọc nhiều lần giá trị của nút nhấn sau mỗi khoảng thời gian chờ, nếu các kết quả giống nhau thì xác nhận nút được nhấn, và ngược lại
Trang 15BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
THÍ NGHIỆM 4
Mục tiêu: Nắm được cách sử dụng ngắt timer phối hợp với chương trình khác
Yêu cầu:
Viết chương trình thực hiện đồng hồ bấm giây, hiển thị lên LED 7 đoạn Hai LED 3 và 2 thể hiện
số giây, 2 LED 1 và 0 thể hiện phần trăm của giây
Khi SW310 nhấn, đồng hồ reset về 0
SW 311 nhấn, đồng hồ bắt đầu chạy
SW 312 nhấn, đồng hồ dừng lại
Hướng dẫn
LED 7 đoạn được quét như ở thí nghiệm 2 dùng ngắt timer
Khi đồng hồ chạy, các giá trị thời gian được cập nhật dùng ngắt timer 0 Giá trị được cập nhật vào các ô nhớ 20H, 21H, 22H và 23H
Các SW310, SW311, SW312 được xử lý trong chương trình chính
Kiểm tra:
Biên dịch và kiểm tra hoạt động của chương trình
Các nút nhấn SW310, SW311, SW312 được xử lý như thế nào? Trình bày cụ thể?
BÁO CÁO
1 Chương trình:
ORG 0000H LJMP BEGIN ORG 000BH LJMP ISR_TIMER0 ; Hiển thị LED ORG 001BH
Trang 16BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
LJMP ISR_TIMER1 ; Đếm giờ ORG 0030H
BEGIN:
MOV TMOD, #11H
MOV R2, #10 WAIT311:
JB P1.1, SW310 ; Nếu không nhấn, kiểm tra SW310 ACALL DL10us
DJNZ R2, WAIT311 SETB ET1 ; Được nhấn, khởi động bộ đếm giờ JNB P1.1, $ ; Chờ thả nút
MOV R2, #10 WAIT310:
JB P1.0, SW312 ; Nếu không nhấn, kiểm tra SW312 ACALL DL10us
DJNZ R2, WAIT310 MOV 20H, #0 ; Được nhấn, reset các thanh ghi MOV 21H, #0 ; chứa nội dung bộ đếm giờ
MOV 22H, #0
Trang 17BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MOV 23H, #0 JNB P1.0, $ ; Chờ thả nút
MOV R2, #10 WAIT312:
JB P1.2, SW311 ; Nếu không nhấn, kiểm tra SW311 ACALL DL10us
DJNZ R2, WAIT312
JNB P1.2, $ ; Chờ thả nút SJMP SW310
CLR TR1 MOV TH1, #HIGH(-9216) ; 10ms MOV TL1, #LOW(-9216)
SETB TR1 INC 23H ACALL UPDATE ; Điều chỉnh giá trị các thanh ghi RETI
UPDATE: ; Hàm con điều chỉnh giá trị các thanh ghi
MOV A, 23H CJNE A, #10, SKIP ; SKIP trong GET_R1 MOV 23H, #0
INC 22H MOV A, 22H
Trang 18BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
CJNE A, #10, SKIP MOV 22H, #0 INC 21H MOV A, 21H CJNE A, #10, SKIP MOV 21H, #0 INC 20H MOV A, 20H CJNE A, #10, SKIP ; Nếu giới hạn trong 1 phút thì MOV 20H, #0 ; so sánh với 6
RET ISR_TIMER0:
CLR TR0 MOV TH0, #HIGH(-9216) MOV TL0, #LOW(-9216) SETB TR0
ACALL GET_R1 ; Lấy giá trị nạp vào R1 ACALL GET_R0 ; Lấy giá trị nạp vào R0 LCALL DisplayLED ; Hiển thị lên LED
RETI DisplayLED:
MOV DPTR, #LED MOV A, R1
MOVC A, @A + DPTR ORL A, R0
Trang 19BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
MOV DPTR, #0 MOVX @DPTR, A RET
GET_R1:
INC R1 CJNE R1, #4, SKIP ; Nếu R1 = 4
GET_R0:
MOV A, #20H ADD A, R1 ; Lấy vị trí ô nhớ MOV R0, A
MOV A, @R0 MOV R0, A RET
MOV R5, #4 DJNZ R5, $ RET
LED: DB 70H, 0B0H, 0D0H, 0E0H
END
2 Kết quả thí nghiệm
a Kết quả mô phỏng:
b Trả lời câu hỏi
Trang 20BÀI THÍ NGHIỆM 5
THÍ NGHIỆM LẬP TRÌNH NGẮT
Các nút nhấn SW310, SW311, SW312 được xử lý như thế nào? Trình bày cụ thể?
Các nút nhấn SW310, SW311, SW312 được quét liên tục theo trình tự:
Kiểm tra trạng thái nút nhấn SW311:
Nếu được nhấn thì tiến hành thời gian tràn 10ms cho timer 0 và set bit ET0
để cho phép ngắt timer0 hoạt động Sau đó chuyển sang kiểm tra trạng thái nút nhấn SW310
Nếu chưa được nhấn thì chuyển sang kiểm tra trạng thái nút nhấn SW310
Kiểm tra trạng thái nút nhấn SW310:
Nếu được nhấn thì tiến hành xóa các thanh ghi có địa chỉ 20H, 21H, 22H và 23H, sau đó khởi động lại ngắt timer0 và chuyển sang kiểm tra trạng thái nút nhấn SW312
Nếu chưa được nhấn thì chuyển sang kiểm tra trạng thái nút nhấn SW312
Kiểm tra trạng thái nút nhấn SW312:
Nếu được nhấn thì reset bit ET0 để dừng ngắt timer0 (đồng hồ ngừng đếm) Sau đó chuyển sang kiểm tra trạng thái nút nhấn SW311
Nếu chưa được nhấn thì chuyển sang kiểm tra trạng thái nút nhấn SW311