Bài giảng Vi xử lý - Chương 3: Lập trình hợp ngữ họ MCS-51
Lập trình cấu trúc (structured programming) là một kỹ thuật tổ chức và mã hóa các chương trình
nhằm giảm sự phức tạp, dễ dàng gỡ rối và hiệu chỉnh chương trình. Lập trình cấu trúc nhấn
mạnh đến các nhiệm vụ lập trình. Người lập trình phân tích một nhiệm vụ lớn thành nhiều công
việc nhỏ hơn, sau đó dần dần chi tiết, cụ thể hóa để được các vấn đề đơn giản. Qua đó, tìm ra
cách giải quyết vấn đề dưới dạng những thuật giải cụ thể rõ ràng, để có thể minh họa bằng
ngôn ngữ giải thuật. Trong lập trình cấu trúc, các thuật giải này được gọi là các chương trình
con. Cách thức phân tích và thiết kế như vậy ta gọi là nguyên lý lập trình từ trên xuống (topdown), để thể hiện quá trình suy diễn từ cái chung nhất cho đến cái cụ thể nhất.
Tất cả các vấn đề lập trình đều có thể được giải quyết chỉ dựa trên 3 cấu trúc:
* Các phát biểu
* Các vòng lặp
* Các lựa chọn
1. Các phát biểu
- Các phát biểu là một cách thức cơ bản để thực hiện một công việc nào đó.
- Các phát biểu còn bao gồm cả việc gán giá trị cho 1 biến hoặc gọi chương trình con.
2. Cấu trúc vòng lặp
- Được sử dụng để thực hiện một hoặc một số công việc lặp đi lặp lại nhiều lần.
#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 Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51 18 f = 10 KHz → T = 0,1 ms = 100 μs Sóng vuông đối xứng → tH = tL = 50 μs = 50TM Chương trình: ORG 0000H LOOP: CPL P1.0 ; 1 μs MOV R7,#23 ; 1 μs DJNZ R7,$ ; 2 x 23 = 46 μs SJMP LOOP ; 2 μs END T tH tL Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51 19 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 MOV R7,#18H ADD A,R7 b. MOV A,#7FH MOV 50H,#29H 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: Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51 20 MOV R0,#20H MOV R1,#30H MOV R2,#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. Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51 21 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. 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). Bài giảng VI XỬ LÝ Chương 3: Lập trình hợp ngữ họ MCS-51 22 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 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
File đính kèm:
- bai_giang_vi_xu_ly_chuong_3_lap_trinh_hop_ngu_ho_mcs_51.pdf