You are on page 1of 39

CHƯƠNG 6

GIAO TIẾP NGOẠI VI

* Chương 6: Giao tiếp ngoại vi -1- Nguyễn Trọng Luật *


6.1 GIỚI THIỆU CHUNG
Các thông số cơ bản của AVR MCU324P
- Nguồn cấp điện Vcc: Vcc=1.8 - 5.5V Chọn Vcc=5V
- Tần số dao động Fosc: Fosc=0 - 20Mhz Chọn Fosc=8Mhz
- Chu kỳ máy MC: 1MC=Tosc 1MC=125ns
- Điện áp ngõ vào mức 0 max VILmax : VILmax=0.1Vcc VILmax=0.5V
- Điện áp ngõ vào mức 1 min VIHmin: VIHmin=0.7Vcc VIHmin=3.5V
- Điện áp ngõ ra mức 0 max VOLmax : VOLmax=0.9V IOL=20mA
- Điện áp ngõ ra mức 1 min VOHmin : VOHmin=4.2V IOH=-20mA
- Dòng ngõ vào(rĩ)mức 0 IIL: IIL=-1μA(VIL)
- Dòng ngõ vào(rĩ)mức 1 IIH: IIH=1μA(VIH)
- Dòng ngõ ra max: IOH/Lmax IOH/Lmax=-/+40mA
- Tổng các dòng IOL/IOH max portB,D: 100mA
- Tổng các dòng IOL/IOH max portA,C: 100mA
* Chương 6: Giao tiếp ngoại vi -2- Nguyễn Trọng Luật *
6.2 GIAO TIẾP NÚT NHẤN (SW) – BÀN PHÍM (Keypad)

Vd: viết chương trình mỗi lần nhấn SW


đèn LED D sẽ lần lượt sáng /tối
.ORG
CBI DDRB, 0 ; PB0 là ngõ vào
SBI PORTB, 0 ; điện trở kéo lên ngõ PB0
WAIT SBI DDRC, 0 ; PC0 là ngõ ra
CBI PORTC, 0 ; PC0=0 Led tối
Y WAIT: SBIC PINB,0 ; SW nhấn PB0=0
PB0 = 0
RJMP WAIT ; SW không nhấn PB0=1
N ; lập vòng lại
Nhảy Thực thi công việc LDI R17, $01 ; đảo bit PC0
có phím ấn IN R18, PORTC
EOR R18, R17
WAIT: SBIC PINB, 0 OUT PORTC, R18
RJMP WAIT RJMP WAIT
… (có phím ấn)
* Chương 6: Giao tiếp ngoại vi -3- Nguyễn Trọng Luật *
❖ Chống rung phím bằng phần mềm: dùng delay vài chục ms giữa 2 lần xét phím có ấn
như lưu đồ:
.ORG
WAIT
CBI DDRB, 0
Y SBI PORTB, 0
Phím ko nhấn
SBI DDRC, 0
N CBI PORTC, 0
WAIT: SBIC PINB,0 ; xét phím PB0 ấn?
Delay 10ms
RJMP WAIT
RCALL DL10ms ; delay 10ms
Y SBIC PINB,0 ; xét phím PB0 ấn?
Phím ko nhấn
RJMP WAIT
N LDI R17, $01
IN R18, PORTC
Thực thi công việc
EOR R18, R17
có phím ấn OUT PORTC, R18
RJMP WAIT
Vd 6.3: viết chương trình mỗi lần nhấn DL10ms: …
SW đèn LED D sẽ lần lượt sáng/tối. …
RET
Chương trình có chống rung phím
* Chương 6: Giao tiếp ngoại vi -4- Nguyễn Trọng Luật *
❖ Một phương pháp chống rung SW khác là lập vòng n lần đọc trạng thái SW xác định
SW nhấn liên tục và lập vòng n lần đọc trạng thái SW xác định SW nhả liên tục sẽ xác
nhận SW có nhấn/nhả. Nếu chỉ 1 lần đọc không đúng trạng thái SW nhấn/nhả sẽ lập
vòng đọc lại từ đấu.
WAIT_0 WAIT_1
Bđ = n Bđ = n
BACK1 BACK2
Y Y
chưa nhấn chưa nhả
N N

Giảm Bđ Giảm Bđ

Rung phím (Key bounce) Y Y


Bđ ≠ 0 Bđ ≠ 0
N N

Thực thi công việc


có phím ấn
* Chương 6: Giao tiếp ngoại vi -5- Nguyễn Trọng Luật *
Vd 6.4: Viết chương trình đọc trạng Chương trình con GET_KEY xác định có phím nhấn
thái các SW và hiển thị dãy LED ;------------------------------------------
(bar LED) nếu có 1 SW nhấn/nhả ;GET_KEY đọc trạng thái các SW,
như sau(có chống rung SW): ;Trả về R17= mã SW và C=1 nếu có SW nhấn
- SW0 : tối dãy LED ;Trả về C=0 nếu SW chưa nhấn
- SW1 : sáng 4 LED trọng số thấp ;------------------------------------------
- SW2 : sáng 4 LED trọng số cao GET_KEY: LDI R17, 4 ;R17 vị trí SW
- SW3 : sáng toàn bộ dãy LED MOV R20, R17 ;cất số SW vào R20
IN R19, PINB ;đọc SW
ANDI R19, 0X0F ;che 4 bit thấp
CPI R19, 0X0F ;xem có SW nhấn?
BRNE CHK_KEY ;R19 khác 0FH, có SW nhấn
NO_KEY: CLC ;SW chưa nhấn,C=0
RJMP EXIT ;thoát
CHK_KEY: ROR R19 ;quay phải vào C tìm vị trí SW nhấn
BRCC KEY_CODE ;C=0 có SW nhấn
DEC R20 ;SW không nhấn giảm vị trí SW
BRNE CHK_KEY ;lập vòng xét đến hết số vị trí SW
RJMP NO_KEY ;thoát khi không có SW nhấn
KEY_CODE: SUB R17, R20 ;R17=mã SW
SEC ;C=1 có SW nhấn
EXIT: RET

* Chương 6: Giao tiếp ngoại vi -6- Nguyễn Trọng Luật *


Chương trình VD 6.4 CPI R17, 0 ; mã SW =0?
.EQU OUTPORT=PORTC BREQ MD_0 ;hiển thị mode 0
.ORG 0 CPI R17, 1 ; mã SW =1?
LDI R16, 0xF0 BREQ MD_1 ;hiển thị mode 1
OUT DDRB, R16 ;PB0-PB3 là ngõ vào CPI R17, 2 ;mã SW=2
LDI R16, 0x0F BREQ MD_2 ;hiển thị mode 2
OUT PORTB, R16 ;điện trở kéo lên PB0-PB3 CPI R17, 3 ;mã SW=3?
LDI R16, 0xFF BREQ MD_3 ;hiển thị mode 3
OUT DDRC, R16 ;PORTC là ngõ ra RJMP WAIT_0 ;lập vòng từ đầu
LDI R16, 0x00 MD_0: LDI R18, 0x00 ;hiển thị mode 0
OUT PORTC, R16 ;LED tối OUT OUTPORT, R18 ;dãy LED tối
WAIT_0: LDI R16, 50 ;50 lần xét SW nhấn RJMP WAIT_0
BACK1: RCALL GET_KEY ;gọi ctc nhận dạng SW MD_1: LDI R18,0x0F ;hiển thị mode 1
BRCC WAIT_0 ;C=0 SW chưa nhấn: lập lại OUT OUTPORT, R18 ;sáng 4 LED thấp
DEC R16 RJMP WAIT_0
BRNE BACK1 ;lập vòng cho đủ số lần đếm MD_2: LDI R18,0xF0 ;hiển thị mode 2
PUSH R17 ; SW đã ấn, cất mã SW OUT OUTPORT, R18 ;sáng 4 LED cao
WAIT_1: LDI R16, 50 ;50 lần xét SW nhả RJMP WAIT_0
BACK2: RCALL GET_KEY ;gọi ctc nhận dạng SW MD_3: LDI R18,0xFF ;hiển thị mode 3
BRCS WAIT_1 ;C=1 SW chưa nhả:lập lại OUT OUTPORT, R18 ;sáng cả dãy LED
DEC R16 RJMP WAIT_0
BRNE BACK2 ;lập vòng cho đủ số lần đếm GET_KEY: …
POP R17 ;SW đã nhả, lấy lại mã SW RET
* Chương 6: Giao tiếp ngoại vi -7- Nguyễn Trọng Luật *
❖ BÀN PHÍM (Keypad)
o PB7:PB4: 4 hàng là ngõ vào, có điện trở
kéo lên, bình thường mức 1
o PB3:PB0: 4 cột là ngõ ra.
❖ Ý tưởng giải thuật nhận dạng phím nhấn
- Lần lượt xuất mức 0 ra từng cột
- Đọc trạng thái từng hàng, nếu có phím
nhấn kết nối với cột đang ở mức 0, hàng
tương ứng sẽ bị kéo xuống mức 0
- Từ mã quét vị trí cột và vị trí hàng ở
mức 0 suy ra mã phím bằng cách cộng vị
trí cột và hàng: . Vị trí cột: 0, 1, 2, 3
. Vị trí hàng: 0, 4, 8, C
Ví dụ khi xuất mã quét cột PB3:PB0 =0111, Vd 6.5: Viết một chương trình nhận dạng khi
nếu đọc hàng về PB7:PB4 =1101, tương ứng nhấn một phím sẽ hiển thị mã ASCII tương ứng
vị trí cột 3 (PB3=0) và vị trí hàng 4 (PB5=0). với mã phím. Chống rung phím khi nhấn và nhả.
Suy ra mã phím ấn = 3 + 4 = 7

* Chương 6: Giao tiếp ngoại vi -8- Nguyễn Trọng Luật *


Chương trình con GET_KEY16 xác định phím nhấn
;-----------------------------------------
;GET_KEY16 đọc trạng thái các phím, CHK_KEY:
;Trả về R17= mã phím và C=1 nếu có phím nhấn SUBI R17, 4 ;tính vị trí cột
;Trả về C=0 nếu phím chưa nhấn NEG R17 ;bù 2 lấy số dương
;------------------------------------------ SWAP R19 ;đảo sang 4 bit thấp mã hàng
LDI R20, 4;R20 đếm số lần quét hàng
GET_KEY16:
SCAN_ROW:
LDI R17, 4 ;R17 đếm số lần quét cột
ROR R19 ;quay phải qua C tìm bit 0
LDI R20, 0xFE ;bắt đầu quét cột 0
BRCC SET_FLG ;C=0 vị trí hàng có phím nhấn
SCAN_COL:
INC R17 ;không đúng hàng
OUT PORTB, R20 ;
;tăng vị trí hàng thêm 4
IN R19, PINB ;đọc trạng thái hàng
INC R17
IN R19, PINB ;đọc lại trạng thái hàng
INC R17
ANDI R19, 0xF0 ;che 4 bit cao lấy mã hàng
INC R17
CPI R19, 0xF0 ;xem có phím nhấn?
DEC R20
BRNE CHK_KEY ;R19 khác F0H, có phím nhấn
BRNE SCAN_ROW ;quét hết 4 hàng
LSL R20 ;quét cột kế tiếp
CLC ;không có phím nhấn C=0
INC R20 ;đặt LSB=1
RJMP EXIT ;thoát
DEC R17 ;giảm số lần quét cột
SET_FLG:
BRNE SCAN_COL ;tiếp tục quét hết số cột
SEC ;có phím nhấn C=1
CLC ;phím chưa nhấn, C=0
EXIT: RET
RJMP EXIT ;thoát
* Chương 6: Giao tiếp ngoại vi -9- Nguyễn Trọng Luật *
Chương trình con KEY_RD chống rung phím
;------------------------------------------
;KEY_RD đọc trạng thái phím
;Chống rung phím khi nhấn/nhả 50 lần
;Sử dụng GET_KEY16 nhận dạng phím nhấn
;Chỉ thoát khi có phím nhấn!!!
;-------------------------------------------
KEY_RD: LDIR16, 50 ;số lần nhận dạng phím nhấn
BACK1: RCALL GET_KEY16 ;gọi ctc nhận dạng phím
BRCC KEY_RD ;C=0 phím chưa nhấn lập lại
DEC R16 ;đếm số lần nhận dạng phím
BRNE BACK1 ;lập vòng cho đủ số lần đếm
PUSH R17 ;xác nhận phím nhấn,cất mã phím
WAIT_1: LDIR16, 50 ;số lần nhận dạng phím nhả
BACK2: RCALL GET_KEY16 ;gọi ctc nhận dạng phím
BRCS WAIT_1 ;C=1 phím chưa nhả
DEC R16 ;đếm số lần nhận dạng phím
BRNE BACK2 ;lập vòng cho đủ số lần đếm
POP R17 ;xác nhận phím nhả lấy lại mã phím
RET
* Chương 6: Giao tiếp ngoại vi - 10 - Nguyễn Trọng Luật *
Chương trình Vd 6.5
.INCLUDE <M324PDEF.INC> ;------------------------------------------
.EQU OUTPORT=PORTC ;HEX_ASC chuyển từ mã Hex sang mã ASCII
.ORG 0 ;Input R17=mã Hex,Output R18=mã ASCII
RJMP MAIN ;------------------------------------------
.ORG 0X40 HEX_ASC:
MAIN: LDI R16, HIGH(RAMEND);đưa stack lên vùng đ/c cao CPI R17, 0x0A ;ký tự <$0A?
OUT SPH, R16 BRCS NUM ;C=1 nhỏ hơn
LDI R16, LOW(RAMEND) LDI R18, 0x37 ;ký tự chữ
OUT SPL, R16 RJMP CHAR
LDI R16, 0x0F NUM: LDI R18, 0x30 ;ký tự số
OUT DDRB, R16 ;PB4-PB7 ngõ vào, CHAR: ADD R18, R17 ;cộng thêm $30
;PB0-PB3 ngõ ra RET
LDI R16, 0xFF
OUT PORTB, R16 ;điện trở kéo lên ngõ PB0-PB7 KEY_RD:
LDI R16, 0xFF …
OUT DDRC, R16 ;PORTC là output …
LDI R16, 0x00 RET
OUT PORTC, R16 ;PORTC=0 LED tối
START: RCALL KEY_RD ;ctc đọc phím GET_KEY16:
RCALL HEX_ASC ;chuyển mã Hex sang mã ASCII …
OUT OUTPORT, R18 ;hiển thị bar LED …
RJMP START ;lập vòng từ đầu RET
* Chương 6: Giao tiếp ngoại vi - 11 - Nguyễn Trọng Luật *
6.3 MỞ RỘNG GIAO TIẾP CỔNG NGOẠI VI Control inputs Inputs Outputs
❖ Giao tiếp IC chốt D 8 bit 74HC573 LE Dn Qn
H X X Z
L H L L
L H H H
L L X Q0

Vd: Viết đoạn chương trình xuất nội dung thanh ghi R17 ra chốt U2 và thanh ghi R18 ra chốt U3
LDI R16, $FF OUT PORTB, R17 ; xuất R17 ra Port B
OUT DDRB, R16 SBI PORTC, 0 ;mở chốt U2, xuất data ra U2
SBI DDRC, 0 CBI PORTC, 0 ;khóa chốt U2, chốt data vừa xuất
SBI DDRC, 1 OUT PORTB, R18 ;xuất R18 ra Port B
CBI PORTC, 0 ;khóa chốt U2 SBI PORTC, 1 ;mở chốt U3, xuất data ra U3
CBI PORTC, 1 ;khóa chốt U3 CBI PORTC, 1 ;khóa chốt U3, chốt data vừa xuất
* Chương 6: Giao tiếp ngoại vi - 12 - Nguyễn Trọng Luật *
❖ Giao tiếp IC đệm 3 trạng thái 74HC244
Inputs (i=1,2;n=0..3) Outputs
iAn iYn
H X Z
L L L
L H H

Vd: Viết đoạn chương trình cất data từ đệm U2 vào thanh ghi R17 và data từ đệm U3 vào thanh ghi R18
LDI R16, 0x00 CBI PORTC, 0 ;mở đệm U2, data đưa về Port B
OUT DDRB, R16 IN R17, PINB ;cất data vào R17
SBI DDRC, 0 SBI PORTC, 0 ;cấm đệm U2
SBI DDRC, 1 CBI PORTC, 1 ;mở đệm U3, data đưa về Port B
SBI PORTC, 0 ;cấm đệm U2 IN R18, PINB ;cất data vào R17
SBI PORTC, 1 ;cấm đệm U3 SBI PORTC, 1 ;cấm đệm U3
* Chương 6: Giao tiếp ngoại vi - 13 - Nguyễn Trọng Luật *
Vd 6.6: Viết chương trình liên tục nhập data từ
ngõ vào U4, chuyển 4 bit thấp và 4 bit cao sang
mã ASCII, lần lượt xuất ra U2 và U3 tương ứng.
.ORG 0
LDIR16, 0x07
OUT DDRC, R16 ;PC2:PC0 là output
SBI PORTC, 2 ;khóa ngõ vào U4
CBIPORTC, 0 ;khóa ngõ ra U2
CBIPORTC, 1 ;khóa ngõ ra U3
START: LDIR16, 0x00
OUT DDRB, R16 ;Port B là input CBIPORTC, 0 ;khóa U2
CBIPORTC, 2 ;mở U4 POP R17 ;phục hồi data
IN R17, PINB ;đọc data SWAP R17 ;hoán vị sang 4 bit thấp
SBI PORTC, 2 ;khóa U4 ANDI R17, 0x0F ;che 4 bit thấp data
PUSH R17 ;cất data RCALL HEX_ASC ;chuyển sang mã ASCII
LDIR16, 0xFF OUT PORTB, R18 ;xuất mã ASCII
OUT DDRB, R16 ;Port B là output SBI PORTC, 1 ;mở U3
ANDI R17, 0x0F ;che 4 bit thấp data CBIPORTC, 1 ;khóa U3
RCALL HEX_ASC ;chuyển sang mã ASCII RJMP START
OUT PORTB, R18 ;xuất mã ASCII HEX_ASC: … (vd 6.5)
SBI PORTC, 0 ;mở U2 RET
* Chương 6: Giao tiếp ngoại vi - 14 - Nguyễn Trọng Luật *
❖ Giao tiếp IC Thanh ghi dịch 74HC595
Ngõ vào điều khiển Ngõ vào Ngõ ra
Chức năng
SHCP STCP DS Q7S Qn
X X L L X L Q0 Reset thanh ghi và ngõ ra song song không đổi
X L L X L L Reset thanh ghi và ngõ ra song song
X X H L X L Z Reset thanh ghi và ngõ ra song song tổng trở cao
X L H DI Q6S Q0 Mode ghi dịch, DI dịch vào thanh ghi, ngõ ra song song không đổi
X L H X Q0 QnS Mode xuất data, ngõ ra các tầng ghi dịch được phép xuất ngõ ra song song
L H DI Q6S QnS Mode ghi dịch và xuất data ngõ ra bằng giá trị ghi dịch trước đó

* Chương 6: Giao tiếp ngoại vi - 15 - Nguyễn Trọng Luật *


Vd 6.9: Từ sơ đồ viết một chương trình nhập data từ Port D, xuất ra dưới dạng nối tiếp giao tiếp với
thanh ghi dịch IC 74HC595. ;-------------------------------------
.ORG 0 ;SHIFT_OUT dịch data nối tiếp xuất ra port MSB trước
RJMP MAIN ;Input: R17 chứa byte data cần dịch
.ORG 0X40 ;Output: R17 bảo toàn nội dung
;-------------------------------------
MAIN: LDIR16, HIGH(RAMEND)
SHIFT_OUT:
OUT SPH, R16
LDI R16, 8 ;R16 đếm số bit dịch
LDIR16, LOW(RAMEND)
SH_O: ROL R17 ;quay trái R17 qua C
OUT SPL, R16
BRCC BIT_0 ;C=0 xuất bit 0
LDI R16, 0x00
SBI PORTB, 0 ;C=1 xuất bit 1
OUT DDRD, R16 ;PortD input
RJMP SH_CK ;nhảy đến tạo CK dịch
LDIR16, 0x07 ;PB0=DS,
BIT_0: CBI PORTB, 0 ;xuất bit 0
;PB1=CK dịch,
SH_CK: SBI PORTB, 1 ;tạo xung CK dịch
;PB2=CK xuất output
CBI PORTB, 1
OUT DDRB, R16
DEC R16 ;đếm số lần dịch
CBIPORTB, 1 ;CK dịch=0
BRNE SH_O ;dịch tiếp cho đủ số bit
CBIPORTB, 2 ;CK xuất=0
SBI PORTB, 2 ;tạo xung CK xuất
START: IN R17, PIND ;đọc data từ PORTD
CBI PORTB, 2
RCALL SHIFT_OUT ;gọi ctc ghi dịch
ROL R17 ;dịch phục hồi R17
RJMP START
RET
* Chương 6: Giao tiếp ngoại vi - 16 - Nguyễn Trọng Luật *
6.4 GIAO TIẾP HIỂN THỊ LED 7 ĐOẠN

• DIPSW4 gồm 4 SW: vị trí ON là đóng SW, vị trí còn lại hở SW.
• Port B lái trực tiếp các chân đoạn do dòng ngõ ra các chân port có thể đạt 20mA,
Đoạn dp g f e d c b a
Data D7 D6 D5 D4 D3 D2 D1 D0
Ký tự 0 1 2 3 4 5 6 7 8 9 A B C D E F
Mã 7 đoạn (H) C0 F9 A4 B0 99 92 82 F8 80 90 88 83 C6 A1 86 8E
* Chương 6: Giao tiếp ngoại vi - 17 - Nguyễn Trọng Luật *
Vd 6.10: Viết chương trình đọc data từ DIPSW4 và hiển thị mã Hex của data ra LED 7 đoạn AC.

.INCLUDE <M324PDEF.INC> START:


.EQU OUTPORT=PORTB IN R17, PINC ;đọc data từ DIPSW4
.EQU IOSETB=DDRB ANDI R17, 0X0F ;che 4 bit thấp
.ORG 0 LDIZH,HIGH(TAB_7SA<<1)
RJMP MAIN ;Z trỏ địa chỉ đầu bảng tra mã 7 đoạn
.ORG 0X40 LDIZL,LOW(TAB_7SA<<1)
MAIN: LDIR16, HIGH(RAMEND) ADD R30, R17 ;cộng offset vào ZL
OUT SPH, R16 LDIR17, 0
LDIR16, LOW(RAMEND) ADC R31, R17 ;cộng carry vào ZH
OUT SPL, R16 LPM R17, Z ;lấy mã 7 đoạn
LDIR16, 0xFF ;PORTB output OUT OUTPORT, R17 ;xuất mã 7 đoạn
OUT IOSETB, R16 RJMP START
LDIR16, 0xF0 ;PC3:PC0 input TAB_7SA:
OUT DDRC, R16 .DB 0xC0,0xF9,0xA4,0xB0,0x99,0x92
LDIR16, 0x0F ;R kéo lênPC3:PC0 .DB 0x82,0xF8,0x80,0x90,0x88,0x83
OUT PORTC, R16 .DB 0xC6,0xA1,0x86,0x8E

* Chương 6: Giao tiếp ngoại vi - 18 - Nguyễn Trọng Luật *


Vd 6.11: Từ ví dụ 6.6,
kết nối 2 LED 7 đoạn
AC như hình. Viết một
chương trình đọc byte
data từ U4, hiển thị
dưới dạng số Hex ra 2
LED 7 đoạn, trọng số
cao xuất ra U2, trong
số thấp xuất ra U3.
;------------------------------------------
Chương trình viết tương tự như Vd 6.6, ;GET_7SEG tra mã 7 đoạn từ data đọc vào
;Input R17=mã Hex,Output R17=mã 7 đoạn
chỉ thay chương trình con đổi mã ASCII
;------------------------------------------
thành đổi mã Led 7 đoạn GET_7SEG:
LDIZH, HIGH(TAB_7SA<<1)
;------------------------------------------- LDIZL, LOW(TAB_7SA<<1)
TAB_7SA: ADD R30, R17 ;cộng offset vào ZL
.DB 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92 LDIR17, 0
.DB 0x82, 0xF8, 0x80, 0x90, 0x88, 0x83 ADC R31, R17 ;cộng carry vào ZH
.DB 0xC6, 0xA1, 0x86, 0x8E LPM R17, Z ;lấy mã 7 đoạn
RET
* Chương 6: Giao tiếp ngoại vi - 19 - Nguyễn Trọng Luật *
❖ Phương pháp quét Led: Lợi dụng hiện tượng lưu ảnh mắt người, tại một thời điểm chỉ
cấp nguồn cho 1 LED sáng, các LED còn lại tối, cứ thế tuần tự cho từng LED và sau đó
lập vòng lại. Để đảm bảo mắt người có cảm giác các LED đều sáng liên tục, tần số quét
lập vòng không nhỏ hơn 50Hz.

* Chương 6: Giao tiếp ngoại vi - 20 - Nguyễn Trọng Luật *


Các bước thực hiện chương trình:
▪ Nhập data từ Port D.
▪ Đổi data từ nhị phân sang BCD
▪ Quét led: tuần tự thực hiện cho từng led
- đổi BCD thành mã led 7 đoạn và xuất ra U2 (qua Port B)
- xuất mã chọn led sáng ra U3 (qua Port B)
- delay 1ms
▪ Lặp lại liên tục các bước trên.

- Để mang tính tổng quát, chương trình con BIN8_BCD chuyển từ số nhị phân 8 bit sang số
BCD 3 digit, kết quả là số BCD nén cất trong R21, R20.
- Trong chương trình con SCAN_4LA, để thuận tiện tạo vòng lặp 4 lần tương ứng quét 4
đèn, ta sử dụng chương trình con BCD_UNP tách số BCD nén thành không nén. Chương
trình con này có thể không cần thiết nếu từ chương trình con BIN8_BCD cho kết quả là số
BCD không nén.
- Có thể tùy chỉnh thời gian trễ trong ctc DELAY_1MS để điều chỉnh độ sáng đèn

* Chương 6: Giao tiếp ngoại vi - 21 - Nguyễn Trọng Luật *


.INCLUDE <M324PDEF.INC> ;-------------------------------------------
.EQU OUTPORT=PORTB ;BIN8_BCD chuyển số nhị phân 8 bit
.EQU INPORT=PIND ; sang số BCD 3 digit
.EQU SR_ADR=0X100 ;Input R17=số nhị phân 8 bit
.ORG 0 ;Output R21, R20=số BCD nén, R21 trọng số cao
LDIR16,0X03 ;Sử dụng ctc DIV8_8, R16=10 số chia
OUT DDRC,R16 ;PC0,PC1 là output ;-------------------------------------------
CBIPORTC,0 ;khóa ngõ ra U2 BIN8_BCD:
CBIPORTC,1 ;khóa ngõ ra U3 CLR R20
LDIR16,0XFF CLR R21
OUT DDRB,R16 LDI R16,10 ;R16=số chia
LDIR16,0X00 RCALL DIV8_8 ;ctc chia 8 bit
OUT DDRD,R16 MOV R20,R16 ;R20=dư: BCD đơn vị
LDIR20,0X00 LDI R16,10
LDIR21,0X00 RCALL DIV8_8
RCALL SCAN_4LA SWAP R16 ;chuyển BCD chục
START: ; lên 4 bit cao
` IN R17,INPORT ;đọc data OR R20,R16 ;ghép BCD nén: CH_ĐV
RCALL BIN8_BCD ;ctc đổi BCD MOV R21,R17 ;R21=BCD trăm
RCALL SCAN_4LA ;ctc quét 4 LED RET
RJMP START
* Chương 6: Giao tiếp ngoại vi - 22 - Nguyễn Trọng Luật *
;--------------------------------------------
;SCAN_4LA hiển thị 4 LED AC bằng pp quét
;Input: R20=số BCD nén (chục-đơn vị)
; R21=số BCD nén (ngàn-trăm)
;ctc BCD_UNP tách số BCD nén thành ko nén
;Sử dụng ctc DELAY_1MS, GET_7SEG LD R17, X+ ;nạp số BCD từ SRAM
;Sử dụng R17, R18, R19, X RCALL GET_7SEG ;lấy mã 7 đoạn
;--------------------------------------------- OUT OUTPORT, R17 ;xuất mã 7 đoạn
SCAN_4LA: SBI PORTC, 0 ;mở U2
RCALL BCD_UNP CBI PORTC, 0 ;khóa U2
LDI R18, 4 ;R18 số lần quét LED OUT OUTPORT, R19 ;xuất mã quét anode LED
LDI R19, 0xFE ;mã quét led anode, SBI PORTC, 1 ;mở U3
;bắt đầu LED0 CBI PORTC, 1 ;khóa U3
LDI XH, HIGH(SR_ADR) RCALL DELAY_1MS ;tạo trễ 1ms sáng đèn
LDI XL, LOW(SR_ADR) SEC ;C=1 chuẩn bị quay trái
LOOP:LDI R17, 0xFF ;làm tối các đèn ROL R19 ;mã quét anode kế tiếp
OUT OUTPORT, R17 DEC R18 ;đếm số lần quét
SBI PORTC, 1 ;mở U3 BRNE LOOP ;thoát khi quét đủ 4 lần
CBI PORTC, 1 ;khóa U3 RET

* Chương 6: Giao tiếp ngoại vi - 23 - Nguyễn Trọng Luật *


;---------------------------------------------------- ;-------------------------------------------
;BCD_UNP tách số BCD nén thành ko nén ;DIV_8_8 chia 2 số nhị phân 8 bit
;Input: R20=số BCD nén (chục-đơn vị) ;Input R17= số bị chia, R16=số chia
; R21=số BCD nén (ngàn-trăm) ;Output R17=thương số, R16=dư số
;Output: cất vào 4 ô nhớ đầu SRAM ;Sử dụng R15
;---------------------------------------------------- ;------------------------------------------
BCD_UNP: DIV8_8: CLR R15 ;R15=thương số
LDI XH, HIGH(SR_ADR) GT_DV: SUBR17, R16 ;trừ số bị chi cho số chia
LDI XL, LOW(SR_ADR) BRCS LT_DV ;C=1 không chia được
MOV R17, R20 ;lấy số BCD nén trọng số thấp INC R15 ;tăng thương số thêm 1
ANDI R17, 0x0F ;lấy số BCD đơn vị RJMP GT_DV ;thực hiện tiếp
ST X+, R17 ;cất vào SRAM LT_DV: ADD R17, R16 ;lấy lại dư số
MOV R17, R20 MOV R16, R17 ;R16=dư số
SWAP R17 MOV R17, R15 ;R17=thương số
ANDI R17, 0x0F ;lấy số BCD chục RET
ST X+, R17 ;cất vào SRAM DELAY_1MS:
MOV R17, R21 ;lấy số BCD nén trọng số cao …
ANDI R17, 0x0F ;lấy số BCD trăm RET
ST X+, R17 ;cất vào SRAM
GET_7SEG:
MOV R17, R21

SWAP R17
RET
ANDI R17, 0x0F ;lấy số BCD ngàn
ST X+, R17 ;cất vào SRAM TAB_7SA:
RET .DB …
* Chương 6: Giao tiếp ngoại vi - 24 - Nguyễn Trọng Luật *
6.5 GIAO TIẾP BỘ HIỂN THỊ LCD KÝ TỰ 16x2

LCD ký tự có 2 thanh ghi: thanh ghi lệnh (IR)


và thanh ghi data (DR), phân biệt bằng RS.
Khi MCU truy xuất LCD, nếu RS=0 data
chính là mã lệnh sẽ chuyển đến IR, nếu RS=1
data là mã ASCII chuyển đến DR hiển thị ký
tự tương ứng ra LCD

DDRAM (Data Display RAM): có địa chỉ từ 80H÷FFH. Nếu ta ghi ký tự ASCII vào vùng RAM này, thì
nó sẽ hiển thị lên LCD. Trong LCD 16x2 thì chỉ các ô nhớ có địa chỉ như hình mới được hiển thị.

Con trỏ (Cursor): là thanh ghi khi trỏ vào vùng DDRAM, thì
ký tự ghi vào thanh ghi DR sẽ được chuyển vào ô nhớ đó.
* Chương 6: Giao tiếp ngoại vi - 25 - Nguyễn Trọng Luật *
❖ Cấu hình LCD:
▪ Lệnh 1 Function set: đặt cấu hình làm việc LCD kết
nối 8/4 bit (DL), số dòng (N), ma trận 5x8 hay 5x10 (F)
o DL: DL=1 giao tiếp data 8 bit D7-D0
DL=0 giao tiếp data 4 bit D7-D4
o N: N=1 đặt 2 dòng, N=0 đặt 1 dòng
o F: F=1 font 5x10 (N=0), F=0 font 5x8
Vd: Function set: giao tiếp 8 bit 2 dòng font 5x8
=> Mã lệnh=38H
▪ Lệnh 2 Clear display: xóa toàn bộ màn hình và con
trỏ tự động dời về đầu dòng 1. Mã lệnh 01H
▪Lệnh 3 Display on/off control: điều khiển màn hình và con trỏ
o D: D=1 màn hình on, D=0 màn hình off
o C: C=1 con trỏ on, C=0 con trỏ off Vd: Display on/off control:màn hình on,con trỏ off
o B: B=1 ký tự và con trỏ chớp, B=0 ký tự và con trỏ không chớp => Mã lệnh=0CH

▪ Lệnh 4 Entry mode set: chọn mode dịch con trỏ/màn hình.
o I/D=1/0: tăng/giảm địa chỉ DDRAM thêm/bớt 1 khi truy xuất DDRAM
o S: S=1 dịch màn hình sang phải (I/D=0) hay trái (I/D=1), S=0: không dịch màn hình
Vd: Entry mode set: con trỏ dịch phải, địa chỉ DDRAM tăng 1 khi ghi data, màn hình không dịch
=> Mã lệnh=06H
* Chương 6: Giao tiếp ngoại vi - 26 - Nguyễn Trọng Luật *
Một số mã lệnh thông dụng (điều khiển RS=0, RW=0)
Mã (HEX) Chức năng Thời gian thực thi
01 Xóa màn hình (Clear display) (tự về vị trí đầu dòng) 1.52ms
02 Trở về vị trí đầu dòng (Return home) 1.52ms
04 Dịch con trỏ sang trái (khi ghi/đọc data) 37μs
06 Dịch con trỏ sang phải (khi ghi/đọc data) 37μs
08 Tắt màn hình, tắt con trỏ 37μs
0C Hiện màn hình, tắt con trỏ 37μs
0F Hiện màn hình, chớp ký tự chỉ bởi con trỏ 37μs
10 Dịch con trỏ sang trái (không thay đổi nội dung DDRAM) 37μs
14 Dịch con trỏ sang phải (không thay đổi nội dung DDRAM) 37μs
18 Dịch màn hình sang trái (không thay đổi nội dung DDRAM) 37μs
1C Dịch màn hình sang phải (không thay đổi nội dung DDRAM) 37μs
28 Đặt chức năng giao tiếp 4 bit cao, 2 dòng, 5 x 8 dots 37μs
38 Đặt chức năng giao tiếp 8 bit, 2 dòng, 5 x 8 dots 37μs
80÷8F, C0÷CF Cho con trỏ về vị trí địa chỉ DDRAM cần hiển thị ký tự 37μs

* Chương 6: Giao tiếp ngoại vi - 27 - Nguyễn Trọng Luật *


❖ Lập trình LCD:
Ghi lệnh vào LCD:
- cho chân RS và RW = 0
- đưa mã lệnh vào các chân data D0..D7
- tạo xung cạnh xuống ở chân E và chờ khoảng 100μs để xừ lý lệnh (đối với mã lệnh
01H và 02H cần chờ khoảng 2ms) thay cho việc kiểm tra bit BF (Busy Flag)

Ghi data vào LCD:


- cho chân RS = 1 và RW = 0
- đưa data cần hiển thị (mã ASCII) vào các chân data D0 – D7
- tạo xung cạnh xuống ở chân E và chờ khoảng 100μs để xừ lý data
Giao tiếp data 8 bit hay 4 bit
- Giao tiếp 8 bit: kết nối 8 chân D0..D7 với 8 chân port tương ứng của MCU. Mỗi lệnh
giao tiếp chỉ cần truy xuất 1 byte kết hợp 3 tín hiệu điều khiển (RS, RW, E).
- Giao tiếp 4 bit: kết nối 4 chân D4..D7 với 4 chân port tương ứng của MCU. Mỗi lệnh
giao tiếp cần truy xuất 2 lần, mỗi lần 4 bit kết hợp với 3 tín hiệu điều khiển (RS, RW, E).
Truy xuất 4 bit cao trước, chờ 100μs rồi truy xuất tiếp 4 bit thấp

* Chương 6: Giao tiếp ngoại vi - 28 - Nguyễn Trọng Luật *


Reset nguồn khởi động LCD

Cấp nguồn Cấp nguồn

Chờ > 15ms sau khi VDD Chờ > 15ms sau khi VDD
tăng đến 4.5V (*) tăng đến 4.5V (*)

Ghi byte lệnh 30H Ghi 4bit lệnh 3H

Chờ > 4.1ms Chờ > 4.1ms

Ghi byte lệnh 30H Ghi 4bit lệnh 3H

Chờ > 100μs Chờ > 100μs

Ghi byte lệnh 30H Ghi 4bit lệnh 3H

Các lệnh reset cấp nguồn giao tiếp 8 bit Chờ > 100μs

Ghi 4bit lệnh 2H


(*) Sử dụng nguồn 3V: Chờ > 40ms
sau khi VDD tăng đến 2.7V Các lệnh reset cấp nguồn giao tiếp 4 bit

* Chương 6: Giao tiếp ngoại vi - 29 - Nguyễn Trọng Luật *


Vd 6.16: Cho sơ đồ MCU324P giao tiếp trực tiếp với LCD 16x2 giao tiếp 8 bit.
Viết một chương trình điều khiển LCD 16x2 thực hiện các công việc sau:
- Reset cấp nguồn cho LCD
- Khởi động LCD viết thành chương trình con
- Hiển thị ra LCD 2 dòng ký tự như hình

Xin chao!
Mon Vi xu ly .INCLUDE <M324PDEF.INC>
.EQU OUTPORT=PORTB ;PORTB data
.EQU INPORT=PINB
.EQU IOSETB=DDRB
.EQU CONT=PORTC ;PORTC điều khiển
.EQU CONT_DR=DDRC
.EQU CONT_OUT=PORTC
.EQU CONT_IN=PINC
.EQU RS=0 ;bit RS
.EQU RW=1 ;bit RW
.EQU E=2 ;bit E
.EQU CR=$0D ;mã xuống dòng
.EQU NULL=$00 ;mã kết thúc

* Chương 6: Giao tiếp ngoại vi - 30 - Nguyễn Trọng Luật *


.ORG 0
RJMP MAIN CBICONT, RS ;RS=0 ghi lệnh
.ORG 0X40 LDIR17, $30 ;mã lệnh=$30 lần 1
MAIN: LDIR16, HIGH(RAMEND) RCALL OUT_LCD ;ctc ghi ra LCD
OUT SPH, R16 LDIR16, 42 ;delay 4.2ms
LDIR16, LOW(RAMEND) RCALL DELAY_US
OUT SPL, R16 CBICONT, RS
LDIR16, 0X07 LDIR17, $30 ;mã lệnh=$30 lần 2
OUT CONT_DR, R16 RCALL OUT_LCD
;PC0,PC1,PC2 là out LDIR16, 2 ;delay 200μs
CBICONT, RS ;RS=PC0=0 RCALL DELAY_US
CBICONT, RW ;RW=PC1=0 ghi LCD CBICONT, RS
CBICONT, E ;E=PC2=0 cấm LCD LDIR17, $30 ;mã lệnh=$30 lần 3
LDIR16, 0XFF RCALL OUT_LCD
OUT IOSETB, R16 ;Port B out LDIR18, $38 ;Function set 2 dòng, font 5x8
/* Reset nguồn khởi động – Cấu hình LCD */ LDIR19, $01 ;Clear display
LDIR16, 250 ;delay 25ms LDIR20, $0C ;display on, con trỏ off
RCALL DELAY_US ;ctc delay 100μsxR16 LDIR21, $06 ;Entry mode set dịch phải con trỏ
LDIR16, 250 ;delay 25ms ;DDRAM tăng 1, ko dịch màn hình
RCALL DELAY_US ;ctc delay 100μsxR16 RCALL INIT_LCD8 ;ctc khởi động LCD 8 bit

* Chương 6: Giao tiếp ngoại vi - 31 - Nguyễn Trọng Luật *


START: LDIR16,1 ;chờ 100μs
RCALL DELAY_US
CBICONT, RS ;RS=0 ghi lệnh DOWN:LDIR16, 1 ;chờ 100μs
LDIR17, $83 RCALL DELAY_US
;con trỏ ở dòng 1 vị trí thứ 4 CBICONT, RS ;RS=0 ghi lệnh
RCALL OUT_LCD LDIR17, $C2
LDIZH, HIGH(TAB<<1) ;con trỏ ở dòng 2 vị trí thứ 3
LDIZL, LOW(TAB<<1) RCALL OUT_LCD
;Z trỏ đầu bảng tra ký tự LINE2: LPM R17, Z+
LINE1: LPM R17, Z+ ;lấy mã ASCII ký tự từ Flash ROM
;lấy mã ASCII ký tự từ Flash ROM CPIR17, NULL ;kiểm tra ký tự kết thúc
CPIR17, CR BREQ WAIT ;ký tự NULL thoát
;kiểm tra ký tự xuống dòng? LDIR16, 1 ;chờ 100μs
BREQ DOWN ; =CR xuống dòng RCALL DELAY_US
LDIR16, 1 ;chờ 100μs SBI CONT, RS ;RS=1 ghi data hiển thị LCD
RCALL DELAY_US RCALL OUT_LCD ;ghi mã ASCII ký tự ra LCD
SBI CONT, RS ;RS=1 ghi data RJMP LINE2 ;tiếp tục dòng 2
RCALL OUT_LCD WAIT: LDIR16, 1 ;chờ 100μs
;ghi mã ASCII ký tự ra LCD RCALL DELAY_US
RJMP LINE1 ;tiếp tục dòng 1 HERE: RJMP HERE

* Chương 6: Giao tiếp ngoại vi - 32 - Nguyễn Trọng Luật *


;-----------------------------------------------------------------
;INIT_LCD8 khởi động LCD ghi 4 byte mã lệnh
;Function set: R18=$38 giao tiếp 8 bit, 2 dòng font 5x8
;Clear Display: R19=$01 xóa màn hình
;Display control: R20=$0C màn hình on, con trỏ off
;Entry mode set: R21=$06 dịch phải con trỏ, địa chỉ
;DDRAM tăng 1 khi ghi data, không dịch màn hình
;---------------------------------------------------------------
INIT_LCD8: LDIR16, 20
LDIR16, 1 ;chờ 100μs ;chờ 2ms sau lệnh Clear display
RCALL DELAY_US RCALL DELAY_US
CBI CONT, RS ;RS=0 ghi lệnh CBICONT, RS ;RS=0 ghi lệnh
MOV R17, R18 ;R18=Function set MOV R17, R20 ;R20=Display control
RCALL OUT_LCD RCALL OUT_LCD
LDIR16, 1 ;chờ 100μs LDIR16, 1 ;chờ 100μs
RCALL DELAY_US RCALL DELAY_US
CBICONT, RS ;RS=0 ghi lệnh CBICONT, RS ;RS=0 ghi lệnh
MOV R17, R19 ;R19=Clear display MOV R17, R21 ;R21=Entry mode set
RCALL OUT_LCD RCALL OUT_LCD
RET

* Chương 6: Giao tiếp ngoại vi - 33 - Nguyễn Trọng Luật *


;-------------------------------------------------- ;-------------------------------------------------------
;OUT_LCD ghi mã lệnh/data ra LCD ;DELAY_US tạo thời gian trễ
;Input: R17 chứa mã lệnh/data ;=R16x100μs(Fosc=8Mhz)
;-------------------------------------------------- ;Input: R16 hệ số nhân thời gian trễ 1 đến 255
OUT_LCD: ;-------------------------------------------------------
OUT OUTPORT, R17 DELAY_US:
;ghi lệnh/data ra LCD MOV R15, R16 ;1MC nạp data cho R15
SBI CONT, E ;tạo xung cạnh xuống LDIR16, 200 ;1MC sử dụng R16
CBI CONT, E ;cho phép LCD L1: MOV R14, R16 ;1MC nạp data cho R14
RET L2: NOP ;1MC
DEC R14 ;1MC
;------------------------------------------------------------- BRNE L2 ;2/1MC
; Bảng chuỗi ký tự ASCII hiển thị ra LCD DEC R15 ;1MC
;------------------------------------------------------------- BRNE L1 ;2/1MC
TAB: .DB "Xin chao!", $0D, "Mon Vi xu ly", $00 RET ;4MC

Chương trình con OUT_LCD ghi mà lệnh/data ra LCD. Trước khi gọi ctcon này; phải cho RW=0, và
RS=0 nếu ghi mã lệnh hoặc RS=1 nếu ghi ký tự hiển thị ra LCD.
Bảng TAB là chuỗi ký tự ASCII để hiển thị được cất trong bộ nhớ Flash: gồm có 2 dòng cách nhau ký tự
0DH, và kết thúc là ký tự null 00H
* Chương 6: Giao tiếp ngoại vi - 34 - Nguyễn Trọng Luật *
Vd 6.17: Cho sơ đồ giao tiếp giữa MCU324P với LCD 16x2 giao tiếp 4 bit như bên dưới. Viết một chương
trình điều khiển LCD 16x2 thực hiện các công việc giống ví dụ 6.16

Khi truy xuất mã lệnh hoặc data, ta chia byte


Xin chao! lệnh/data thành 2 lệnh, mỗi lệnh gồm 4 bit kết
Mon Vi xu ly hợp với các tín hiệu điều khiển, truy xuất 4 bit
cao trước. Lưu ý là giữa 2 lần truy xuất lệnh 4bit
phải có thời gian chờ 100μs!

.INCLUDE <M324PDEF.INC>
.EQU LCD=PORTC ;PORTC giao tiếp BUS
LCD16x2
.EQU LCD_DR=DDRC
.EQU LCD_IN=PINC
.EQU RS=0 ;bit RS
.EQU RW=1 ;bit RW
.EQU E=2 ;bit E
.EQU CR=$0D ;mã xuống dòng
.EQU NULL=$00 ;mã kết thúc

* Chương 6: Giao tiếp ngoại vi - 35 - Nguyễn Trọng Luật *


.ORG 0 CBILCD, RS ;RS=0 ghi lệnh
RJMP MAIN LDIR17, $30 ;mã lệnh=$30 lần 1,
.ORG 0X40 ;RS=RW=E=0
MAIN: LDIR16, HIGH(RAMEND) OUT RCALL OUT_LCD4 ;ctc ghi ra LCD
SPH, R16 LDIR16, 42 ;delay 4.2ms
LDIR16, LOW(RAMEND) RCALL DELAY_US
OUT SPL, R16 CBILCD, RS
LDIR16, 0XFF LDIR17, $30 ;mã lệnh=$30 lần 2
OUT LCD_DR, R16 ;PORTC là output RCALL OUT_LCD4
CBILCD, RS ;RS=PC0=0 LDIR16, 2 ;delay 200μs
CBILCD, RW ;RW=PC1=0 ghi RCALL DELAY_US
CBILCD, E ;E=PC2=0 cấm LCD CBILCD, RS
/* Reset nguồn khởi động – Cấu hình LCD */ LDIR17, $32 ;mã lệnh=$32
LDIR16, 250 ;delay 25ms RCALL OUT_LCD4_2 ;ctc ghi 1 byte ra LCD
RCALL DELAY_US LDIR18, $28 ;Function set
LDIR16, 250 ;delay 25ms ;giao tiếp 4 bit 2 dòng font 5x8
RCALL DELAY_US LDIR19, $01 ;Clear display
LDIR20, $0C ;display on,con trỏ off
LDIR21, $06 ;Entry mode set
RCALL INIT_LCD4 ;ctc khởi động LCD 4 bit

* Chương 6: Giao tiếp ngoại vi - 36 - Nguyễn Trọng Luật *


START: CBI LCD, RS ;RS=0 ghi lệnh
LDIR17, $01 ;xóa màn hình
RCALL OUT_LCD4_2 DOWN:LDIR16, 1 ;chờ 100μs
LDIR16, 20 ;chờ 2ms RCALL DELAY_US
RCALL DELAY_US CBILCD, RS ;RS=0 ghi lệnh
CBILCD, RS ;RS=0 ghi lệnh LDIR17, $C2
LDIR17, $83 ;con trỏ ở dòng 2 vị trí thứ 3
;con trỏ ở dòng 1 vị trí thứ 4 RCALL OUT_LCD4_2
RCALL OUT_LCD4_2 LINE2: LPM R17, Z+ ;lấy mã ASCII
LDIZH, HIGH(TAB<<1) CPIR17, NULL ;ký tự kết thúc?
LDIZL, LOW(TAB<<1) BREQ WAIT ;= NULL thoát
LINE1: LPM R17, Z+ ;lấy mã ASCII SBI CONT, RS ;RS=1 ghi data
CPIR17, CR ;ký tự xuống dòng? RCALL OUT_LCD4_2
BREQ DOWN ;= CR xuống dòng ;ghi mã ASCII ký tự ra LCD
SBI LCD, RS ;RS=1 ghi data RJMP LINE2 ;tiếp tục dòng 2
RCALL OUT_LCD4_2 WAIT: LDIR16, 1 ;chờ 100μs
;ghi mã ASCII ký tự ra LCD RCALL DELAY_US
RJMP LINE1 ;tiếp tục hiển thị dòng 1 HERE: RJMP HERE

* Chương 6: Giao tiếp ngoại vi - 37 - Nguyễn Trọng Luật *


;----------------------------------------------------------------- ;--------------------------------------------------
;INIT_LCD4 khởi động LCD ghi 4 byte mã lệnh ;OUT_LCD4 ghi mã lệnh/data ra LCD
;Function set: R18=$28 giao tiếp 4 bit, 2 dòng font 5x8 ;Input: R17 chứa mã lệnh/data 4 bit cao
;Clear display: R19=$01 xóa màn hình ;--------------------------------------------------
;Display control: R20=$0C màn hình on,con trỏ off OUT_LCD4: OUT LCD, R17
;Entry mode set: R21=$06 dịch phải con trỏ SBI LCD, E
;RS=bit0=0, RW=bit1=0 CBILCD, E
;---------------------------------------------------------------- RET
INIT_LCD4: ;-------------------------------------------------------
CBILCD, RS ;RS=0: ghi lệnh ;DELAY_US tạo thời gian trễ
MOV R17, R18 ;R18=Function set ;=R16x100μs(Fosc=8Mhz)
RCALL OUT_LCD4_2 ;ghi 1 byte data ;Input: R16 hệ số nhân thời gian trễ 1 đến 255
MOV R17, R19 ;R19=Clear display ;-------------------------------------------------------
RCALL OUT_LCD4_2 DELAY_US: …
LDIR16, 20 ;chờ 2ms …
RCALL DELAY_US RET
MOV R17, R20 ;R20=Display LCD ;-------------------------------------------------------------
RCALL OUT_LCD4_2 ; Bảng chuỗi ký tự ASCII hiển thị ra LCD
MOV R17, R21 ;R21=Entry mode set ;-------------------------------------------------------------
RCALL OUT_LCD4_2 TAB: .DB "Xin chao!", $0D, "Mon Vi xu ly", $00
RET
* Chương 6: Giao tiếp ngoại vi - 38 - Nguyễn Trọng Luật *
;------------------------------------------------------
;OUT_LCD4_2 ghi 1 byte mã lệnh/data ra LCD
;chia làm 2 lần ghi 4bit
;Input: R17 chứa mã lệnh/data,R16
;bit RS=0/1:lệnh/data, bit RW=0:ghi
;Sử dụng ctc OUT_LCD4
;------------------------------------------------------
OUT_LCD4_2: LDIR16, 1 ;chờ 100μs
LDIR16,1 ;chờ 100μs RCALL DELAY_US
RCALL DELAY_US POP R17 ;phục hồi R17
IN R16, LCD ;đọc PORT LCD POP R16 ;phục hồi R16
ANDI R16, (1<<RS) ;lọc bit RS SWAP R17 ;đảo 4 bit
PUSH R16 ;cất R16 ANDI R17, $F0
PUSH R17 ;cất R17 ;lấy 4 bit thấp chuyển thành cao
ANDI R17, $F0 ;lấy 4 bit cao OR R17, R16 ;ghép bit RS
OR R17, R16 ;ghép bit RS RCALL OUT_LCD4 ;ghi ra LCD
RCALL OUT_LCD4 ;ghi ra LCD RET
Chương trình con OUT_LCD4_2 tách byte mã lệnh/data ra 2 nhóm 4 bit, mỗi nhóm 4 bit được đưa lên trọng
số cao và ghép với 3 bit điều khiển E, RW, RS ở trọng số thấp, xuất lần lượt ra port, với nhóm 4 bit cao xuất
trước. (giữa 2 lần xuất delay 100μs). Trước khi gọi ctcon này; phải cho RW=0, và RS=0 nếu ghi byte mã
lệnh hoặc RS=1 nếu ghi byte data ký tự hiển thị ra LCD.
* Chương 6: Giao tiếp ngoại vi - 39 - Nguyễn Trọng Luật *

You might also like