Professional Documents
Culture Documents
HỒ CHÍ MINH
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
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
ORG 2000H
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:
CLR LCD_RS
SETB LCD_E
MOVX @DPTR, A
CLR LCD_E
LCALL WAIT
RET
WAIT:
MOV R6,#10
DJNZ R7,$
DJNZ R6,DL1
RET
WRITETEXT:
SETB LCD_E
SETB LCD_RS
MOVX @DPTR, A
CLR LCD_E
CALL WAIT
RET
DISPLAY:
MOV R3, #15
MOV A, #0
LOP:
MOV R0, A
MOVC A, @A + DPTR
JZ EXIT
ACALL WRITETEXT
LU:
MOV A, R0
INC A
MOV A, #0C0H
LCALL WRITECOM
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
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
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
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
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
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
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:
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
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
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