Ví dụ: Một chương trình yêu cầu các đáp ứng 0, 1, 2, hoặc 3 của một user để chọn một
trong bốn hành động. Viết đoạn chương trình nhập một ký tự từ bàn phím và nhảy đến
ACT0, ACT1, ACT2 hoặc ACT3, phụ thuộc vào đáp ứng của user. Bỏ qua việc kiểm tra
lỗi.
Pseudo-code:
[nhập một ký tự]
CASE [ký tự] OF
‘0’: [hành động 0]
‘1’: [hành động 1]
‘2’: [hành động 2]
‘3’: [hành động 3]
END_CASE
22 trang |
Chia sẻ: thienmai908 | Lượt xem: 1420 | Lượt tải: 0
Bạn đang xem trước 20 trang nội dung tài liệu Bài giảng vi xử lý Chương 3: Lập trình hợp ngữ họ MCS-51, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
Hành động 3
No
Yes Yes Yes Yes No
Nhập ký tự
Mã 8051
CALL INCH
CJNE A, #’0’, SKIP1
ACT0: .
.
.
SKIP1: CJNE A, #’1’, SKIP2
15
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
ACT1: .
.
.
SKIP2: CJNE A, #’2’, SKIP3
ACT2: .
.
.
SKIP3: CJNE A, #’3’, EXIT
ACT2: .
.
.
EXIT: (tiếp tục)
Hay
CALL INCH
ANL A, #3
RL A
MOV DPTR, #TABLE
JMP @A+DPTR
TABLE: AJMP ACT0
AJMP ACT1
AJMP ACT2
ACT3: .
.
.
JMP EXIT
ACT0: .
.
.
JMP EXIT
ACT1: .
.
.
JMP EXIT
ACT2: .
.
.
EXIT: (tiếp tục)
4. Kỹ thuật tạo trễ
Ví dụ 1: Viết chương trình con tên DELAY_100 để tạo trễ (trì hoãn) 100 μs. Giả sử dùng
thạch anh 12 MHz (fOSC = 12 MHz).
Giải:
Hướng dẫn: Dùng thời gian thực thi lệnh để tính thời gian tạo trễ cần thiết.
fOSC = 12 MHz → fM = fOSC / 12 = 1 MHz → TM = 1 μs
Cách 1: Dùng các lệnh NOP
DELAY_100:
; dùng 98 lệnh NOP → 98 μs
NOP
16
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
NOP
…
NOP
RET ; 2 μs → 98 + 2 = 100 μs
Cách 2: Dùng vòng lặp để chương trình ngắn gọn hơn.
DELAY_100:
MOV R7,#49 ; 1 μs
LOOP: DJNZ R7,LOOP ; 2 μs / 1 lệnh → 2 x 49 = 98 μs
RET ; 2 μs
Tổng quát:
DELAY_T:
MOV R7,#N ; 1 TM, N ≤ 255
LOOP: DJNZ R7,LOOP ; 2 TM / 1 lệnh → (2 x N) TM
RET ; 2 TM
→ tổng thời gian tạo trễ: T = [(1 + 2 x N + 2)TM] ≅ [(2 x N) TM] μs
Chú ý:
Lệnh LOOP: DJNZ R7, LOOP tương đương với lệnh DJNZ R7,$. Dấu $ là một ký
hiệu đặc biệt của trình dịch hợp ngữ ASM51 để tham chiếu vị trí của lệnh hiện
hành.
Ví dụ 2: Viết chương trình con tên DELAY_10ms để tạo trễ 10 ms. Giả sử dùng thạch anh
12 MHz (fOSC = 12 MHz).
Giải:
Thời gian cần tạo trễ: T = 10 ms = 10000 μs = 10000 TM.
Nếu dùng vòng lặp như ví dụ 8 thì thời gian tạo trễ tối đa khoảng ≅ 2 x 255 = 510μs
< 10000μs. Như vậy cần dùng 2 vòng lặp lồng nhau.
Chương trình:
DELAY_10ms:
MOV R7,#20 ; 1 μs
LOOP: MOV R6,#250 ; 1 μs
DJNZ R6,$ ; 2 μs / 1 lệnh
DJNZ R7,LOOP ; 2 μs / 1 lệnh
RET ; 2 μs
→ tổng thời gian tạo trễ: T = 1 + 20(1 + 2 x 250 + 2) + 2 = 10063 μs ≅ 10000 μs
Tổng quát:
DELAY_T:
MOV R7,#M ; 1 TM
LOOP: MOV R6,#N ; 1 TM
DJNZ R6,$ ; 2 TM / 1 lệnh
DJNZ R7,LOOP ; 2 TM / 1 lệnh
RET ; 2 TM
→ tổng thời gian tạo trễ: T = [1 + M(1 + 2 x N + 2) + 2]TM ≅ [(2 x M x N)TM] μs
Ví dụ 3: Viết chương trình tạo sóng vuông tuần hoàn đối xứng tại chân P1.0 có tần số là
f= 10 KHz. Giả sử fOSC = 12 MHz.
Giải:
fOSC = 12 MHz → fM = fOSC / 12 = 1 MHz → TM = 1 μs
f = 10 KHz → T = 0,1 ms = 100 μs
17
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
Sóng vuông đối xứng → tH = tL = 50 μs = 50TM
T
tH tL
Chương trình:
ORG 0000H
LOOP: CPL P1.0 ; 1 μs
MOV R7,#28 ; 1 μs
DJNZ R7,$ ; 2 x 28 = 46 μs
SJMP LOOP ; 2 μs
END
18
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
CÂU HỎI VÀ BÀI TẬP CHƯƠNG 3
3.1. Hãy cho biết cách định địa chỉ của mỗi lệnh sau:
a.MOV R1,A b.MOV A,#12H c.MOV A,@R1 d.PUSH B
e.MOV A,12H f.SJMP LOOP g.ACALL SUB1 h.LJMP 0567H
3.2. Để nạp vào R4 giá trị 56H thì có cần dấu ‘#’ trong lệnh: MOV R4,#56H không?
3.3. Sự khác biệt giữa 2 lệnh sau là gì?
INC A
INC ACC
3.4. Hãy xác định offset tương đối cho lệnh:
SJMP AHEAD
Biết lệnh đặt tại địa chỉ 0400H và 0401H, nhãn AHEAD đặt tại địa chỉ 041FH.
3.5. Hãy xác định offset tương đối cho lệnh:
SJMP BACK
Biết lệnh đặt tại địa chỉ A050H và A051H, nhãn BACK đặt tại địa chỉ 9FE0H.
3.6. Giả sử lệnh:
AJMP THERE
trong bộ nhớ chương trình ở địa chỉ 2FF0H và 2FF1H, nhãn THERE ở địa chỉ 2F96H. Hãy xác
định các byte mã máy của lệnh trên?
3.7. Giả sử thanh ghi A chứa 5AH. Hãy cho biết giá trị trong thanh ghi A sau khi thực hiện
lệnh sau:
XRL A,#0FFH
Hãy tìm một lệnh khác tương đương với lệnh trên?
3.8. Giả sử thanh ghi A chứa 50H và thanh ghi PSW chứa 0CH. Hãy cho biết giá trị trong
thanh ghi A sau khi thực hiện lệnh sau:
RLC A
3.9. Hãy xác định nội dung của thanh ghi A sau khi thực hiện các chuỗi lệnh sau:
a. MOV A,#25 b. MOV A,#7FH
MOV R7,#18H MOV 50H,#29H
ADD A,R7 MOV R0,#50H
XCHD A,@R0
3.10. Cho biết giá trị của cờ CY sau khi thực hiện các đoạn mã sau:
a. CLR C b. MOV A,#54H c. MOV A,#250
CPL C ADD A,#0C4H ADD A,#05
3.11. Các lệnh nào sau đây là không hợp lệ:
1.MOV R7,#500 2.MOV A,50H 3.ADD A,R5 4.ADD R3,A
5.MOV R1,#50 6.MOV A,#F5H 7.ADD A,#50H 8.MOV @R1,R7
9.PUSH A 10.MOV A,@R3 11.MOV R7,#00 12.MOV R6,R7
3.12. Cho nội dung của các ô nhớ và thanh ghi: (30H) = 12H; (B) = 34H; (A) = 05H. Hãy xác
định nội dung của ô nhớ 30H, thanh ghi A và B sau khi thực thi đoạn chương trình sau:
MOV R1,#30H
XCH A,B
XCHD A,@R1
SWAP A
XCHD A,@R1
SWAP A
3.13. Xét đoạn chương trình sau:
19
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
MOV R0,#20H
MOV R1,#30H
MOV R0,#2 ; *
CLR C
NEXT: MOV A,@R0
ADDC A,@R1
MOV @R0,A
INC R0
INC R1
DJNZ R2,NEXT
a. Sau khi thực hiện lệnh thứ 3 (có chú thích *), nội dung của R0, R1 và R2 là bao nhiêu?
b. Lệnh có nhãn NEXT được thực thi bao nhiêu lần?
c. Sau khi hoàn tất chương trình trên thì nội dung của R0, R1 và R2 là bao nhiêu?
d. Cho nội dung của các ô nhớ ban đầu là: (20H) = 23H, (21H) = 45H, (30H) = 67H, (31H) =
89H:
• Cho biết nội dung của các ô nhớ trên sau khi thực thi xong chương trình trên?
• Chức năng của chương trình trên?
3.14. Xét chương trình sau:
ORG 0000H
MOV R0,#05H
MOV R1,#40H
MOV R2,#0 ; *
MOV @R1,#0
AGAIN: MOV DPTR,#TABLE
MOV A,R2
MOVC A,@A+DPTR
ADD A,@R1
MOV @R1,A
INC R2
DJNZ R0,AGAIN
AJMP EXIT
TABLE: DB 10H,11H,12H,13H,14H
EXIT: NOP
END
a. Sau khi thực hiện lệnh có chú thích *, nội dung của R0, R1 và R2 là bao nhiêu?
b. Lệnh có nhãn AGAIN được thực thi bao nhiêu lần?
c. Sau khi hoàn tất chương trình trên thì nội dung của R0, R1 và R2 là bao nhiêu?
d. Nội dung của ô nhớ 40H sau khi thực thi xong chương trình trên?
e. Chức năng của chương trình trên?
f. Nếu kết quả của chương trình trên được cất vào ô nhớ 50H thì lệnh nào cần sửa đổi?
3.15. Viết 1 đoạn chương trình xóa 20 byte ô nhớ RAM nội bắt đầu từ địa chỉ 30H.
3.16. Viết 1 đoạn chương trình xóa 100 byte ô nhớ RAM ngoài bắt đầu từ địa chỉ 1000H.
3.17. Viết 1 đoạn chương trình đọc 20 byte ô nhớ RAM ngoài bắt đầu từ địa chỉ 2000H và ghi
vào RAM nội bắt đầu từ địa chỉ 30H.
3.18. Viết chương trình con TINHTB_3SO tính giá trị trung bình của 3 số nguyên dương chứa
trong 3 ô nhớ 30H, 31H và 32H. Kết quả (phần nguyên) chứa trong thanh ghi R7. Giả sử tổng của
3 số đó không lớn hơn 255.
3.19. Viết 1 chương trình con cộng 2 số 16 bit không dấu, số hạng 1 cất trong R7_A (R7: byte
cao, A: byte thấp), số hạng 2 cất trong ô nhớ 31H_30H (31H: byte cao, 30H: byte thấp). Kết quả
trả về cất trong R7_A.
20
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
3.20. Viết 1 chương trình con trừ 2 số 16 bit không dấu, số bị trừ cất trong R7_A (R7: byte cao,
A: byte thấp), số trừ cất trong ô nhớ 31H_30H (31H: byte cao, 30H: byte thấp). Kết quả trả về
cất trong R7_A.
3.21. * Viết 1 chương trình con nhân số 16 bit cất trong R7_A (R7: byte cao, A: byte thấp) với
số 8 bit cất trong B. Kết quả trả về 24 bit cất trong R7_B_A.
3.22. * Viết 1 chương trình con chia số 16 bit cất trong R7_A (R7: byte cao, A: byte thấp) cho
số 8 bit cất trong B. Kết quả: thương số cất trong R7_A, dư số cất trong B.
3.23. Viết 1 chương trình con lấy bù 2 của số 16 bit cất trong R7_A (R7: byte cao, A: byte
thấp). Kết quả trả về cất trong R7_A.
3.24. Viết chương trình con BINTOBCD chuyển số nhị phân trong A sang số BCD 3 digit (ký
số) cất trong các ô nhớ 32H, 31H và 30H (32H: trăm, 31H: chục, 30H: đơn vị).
3.25. Viết chương trình con BCDTOBIN chuyển số BCD không nén (2 ký số) trong A sang số
nhị phân cất trong ô nhớ 30H.
3.26. * Viết chương trình con BCDTOBIN16 chuyển số nhị phân 16 bit trong R7_A (R7: byte
cao, A: byte thấp) sang số BCD 5 digit cất trong các ô nhớ theo thứ tự từ chục ngàn đến đơn vị
là: 34H_33H_32H_31H_30H.
3.27. Viết chương trình đổi các ký tự chữ hoa trong các ô nhớ 30H → 3FH trong RAM nội sang
chữ thường.
3.28. Viết chương trình đổi các ký tự chữ hoa trong các ô nhớ 30H → 3FH trong RAM nội sang
chữ thường và ngược lại.
3.29. Viết chương trình con SOSANH16 so sánh số 16 bit không dấu cất trong R7_A (R7: byte
cao, A: byte thấp) với số 16 bit không dấu làm giá trị chuẩn cất trong ô nhớ 31H_30H (31H: byte
cao, 30H: byte thấp). Kết quả trả về:
- (C) = 1 nếu (R7_A) < (31H_30H)
- (C) = 0 nếu (R7_A) ≥ (31H_30H)
Lưu ý: phải bảo toàn nội dung của các thanh ghi và ô nhớ ở trên.
3.30. Viết chương trình kiểm tra một khối dữ liệu trong RAM ngoài có chiều dài 200 byte bắt
đầu từ địa chỉ 1000H xem có bao nhiêu byte có giá trị là 0. Kết quả (số byte có giá trị là 0) được
lưu vào ô nhớ có địa chỉ là 0FFFH trong RAM ngoài.
3.31. Viết chương trình kiểm tra một khối dữ liệu trong RAM ngoài có chiều dài 50 byte bắt
đầu từ địa chỉ 2000H xem có bao nhiêu byte có giá trị là 0, dương và âm. Kết quả được lưu vào
các ô nhớ trong RAM nội như sau:
- Ô nhớ 30H: chứa số byte bằng 0.
- Ô nhớ 31H: chứa số byte dương.
- Ô nhớ 32H: chứa số byte âm.
3.32. Viết 1 chương trình con tên DELAY_500 tạo trễ 500μs, biết fOSC = 12 MHz.
3.33. Viết 1 chương trình con tên DELAY_20ms tạo trễ 20ms, biết fOSC = 12 MHz.
3.34. Viết 1 chương trình con tên DELAY_1s tạo trễ 1s, biết fOSC = 12 MHz.
3.35. Viết chương trình xuất chuỗi xung vuông đối xứng có tần số f = 1KHz ra chân P1.0.
3.36. Viết chương trình xuất chuỗi xung vuông ra chân P1.0 với tần số f = 10KHz, duty cycle =
30% (thời gian mức cao = 30% thời gian của chu kì xung).
3.37. Viết chương trình điều khiển đèn giao thông tại ngã tư đường (đèn xanh sáng 4s, đèn
vàng sáng 1s, đèn đỏ sáng 5s). Dùng port 1 để điều khiển các đèn với quy định nếu xuất ra mức
logic 0 là đèn sáng:
Chân Đèn đường 1 Chân Đèn đường 2
21
Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51
P1.0 Xanh P1.3 Xanh
P1.1 Vàng P1.4 Vàng
P1.2 Đỏ P1.5 Đỏ
3.38. Cho mạch kết nối như sau:
a. Hãy viết chương trình để sáng từng LED theo chiều D1 → D8 và lặp lại, thời gian sáng
của mỗi LED là 0,2s.
b. Tương tự câu a nhưng theo chiều D8 → D1.
c. Kết hợp câu a và b: sáng theo chiều D1 → D8 rồi D8 → D1 và lặp lại.
d. Hãy viết chương trình để các LED sáng lan tỏa theo chiều D1 → D8 rồi tắt dần theo chiều
D1 → D8 và lặp lại, thời gian cách nhau giữa 2 LED là 0,2s.
e. Tương tự câu d nhưng theo chiều từ D8 → D1.
3.39. Cho mạch kết nối như sau:
Hãy viết chương trình để xuất giá trị BCD trong ô nhớ 30H ra LED 7 đoạn.
P1.0
P1.3
P1.4
P1.5
P1.6
P1.1
P1.2
P1.7
8051
D1
D3
D7
74HC373
1
11
2
5
6
9
12
15
16
19
3
4
7
8
13
14
17
18
OE
LE
Q1
Q2
Q3
Q4
Q5
Q6
Q7
Q8
D1
D2
D3
D4
D5
D6
D7
D8
D5
330 x 8
+5V
D6
D8
D2
+5V
D4
+5V
P1.0
P1.3
P1.4
P1.5
P1.6
P1.1
P1.2
P1.7
8051
f
74HC373
1
11
2
5
6
9
12
15
16
19
3
4
7
8
13
14
17
18
OE
LE
Q1
Q2
Q3
Q4
Q5
Q6
Q7
Q8
D1
D2
D3
D4
D5
D6
D7
D8
b
d
+5V
c
e
a
g
330x8
22
Các file đính kèm theo tài liệu này:
- Ch3.pdf