You are on page 1of 42

TRƯỜNG ĐẠI HỌC BÁCH KHOA TP.

HỒ CHÍ MINH

MÔN HỌC: THÍ NGHIỆM VI


XỬ LÝ

BÁO CÁO THÍ NGHIỆM

GVHD: Nguyễn Khắc Phương Tuấn

LỚP: L05 Nhóm: 6


Phạm Trọng Sang 1712943
Phạm Trần Minh Quân 1712828
Trương Thanh Sang 1712945
BÀI 1: LẬP TRÌNH GIAO TIẾP LED ĐƠN VÀ
PHÍM ĐƠN

 THÍ NGHIỆM 1:Viết chương trình thực hiện việc đọc liên tục trạng thái
của nút nhấn được nối đến P1.0 và hiển thị ra led được nối tại chân P3.0 (bit
thứ 0 của led thanh BL202).
ORG 2000H
SETB P3.0 // Tắt led P3.0
JNB P1.0, LOOP // Kiểm tra nút P1.0
CLR P3.0 // Bật led P3.0
SJMP $
END
- LED nối vào P1.0 và P3.0 đều bị tác động. LED tại P1.0 bị tác động do phần
cứng, khi nhấn phím, mức điện áp trên P1.0 bằng 0, đầu còn lại của LED được
nối với điện trở và nối lên VCC nên đèn tại P1.0 sáng. Tương tự, tại P3.0, 1 đầu
LED được nối vào điện trở và nối đến VCC, đầu còn lại nối đến P3.0. Khi nhấn
nút, P1.0 có mức điện áp thấp, phần mềm sẽ đọc mức điện áp và đặt cho P3.0
mức điện áp thấp nên đèn sáng.
- Tất cả các chân trên P1 và P3 đều có thể sử dụng do tất cả các chân đều có thể
dùng làm chân IO.

 THÍ NGHIỆM 2: Biên dịch và thử nghiệm chương trình cho sẵn sau:
ORG 2000H
MAIN:
CPL P3.0 // Đảo bit P3.0 làm nháy led
JMP MAIN
END
- Theo lý thuyết, với thạch anh 11.0592MHz, chương trình trên sẽ tạo ra sóng
vuông trên P3.0 với chu kì 6.5us
- Tần số tối đa một xung tuần hoàn có chu kỳ nhiệm vụ 50% có thể đạt được là
153600Hz với đoạn code như trên
 THÍ NGHIỆM 3: Viết chương trình tạo xung vuông 1 KHz, chu kỳ nhiệm
vụ 50% trên P3.0
ORG 2000H
CONT:
CPL P3.0 // Đảo bit P3.0
ACALL DELAY5 // Gọi chương trình con
SJMP CONT
DELAY5: // Delay 500MC
MOV R7,#230
LOOP:
DJNZ R7,LOOP
RET
END
- Vòng trễ tạo ra với thời gian trễ 0.5ms. Mỗi vòng lặp DJNZ có thời gian thực
thi 2 chu kì máy, mỗi chu kì máy có thời gian bằng 12 chu kì thạch anh. Gọi n
là số lần lặp:
0.5(10^-3)=2n.Tmáy=2n.12Txtal=24n.(1/11059200) => n=230.4 => chọn
n=230
- Vẽ lại dạng sóng:
- Sai số nhỏ nhất có thể đạt được: (230.4-230)/230.4=0.17%

 THÍ NGHIỆM 4: Viết chương trình con Delay1sIns và dùng chương trình
con này để chớp/tắt LED đơn gắn vào P1.0 sau mỗi khoảng thời gian 1s.
- Tính thời gian delay 1s:
1
1=2n.Tmáy=2n.12Txtal=24n.( 11059200 ) => n=460800 => chọn n1=250;
n2=250; n3=7

ORG 2000H
LOOP:
CPL 1.0 // Đảo bit, chớp tắt led
ACALL DELAY1S // Gọi chương trình con
SJMP LOOP
DELAY1S: // Delay 1s
MOV R7,#8
LAP1:
MOV R6,#250
LAP2:
MOV R5,#250
LAP3:
DJNZ R5,LAP3
DJNZ R6,LAP2
DJNZ R7,LAP1
RET
END

 THÍ NGHIỆM 5: Viết chương trình tạo hiệu ứng quay LED: các LED đơn
trên BARLED1 sáng lần lượt từ trái sang phải sau thời gian 1s và lặp lại. Sử
dụng chương trình con 1s đã viết ở trên.
ORG 2000H
MOV DPTR,#SIGNAL // Gán địa chỉ của bảng đã tạo cho DPTR
LOOP:
MOV R7,#8
LAP:
MOV A,R7
MOVC P1,@A+DPTR // Gán giá trị trong bảng cho P1
ACALL DELAY1S // Gọi chương trình con delay 1s
DJNZ R7,LAP // Vòng lập để chạy led
MOV P1,#0FFH // Tắt BARLED sau khi quay đủ 8 led
SJMP LOOP // Lặp lại chương trình

DELAY1S: // Delay 1s
MOV R7,#8
LAP1:
MOV R6,#250
LAP2:
MOV R5,#250
LAP3:
DJNZ R5,LAP3
DJNZ R6,LAP2
DJNZ R7,LAP1
RET
TABLE: // Bảng chứa các giá trị của từng led khi sáng
DB 00H,01H,03H,07H,0FH,1FH,3FH,7FH
END

- LED ngoài cùng bên trái nối với MSB của P1


BÀI 2: HIỂN THỊ LED 7 ĐOẠN

 THÍ NGHIỆM 1: Viết chương trình con DisplayLed0 hiển thị lên LED 7
đoạn số 0 giá trị chứa trong thanh ghi R0

DISPLAYLED0:
MOV R0,#0
MOV A,R0 // Đặt giá trị hiển thị
ADD A,#0E0H // Chọn thứ tự của led hiển thị
MOV DPTR,#0000H // Định vị địa chỉ của led7 đoạn
MOVX @DPTR,A // Xuất giá trị ra led
RET

Viết chương trình chính hiển thị số 9 lên LED 7 đoạn số 0 bằng cách cho R0
bằng 9 và gọi chương trình con DisplayLed0.

ORG 2000H
MOV R0,#9 // Gán giá trị muốn hiển thị cho R0
ACALL DISPLAYLED0 // Gọi chương trình con hiển thị led
SJMP DONE

DISPLAYLED0:
MOV A,R0 // Đặt giá trị hiển thị ra led
ADD A,#0E0H // Chọn led 7 đoạn số 0
MOV DPTR,#0000H // Định vị địa chỉ của led7 đoạn
MOVX @DPTR,A // Xuất giá trị ra led
RET
DONE: NOP
END
 THÍ NGHIỆM 2: Viết chương trình hiển thị lên LED 7 đoạn số 0 các con
số từ 0 đến 9 sau các khoảng thời gian 1s
ORG 2000H
MOV R0,#0 // Gán giá trị đầu là 0
LOOP:
ACALL DISPLAYLED0 // Gọi chương trình con hiển thị led
INC R0
ACALL DELAY1S // Gọi chương trình con delay 1s
CJNE R0,#10,LOOP // Kiểm tra giá trị xuất ra để tạo vòng lặp
MOV R0,#0 // Gán lại giá trị đầu là 0
SJMP LOOP
DISPLAYLED0:
MOV A,R0 // Đặt giá trị hiển thị ra led
ADD A,#0E0H // Chọn led 7 đoạn số 0
MOV DPTR,#0000H // Định vị địa chỉ của led7 đoạn
MOVX @DPTR,A // Xuất giá trị ra led
RET
DELAY1S:
MOV R7,#-20
TIMELOOP:
MOV TMOD, #01H // Set mode 1 cho timer0
MOV TH0,#HIGH(-50000) // Đặt giá trị bit cao cho thanh ghi TH0
MOV TL0,#LOW(-50000) // Đặt giá trị bit thấp cho thanh ghi TL0
SETB TR0 // Cho timer0 chạy
JNB TF0,$ // Kiểm tra cờ tràn của timer0
CLR TF0 // Xóa cờ tràn
CLR TR0 // Dừng timer0
DJNZ R7,TIMELOOP
RET
END
 THÍ NGHIỆM 3: Viết chương trình con DisplayLED xuất giá trị chứa trong
thanh ghi R0 lên LED 7 đoạn có số thứ tự chứa trong thanh ghi R1. R0 nằm
trong tầm từ 0-9 và R1 trong tầm từ 0-3.
Sau đó dùng chương trình con này viết chương trình chính xuất giá trị 1 lên
LED 7 đoạn số 3.
ORG 2000H
MOV R0,#1 // Gán giá trị hiển thị cho R0
MOV R1,#3 // Gán giá trị thứ tự led cho R1
ACALL DISPLAYLED // Gọi chương trình con hiển thị led
ACALL DELAY1S // Gọi chương trình con delay 1s
SJMP FINISH

DISPLAYLED:
MOV A,R1 // Gán số thứ tự của led cho A
CJNE A,#0,ANONUM1 // Kiểm tra thứ tự led
MOV A,#0E0H // Chọn led 7 đoạn số 0
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE

ANONUM1:
CJNE A,#1,ANONUM2 // Kiểm tra thứ tự led
MOV A,#0D0H // Chọn led 7 đoạn số 1
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE

ANONUM2:
CJNE A,#2,ANONUM3 // Kiểm tra thứ tự led
MOV A,#0B0H // Chọn led 7 đoạn số 2
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE
ANONUM3:
MOV A,#70H // Chọn led 7 đoạn số 3
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
DONE:
MOV DPTR,#0000H // Định vị địa chỉ của led7 đoạn
MOVX @DPTR,A // Xuất giá trị ra led
RET

DELAY1S:
MOV R7,#-20
TIMELOOP:
MOV TMOD, #01H // Set mode 1 cho timer0
MOV TH0,#HIGH(-50000) // Đặt giá trị bit cao cho thanh ghi TH0
MOV TL0,#LOW(-50000) // Đặt giá trị bit thấp cho thanh ghi TL0
SETB TR0 // Cho timer0 chạy
JNB TF0,$ // Kiểm tra cờ tràn của timer0
CLR TF0 // Xóa cờ tràn
CLR TR0 // Dừng timer0
DJNZ R7,TIMELOOP
RET

FINISH:
END

 THÍ NGHIỆM 4: Viết chương trình hiển thị số 1 lên LED7 đoạn 0, sau đó
1s hiển thị số 2 lên LED 7 đoạn 1, sau đó 1s hiển thị số 3 lên LED 7 đoạn 2,
sau đó 1s hiển thị số 4 lên LED 7 đoạn 3. Quá trình này lặp đi lặp lại. Việc
hiển thị này sử dụng chương trình con DisplayLED đã viết ở trên.
Giảm thời gian trễ xuống còn 100 ms. Quan sát hiện tượng.
Tính toán thời gian trễ sao cho không còn thấy LED nhấp nháy và áp dụng
vào chương trình
Giảm thời gian trễ xuống bằng 0 (không sử dụng hàm delay). Quan sát hiện
tượng.
ORG 2000H
LOOP:
MOV R7,#4 // Chu kì của vòng lặp
MOV R0,#1 // Gán giá trị hiển thị cho R0
MOV R1,#3 // Gán giá trị thứ tự led cho R1

LOOP1:
ACALL DISPLAYLED // Gọi chương trình con hiển thị led
ACALL DELAY1S // Gọi chương trình con delay 1s
INC R0 // Tăng giá trị hiển thị
INC R1 // Tăng giá trị thứ tự
DJNZ R7, LOOP1
SJMP LOOP
DISPLAYLED:
MOV A,R1 // Gán số thứ tự của led cho A
CJNE A,#0,ANONUM1 // Kiểm tra thứ tự led
MOV A,#0E0H // Chọn led 7 đoạn số 0
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE

ANONUM1:
CJNE A,#1,ANONUM2 // Kiểm tra thứ tự led
MOV A,#0D0H // Chọn led 7 đoạn số 1
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE

ANONUM2:
CJNE A,#2,ANONUM3 // Kiểm tra thứ tự led
MOV A,#0B0H // Chọn led 7 đoạn số 2
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
SJMP DONE
ANONUM3:
MOV A,#70H // Chọn led 7 đoạn số 3
ADD A,R0 // Gán giá trị và số thứ tự của led cho A
DONE:
MOV DPTR,#0000H // Định vị địa chỉ của led7 đoạn
MOVX @DPTR,A // Xuất giá trị ra led
RET
DELAY1S:
MOV R7,#-20
TIMELOOP:
MOV TMOD, #01H // Set mode 1 cho timer0
MOV TH0,#HIGH(-50000) // Đặt giá trị bit cao cho thanh ghi TH0
MOV TL0,#LOW(-50000) // Đặt giá trị bit thấp cho thanh ghi TL0
SETB TR0 // Cho timer0 chạy
JNB TF0,$ // Kiểm tra cờ tràn của timer0
CLR TF0 // Xóa cờ tràn
CLR TR0 // Dừng timer0
DJNZ R7,TIMELOOP
RET
END

- Khi giảm thời gian delay còn 100ms, các LED 7 đoạn chớp tắt nhanh hơn
- Khi loại bỏ hàm delay, các LED 7 đoạn dường như hiển thị các số cùng lúc
- Mắt người có hiện tượng lưu ảnh, những hình ảnh chuyển động với tốc độ trên
24 khung hình 1 giây sẽ khiến mắt ta không thể phân biệt được sự nhấp nháy
của ảnh. Vậy LED cần có thời gian sáng mỗi chu kì quét là: 1/(4.25)=10ms
BÀI 3: GIAO TIẾP LCD và ADC
 THÍ NGHIỆM 1: Download chương trình mẫu LCD.A51 trên trang web bộ
môn điện tử.
Biên dịch và chạy thử chương trình
Sửa chương trình để hiển thị tên sinh viên lên hàng đầu
- Tại cuối chương trình, sau nhãn MESSAGE, sửa các kí tự trong dấu “” thành
tên sinh viên

LCD_E BIT P3.4

LCD_RS BIT P3.5

LCD_ADDR EQU 6000H

ORG 2000H

MOV TMOD, #01H

MOV DPTR, #LCD_ADDR

LCALL LCD_INT

LCALL DISPLAY

SJMP $

LCD_INT:

MOV A, #38H

LCALL WRITECOM

MOV A, #0EH

LCALL WRITECOM

MOV A, #06H

LCALL WRITECOM

RET
WRITECOM:

MOV DPTR, #LCD_ADDR

CLR LCD_RS

SETB LCD_E

MOVX @DPTR, A

CLR LCD_E

LCALL WAIT

RET

WAIT:

MOV R6,#10

DL1: MOV R7,#250

DJNZ R7,$

DJNZ R6,DL1

RET

WRITETEXT:

MOV DPTR, #LCD_ADDR

SETB LCD_E

SETB LCD_RS

MOVX @DPTR, A

CLR LCD_E

CALL WAIT

RET

DISPLAY:
MOV R3, #15

MOV A, #0

LOP:

MOV DPTR, #TEXT

MOV R0, A

MOVC A, @A + DPTR

JZ EXIT

ACALL WRITETEXT

LU:

MOV A, R0

INC A

DJNZ R3, LOP

MOV A, #0C0H

LCALL WRITECOM

MOV R3, #15

SJMP LU

EXIT:

RET

TEXT:

DB "TRONG SANG",0

END
 THÍ NGHIỆM 2:
- Viết chương trình con CLEARSCREEN để xóa màn hình LCD
CLRSCREEN:
PUSH ACC

MOV A, #01H

CALL WRITECOM

POP ACC

RET

- Viết thêm chương trình con GOTOXY để di chuyển con trỏ của LCD
đến hàng x, cột y, với X chứa trong R0 và Y chứa trong R1
GOTOXY:
MOV A,R0 // Gán giá trị thứ tự hàng cho A
CJNE A,#0,ROW1 // Kiểm tra thứ tự hàng (hàng 0)
ADD A,R1 // Thêm thứ tự cột vào cho A
ADD A,#80H // Thêm vào địa chỉ hiển thị lên hàng 0
LCD
SJMP GOTOXYDONE
ROW1: // Hàng 1
ADD A,R1 // Thêm thứ tự cột vào cho A
ADD A,#0C0H // Thêm vào địa chỉ hiển thị lên hàng 1 LCD
GOTOXYDONE:
RET
- Sửa chương trình ở thí nghiệm 1 để hiển thị thêm số nhóm ở hàng thứ 2

LCD_E BIT P3.4 // Định nghĩa cho nhãn


LCD_RS BIT P3.5 // Định nghĩa cho nhãn
LCDADDR EQU 6000H // Định nghĩa cho nhãn
ORG 0000H

MAIN:
MOV DPTR, #LCDADDR // Gán địa chỉ của LCD cho PDTR
ACALL CLEAR // Gọi chương trình con clear LCD
ACALL INIT_LCD // Gọi chương trình con đặt các trạng thái đầu
cho LCD
ACALL DISPLAYSTRING // Gọi chương trình con xuất kí tự trong bảng
MESSAGE lên LCD
MOV R0,#1 // Đặt thứ tự hàng
MOV R1,#0 // Đặt thứ tự cột
ACALL GOTOXY // Gọi chương trình con định vị hàng và cột
LCD
ACALL DISPLAYSTRING1 // Gọi chương trình con xuất kí tự trong bảng
MESSAGE1 lên LCD
SJMP $
INIT_LCD:
MOV A, #38H // Lệnh chọn font ký tự là 5×8
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
MOV A, #0EH // Lệnh bật LCD và tắt con trỏ ký tự
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
MOV A, #06H // Lệnh cho con trỏ tự động dịch phải
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
RET

CLEAR:
MOV A, #01H // Lệnh clear màn hình LCD
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
RET

GOTOXY:
MOV A,R0 // Gán giá trị thứ tự hàng cho A
CJNE A,#0,ROW1 // Kiểm tra thứ tự hàng (hàng 0)
ADD A,R1 // Thêm thứ tự cột vào cho A
ADD A,#80H // Thêm vào địa chỉ hiển thị lên hàng 0
LCD
SJMP GOTOXYDONE
ROW1: // Hàng 1
ADD A,R1 // Thêm thứ tự cột vào cho A
ADD A,#0C0H // Thêm vào địa chỉ hiển thị lên hàng 1 LCD
GOTOXYDONE:
RET

WRITECOM:
MOV DPTR, #LCDADDR // Gán địa chỉ của LCD cho PDTR
SETB LCD_E // Set cờ cho phép
CLR LCD_RS // Dữ liệu được hiểu là lệnh
MOVX @DPTR, A // Nhập lệnh cho LCD
CLR LCD_E // Clear cờ cho phép
ACALL WAIT_LCD // Gọi chương trình delay
RET

WRITETEXT:
MOV DPTR, #LCDADDR // Gán địa chỉ của LCD cho PDTR
SETB LCD_E // Set cờ cho phép
SETB LCD_RS // Dữ liệu được hiểu là dữ liệu
MOVX @DPTR, A // Nhập dữ liệu xuất ra cho LCD
CLR LCD_E // Clear cờ cho phép
ACALL WAIT_LCD // Gọi chương trình delay
RET

DISPLAYSTRING:
MOV A,#0 // Gán thứ tự của kí tự trong bảng
LOOP:
MOV DPTR, #MESSAGE // Gán địa chỉ của bảng
MOV R0,A
MOVC A,@A+DPTR // Gán giá trị của kí tự trong bảng cho A
JZ EXIT // Kiểm tra kí tự null của chuỗi trong bảng
ACALL WRITETEXT // Gọi chương trình con xuất dữ liệu ra
LCD
MOV A,R0
INC A // Tăng thứ tự của kí tự trong bảng
DJNZ B,LOOP
EXIT:
RET

DISPLAYSTRING1:
MOV A,#0 // Gán thứ tự của kí tự trong bảng
LOOP1:
MOV DPTR, #MESSAGE1 // Gán địa chỉ của bảng
MOV R0,A
MOVC A,@A+DPTR // Gán giá trị của kí tự trong bảng cho A
JZ EXIT // Kiểm tra kí tự null của chuỗi trong bảng
ACALL WRITETEXT // Gọi chương trình con xuất dữ liệu ra
LCD
MOV A,R0
INC A // Tăng thứ tự của kí tự trong bảng
DJNZ B,LOOP
EXIT:
RET
WAIT_LCD:
MOV R6,#10
DL1:
MOV R7, #250
DJNZ R7, $
DJNZ R6,DL1
RET

MESSAGE:
DB "TRONG SANG",0
MESSAGE1:
DB "NHOM 6",0

 THÍ NGHIỆM 3 và 4: Viết chương trình con CALADC tính toán giá trị
điện áp thực tế đặt vào kênh 0 ADC từ giá trị đo được của ADC. Chương
trình có giá trị vào chứa trong R0 (là kết quả của chương trình con
READADC). Giá trị trả về chứa trong R0 và R1, R0 chứa giá trị nguyên và
R1 chứa giá trị thập phân.
RS BIT P3.5
EN BIT P3.3
ORG 2000H

MAIN:
ACALL KD_LCD
ACALL HIENTHI // Gọi chương trình con hiển thị
LAP:
MOV DPTR,#4000H // Gán địa chỉ ADC cho DPTR
MOVX @DPTR,A
ACALL DELAY120US // Gọi chương trình con delay
MOVX A,@DPTR
MOV R5,A
ACALL XUATDIENAP
SJMP LAP
DELAY120US:
MOV R1,#60
DJNZ R1,$
RET

NHAPLENH: // CHƯƠNG TRÌNH NHẬP LỆNH


CHO LCD
CLR RS
MOV DPTR,#6000H
MOVX @DPTR,A
SETB EN
CLR EN
ACALL DELAY5MS
RET

DELAY5MS:
MOV TMOD,#01H
MOV TL0,#LOW(-5000)
MOV TH0,#HIGH(-5000)
SETB TR0
JNB TF0,$
CLR TR0
CLR TF0
RET

KD_LCD:
MOV A,#30H
ACALL NHAPLENH
MOV A,#30H
ACALL NHAPLENH
MOV A,#30H
ACALL NHAPLENH
MOV A,#0CH
ACALL NHAPLENH
MOV A,#01H
ACALL NHAPLENH
MOV A,#38H
ACALL NHAPLENH
MOV A,#06H
ACALL NHAPLENH
RET

XUAT1KT: // CHƯƠNG TRÌNH XUẤT KÍ TỰ


SETB RS
MOV DPTR,#6000H
MOVX @DPTR,A
SETB EN
CLR EN
ACALL DELAY5MS
RET
XUATDIENAP:
MOV A,#88H
ACALL NHAPLENH // Gọi chương trình con nhập lệnh
MOV A,R5
MOV B,#51
DIV AB
ADD A,#48
ACALL XUAT1KT // Gọi chương trình con xuất kí tự
MOV A,#10
MUL AB
MOV R4,B
MOV B,#51
CJNE R4,#1,TIEP1
DIV AB
ADD A,#5
MOV R4,A
SJMP TIEP2
TIEP1:
DIV AB
MOV R4,A
TIEP2:
MOV A,#8AH
ACALL NHAPLENH
MOV A,R4
ADD A,#48
ACALL XUAT1KT
RET

HIENTHI: // CHƯƠNG TRÌNH XUẤT CHUỖI KÍ TỰ TRONG BẢNG


MOV A,#80H
ACALL NHAPLENH
MOV R3,#0
LOOP:
MOV A,R3
MOV DPTR,#TABLE
MOVC A,@A+DPTR
JZ LAP1
ACALL XUAT1KT
INC R3
DJNZ B,LOOP
RET
TABLE: DB "VOLT: , V",0
LAP1: NOP
RET
END
BÀI 4: LẬP TRÌNH GIAO TIẾP TIMER VÀ
SERIAL PORT

Phần TIMER

 THÍ NGHIỆM 1: Viết chương trình tạo sóng vuông 1 KHz trên chân P1.0
sử dụng timer 0 ở chế độ 1
- Có dùng timer mod 2 kết hợp vòng lặp
ORG 2000H
LOOP:
CPL P1.0 // Đảo bit P1.0
ACALL DELAY5 // Gọi chương trình con delay 500MC
SJMP LOOP

DELAY5: // Delay sử dụng timer


MOV TMOD,#01H // Set mod 1 cho timer 0
MOV TH0,#HIGH(-461) // Gán bit cao cho thanh ghi TH0
MOV TL0,#LOW(-461) // Gán bit thấp cho thanh ghi TL0
SETB TR0 // Cho timer0 chạy
JNB TF0,$ // Kiểm tra cờ tràn của timer 0
CLR TF0 // Xóa cờ tràn của timer 0
CLR TR0 // Dừng timer0
RET
END

Dạng sóng có thể bị sai số, để hạn chế sai số, ta nên tính toán giá trị nạp vào
TH0 và TL0 bằng tần số xtal của mạch

 THÍ NGHIỆM 2: Viết chương trình tạo sóng vuông 10 KHz trên chân P1.0
sử dụng timer 0 ở chế độ 2
ORG 2000H
MOV TMOD,#02H // Set mode 2 cho timer0
MOV TH0,#-50 // Đặt giá trị cho thanh ghi TH0
SETB TR0 // Cho timer0 chạy
LOOP:
JNB TF0,$ // Kiểm tra cờ tràn của timer0
CLR TF0 // Xóa cờ tràn timer0
CPL P1.0 // Đảo bit để tạo sóng vuông
SJMP LOOP
END

- Ở chế độ 2, độ trễ gây ra do các câu lệnh đảo giá trị bit gây sai số cho dạng
sóng ngõ ra. Tuy nhiên sai số là không lớn

Phần SERIAL PORT

 THÍ NGHIỆM 3: Viết chương trình phát chuỗi ký tự “Hello, world” lên
máy tính thông qua HyperTerminal với tốc độ baud 19200 pbs mỗi khi SW
310 (gắn vào P1.0) được nhấn
ORG 2000H
MOV SCON,#52H // Set mode 2 cho serial port
MOV TMOD,#20H // Set mode 2 cho timer 1
MOV TH1,#-3 // Đặt giá trị cho timer
SETB TR1 // Cho timer chạy
MOV R7,#11 // Chiều dài chuỗi kí tự trong bảng
MOV R0,#0 // Thứ tự của kí tự xuất ra
MOV DPTR,#MESSAGE // Gán địa chỉ của bảng cho DPTR
JB P1.0,$ // Kiểm tra nút nhấn
JNB P1.0,$ // Kiểm tra nút nhấn
LOOP:
MOV A,R0
MOVC A,@A+DPTR // Gán giá trị của kí tự trong bảng cho A
ACALL SEND // Gọi chương trình con để send kí tự
ACALL DELAY // Gọi chương trình con delay
INC R0 // Tăng biến thứ tự
DJNZ R7,LOOP // Kiểm tra chuỗi
SJMP DONE

SEND:
JNB TI,$ // Kiểm tra cờ TI
CLR TI // Xóa cờ TI
MOV SBUF, A // Chuyển dữ liệu từ A cho SBUF
RET

DELAY:
MOV R6,#40
DL2:
MOV R5, #250
DJNZ R5, $
DJNZ R6,DL2
RET

MESSAGE:
DB "HELLO WORLD",0
DONE:
END
 THÍ NGHIỆM 2: Viết chương trình nhận các ký tự từ máy tính gửi đến
EME-MC8 thông qua HyperTerminal (bằng cách gõ các ký tự trên bàn phím
khi đang ở trong chương trình HyperTerminal) và hiển thị lên LCD như sau:
Nếu ký tự là chữ thì hiển thị lên LCD; Enter thì xuống hàng; ESC thì xóa
màn hình LCD; Backspace thì xóa ký tự bên trái dấu nháy.
ORG 2000H
EN BIT P3.3
RS BIT P3.5
ORG 2000H
MOV SCON,#52H // Set mode 2 cho serial port
MOV TMOD,#20H // Set mode 2 cho timer 1
MOV TH1,#-3 // Đặt giá trị cho timer
SETB TR1 // Cho timer 1 chạy
MOV A,#01H
ACALL WRITE_COMMAND // Gọi chương trình nhập lệnh cho LCD
MOV DPTR, #6000H // Gán địa chỉ của LCD cho DPTR
ACALL INIT_LCD // Gọi chương trình con đặt các trạng thái đầu
cho LCD
MAIN:
ACALL IN_CHAR // Gọi chương trình kiểm tra cờ RI và gán giá trị
nhận được của SBUF cho A
ACALL WRITE_TEXT // Gọi chương trình con xuất kí tự ra LCD
SJMP MAIN
IN_CHAR:
JNB RI, IN_CHAR // Kiểm tra cờ RI
CLR RI // Xóa cờ RI
MOV A, SBUF
RET

INIT_LCD:
MOV A, #38H // Lệnh chọn font ký tự là 5×8
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
MOV A, #0EH // Lệnh bật LCD và tắt con trỏ ký tự
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
MOV A, #06H // Lệnh cho con trỏ tự động dịch phải
ACALL WRITECOM // Gọi chương trình con nhập lệnh lên
LCD
RET
WAIT_LCD:
MOV R7,#100
WAITLCDLOOP:
MOV R6,#250
DJNZ R6,$
DJNZ R7,WAITLCDLOOP
RET
WRITE_TEXT:
MOV DPTR,#6000H // Gán địa chỉ của LCD cho DPTR
ACALL WAIT_LCD // Gọi chương trình con delay
SETB EN // Set cờ cho phép
SETB RS // Dữ liệu được hiểu là dữ liệu
MOVX @DPTR,A // Xuất ra LCD
CLR EN // Clear cờ cho phép
RET
WRITE_COMMAND:
MOV DPTR,#6000H // Gán địa chỉ của LCD cho DPTR
ACALL WAIT_LCD // Gọi chương trình con delay
SETB EN // Set cờ cho phép
CLR RS // Dữ liệu được hiểu là lệnh
MOVX @DPTR,A // Nhập lệnh cho LCD
CLR EN // Clear cờ cho phép
RET
END
BÀI 5: LẬP TRÌNH NGẮT
 THÍ NGHIỆM 1: 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 317 (gắn vào P1.0) được nhấn, và tắt LED
khi phím được nhả.
ORG 2000H
LJMP MAIN
ORG 2023H
LJMP SERIALINT
ORG 2030H
MAIN:
MOV SCON,#52H // Set mode 2 cho serial port
MOV TMOD,#20H // Set mode 2 cho timer 1
MOV TH1,#-3 // Đặt giá trị cho timer
SETB TR1 // Cho timer1 chạy
SETB EA // Cho phép ngắt cục bộ
SETB ES // Cho phép ngắt ngoài
LOOP: // Kiểm tra nút nhấn SW317 và bật LED
MOV P1,#0FFH
MOV A,P1
CJNE A,#0FEH,LOOP
MOV A,#0FDH
SJMP LOOP
SERIALINT: // Chương trình thực hiện khi ngắt
JNB RI,SKIP // Kiểm tra cờ RI
CLR RI // Xóa cờ RI
MOV SBUF,A
SKIP:
CLR TI
RETI
END
THÍ NGHIỆM 2: 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.
ORG 2000H
LJMP MAIN
ORG 200BH
LJMP TIMER0INT

ORG 2030H
MAIN:
MOV R1,#0
SETB EA // Cho phép ngắt toàn cục
SETB ET0 // Cho phép ngắt timer0
MOV TMOD,#01H // Set mode 1 cho timer0
MOV TH0,#HIGH(-10000) // Gán bit cao cho TH0
MOV TL0,#LOW(-10000) // Gán bit thấp cho TL0
SETB TR0 // Cho timer0 chạy
SJMP $ // Chờ ngắt

TIMER0INT: // Chương trình thực hiện khi ngắt


CJNE R1,#4,CONT // Kiểm tra R1
MOV R1,#0
CONT:
MOV A,R1
ADD A,#20H
MOV R0,A
MOV A,@R0
MOV R0,A
ACALL DISPLAYLED // Gọi chương trình con xuất ra LED 7
đoạn
RETI
DISPLAYLED:
MOV A,R1
CJNE A,#0,LED1 // Kiểm tra thứ tự LED
MOV A,#0E0H // Chọn Led 0
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED1:
CJNE A,#1,LED2 // Kiểm tra thứ tự LED
MOV A,#0D0H // Chọn Led 1
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED2:
CJNE A,#2,LED3 // Kiểm tra thứ tự LED
MOV A,#0B0H // Chọn Led 2
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED3:
MOV A,#70H // Chọn Led 2
ADD A,R0 // Xuất giá trị ra led
DONE:
MOV DPTR,#0000H
MOVX @DPTR,A
RET
END

 THÍ NGHIỆM 3: 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
ORG 2000H
LJMP MAIN
ORG 200BH
LJMP TIMER0INT

ORG 2030H
MAIN:

// LUU GIA TRI CHO 20H -> 23H VE 0


MOV R0,#20H
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
MOV R1,#0

// SE TCHẾ ĐỘ CHO INTERRUPT


SETB EA
SETB ET0
MOV TMOD,#01H
MOV TH0,#HIGH(-10000)
MOV TL0,#LOW(-10000)
SETB TR0

COUNT:
ACALL BUTTONCOUNT // Gọi chương trình con đếm số lần
nhấn
SJMP COUNT
BUTTONCOUNT:
MOV P1,#0FFH
MOV A,P1
CJNE A,#0FEH,COUNTDONE // Kiểm tra nút nhấn
ACALL DELAYBUTTON // Gọi chương trình con delay
MOV R0,#23H
MOV A,@R0 // Gán giá trị trong thanh ghi 23H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 22H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 21H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 20H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
SJMP COUNTDONE

SKIP:
INC A
MOV @R0,A
COUNTDONE:
RET

DELAYBUTTON: // Chống rung phím


MOV R6,#40
DL2:
MOV R7, #250
DJNZ R7, $
DJNZ R6,DL2
RET

TIMER0INT:
CJNE R1,#4,CONT // Kiểm tra R1
MOV R1,#0
CONT:
MOV A,R1
ADD A,#20H
MOV R0,A
MOV A,@R0
MOV R0,A
ACALL DISPLAYLED // Gọi chương trình con xuất ra LED 7
đoạn
MOV TH0,#HIGH(-10000)
MOV TL0,#LOW(-10000)
SETB TR0
RETI

DISPLAYLED:
MOV A,R1
CJNE A,#0,LED1 // Kiểm tra thứ tự LED
MOV A,#0E0H // Chọn Led 0
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED1:
CJNE A,#1,LED2 // Kiểm tra thứ tự LED
MOV A,#0D0H // Chọn Led 1
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED2:
CJNE A,#2,LED3 // Kiểm tra thứ tự LED
MOV A,#0B0H // Chọn Led 2
ADD A,R0 // Xuất giá trị ra led
SJMP DONE

LED3:
MOV A,#70H // Chọn Led 2
ADD A,R0 // Xuất giá trị ra led
DONE:
MOV DPTR,#0000H
MOVX @DPTR,A
RET
END

 THÍ NGHIỆM 4: 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
ORG 2000H
LJMP MAIN
ORG 200BH
LJMP TIMER0INT
ORG 2030H

MAIN:
CLR C
// SET CÁC GIÁ TRỊ TRONG CÁC THANH GHI 20H, 21H, 22H, 23H VỀ 0
MOV R0,#20H
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0

MOV R1,#0
SETB ET0 // Cho phép ngắt timer0
SETB EA // Cho phép ngắt toàn cục
MOV TMOD,#01H // Set mode 1 cho timer0
MOV TH0,#HIGH(-10000)
MOV TL0,#LOW(-10000)
SETB TR0 // Cho timer 0 chạy
CONTCOUNT:
MOV P1,#0FFH
MOV A,P1
CJNE A,#0FEH,ANOBUTTON1 // Kiểm tra nút nhấn
SW310
MOV R0,#20H
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
INC R0
MOV @R0,#0
CLR C
SJMP CONTCOUNT

ANOBUTTON1:
CJNE A,#0FDH,ANOBUTTON2 // Kiểm tra nút nhấn
SW311
SETB C
SJMP CONTCOUNT

ANOBUTTON2:
CJNE A,#0FBH,CONTCOUNT // Kiểm tra nút nhấn SW312
CLR C
SJMP CONTCOUNT

TIMER0INT: // Chương trình chạy khi ngắt


timer0
ACALL TIMEVALUE // Gọi chương trình con set giá trị hiển thị
CLR TR0 // Xóa cờ tràn TR0
CJNE R1,#4,CONT
MOV R1,#0
CONT:
MOV A,R1
ADD A,#20H
MOV R0,A
MOV A,@R0
MOV R0,A
ACALL DISPLAYLED // Gọi chương trình con hiển thị led
MOV TH0,#HIGH(-10000)
MOV TL0,#LOW(-10000)
SETB TR0
RETI

DISPLAYLED: // CHƯƠNG TRÌNH HIỂN THỊ RA LED 7


ĐOẠN
MOV A,R1
CJNE A,#0,ANONUM1
MOV A,#0E0H
ADD A,R0
SJMP DONE
ANONUM1:
CJNE A,#1,ANONUM2
MOV A,#0D0H
ADD A,R0
SJMP DONE
ANONUM2:
CJNE A,#2,ANONUM3
MOV A,#0B0H
ADD A,R0
SJMP DONE
ANONUM3:
MOV A,#70H
ADD A,R0
DONE:
MOV DPTR,#0000H
MOVX @DPTR,A
RET

TIMEVALUE:
JNC COUNTDONE // Kiểm tra bit trong cờ C
MOV R0,#23H
MOV A,@R0 // Gán giá trị trong thanh ghi 23H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 22H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 21H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
DEC R0
MOV A,@R0 // Gán giá trị trong thanh ghi 20H
cho A
CJNE A,#9,SKIP // Kiểm tra giá trị
MOV A,#0
MOV @R0,A
SJMP COUNTDONE

SKIP:
INC A
MOV @R0,A
COUNTDONE:
RET

You might also like