Professional Documents
Culture Documents
2 LAB3-4 PREPARE Moi
2 LAB3-4 PREPARE Moi
2 LAB3-4 PREPARE Moi
LCD 16x2
Phần lớn các module LCD sử dụng giao tiếp 16 chân trong đó có:
- 8 đường dữ liệu
- 3 đường điều khiển
- 3 đường cấp nguồn cho module
- 2 đường cấp nguồn cho LED nền trên LCD
Châ Tên Mô tả chức năng
n
1 VSS GND.
2 VDD +5 Volt.
3 VEE Tương phản (contrast): dùng để điều chỉnh độ tương phản
giữ các chữ cái và đèn nền trong LCD. Chân này sẽ được
nối vào một mạch chia áp dùng biến trở để dễ dàng thay đổi
độ tương phản khi vặn biến trở.
4 RS Chọn thanh ghi (Register Select): chọn thanh ghi trong
LCD để giao tiếp.
5 R/W Đọc/ghi (Read/Write): Chọn chế độ đọc hoặc ghi vào LCD.
Trong kit thí nghiệm VXL, sinh viên chỉ thực hiện chế độ
ghi vào LCD nên chân này được nối đất.
Ghi chú: đối với các tín hiệu có kí hiệu bởi dấu ‘/’ thì ta
hiểu phần bên trái dấu ‘/’ tương ứng với bit 1, phần bên
phải dấu ‘/’ tương ứng với bit 0.
6 E Cho phép (Enable): cho phép dữ liệu đọc/ghi trên LCD. Sau
khi thiết lập các tín hiệu cần vào LCD (từ các chân RS,
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
R/W, dữ liệu [0-7]) thì chân này kích cạnh xuống để thực
hiện lệnh.
7 D0 Bit 0 của dữ liệu
8 D1 Bit 1 của dữ liệu
9 D2 Bit 2 của dữ liệu
10 D3 Bit 3 của dữ liệu
11 D4 Bit 4 của dữ liệu
12 D5 Bit 5 của dữ liệu
13 D6 Bit 6 của dữ liệu
14 D7 Bit 7 của dữ liệu
15 LED+ Cấp nguồn + cho đèn LED nền trên LCD
16 LED- Cấp nguồn – cho đèn LED nền trên LCD
Trong bo mạch thí nghiệm vi xử lý, phần giao tiếp LCD được thiết kế theo giao tiếp 3
bus tương tự như khi thiết kế LED 7 đoạn hay LED ma trận, với địa chỉ chốt là 6000H-
7FFFH.
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Về lập trình ta nên chia mã lệnh ghi vào LCD thành 2 loại: ghi lệnh và ghi ký tự, ứng
với chân RS = 0 và RS = 1. Ghi lệnh (khi RS =0): là các lệnh cấu hình LCD, thiết lập con
trỏ tắt hoặc bật, nhấp nháy hay không… Ghi ký tự (khi RS =1): là ghi/ đọc ký tự từ RAM
trên LCD. Các chương trình con xuất lệnh và ký tự vào LCD được trình bày phía dưới.
Trong đó LCDADDR cần được định nghĩa là địa chỉ chốt LCD trước khi dùng, các chân
LCD_E và LCD_RS cần gán đúng với sơ đồ thiết kế.
Chương trình con xuất lệnh LCD:
WRITECOM:
MOV DPTR, #LCDADDR
SETB LCD_E
CLR LCD_RS
MOVX @DPTR, A
CLR LCD_E
ACALL WAIT_LCD
RET
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Chương trình con xuất ký tự LCD
WRITETEXT:
MOV DPTR, #LCDADDR
SETB LCD_E
SETB LCD_RS
MOVX @DPTR, A
CLR LCD_E
ACALL WAIT_LCD
RET
Để sử dụng việc ghi lệnh ta thực hiện gán A là mã lệnh mong muốn, sau đó gọi hàm
con ghi lệnh là được.
MOV A, (mã lệnh mong muốn)
ACALL WRITECOM
Ví dụ: Trước khi hiển thị LCD phải có một đoạn lệnh để cấu hình cho LCD như sau:
INIT_LCD:
MOV A, #38H
ACALL WRITECOM
MOV A, #0EH
ACALL WRITECOM
MOV A, #06H
ACALL WRITECOM
RET
Mã lệnh là 38H = 0011 1000B đây chính là lệnh bắt đầu với DB5 =1, khi dùng ghi
lệnh thì RS = 0, ta tra bảng, gióng xuống tìm DB5 = 1. Đây là câu lệnh Function set, với
DL = 1, N =1 và F =0. Tức là giao tiếp 8 bits, số lượng dòng là 2, kích thước ký tự là 5x8.
Ghi chú: đối với các tín hiệu có kí hiệu bởi dấu ‘/’ thì ta hiểu phần bên trái dấu ‘/’
tương ứng với bit 1, phần bên phải dấu ‘/’ tương ứng với bit 0.
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Tương tự với mã lệnh 0EH = 0000 1110B. Tức D = 1, C =1, B =0 có nghĩa là: cho
phép hiển thị, cho phép bật con trỏ, không cho con trỏ nhấp nháy.
Về phần ghi ký tự cũng tương tự. Gán mã ký tự mong muốn vào A rồi gọi hàm
WRITETEXT.
MOV A, (mã ký tự mong muốn)
ACALL WRITETEXT
Ví dụ ghi ký tự V ra LCD.
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
MOV A,#‘V’
ACALL WRITETEXT
Sau khi thực hiện lệnh ghi ký tự, mã ký tự sẽ được ghi vào ô DDRAM hiện hành. Nếu
địa chỉ DDRAM hiện hành thuộc khoản 00H-0FH hoặc 40H-4FH thì trên LCD sẽ hiển
thị ký tự tương ứng vào ô đó, đồng thời sau đó địa chỉ DDRAM sẽ tự cộng thêm 1 và sẽ
ghi ký tự ở ô tiếp theo nếu dùng thêm lệnh ghi ký tự. Trường hợp ô ký tự hiện hành là 0F
(tức ô cuối cùng của hàng 1), sau khi ghi lệnh ghi ký tự ra ô này, DDRAM sẽ được cộng
lên 1 là 10H chứ không phải là 40H, nghĩa là ký tự sẽ không tự động nhảy xuống hàng
dưới. Để xuống hàng hoặc ghi vào ô ký tự cụ thể nào ta cần phải sử dụng thêm lệnh chọn
địa chỉ DDRAM như sau, mã lệnh này được tính là 80H+địa chỉ DDRAM cần nhảy đến.
Ví dụ muốn ghi chữ VXL lên LCD tại vị trí sau thì công việc cần làm là: gọi lệnh chọn
địa chỉ DDRAM tại ô 46H, mã lệnh của lệnh này sẽ là 80H + 46H = C6H. Tiếp đó ghi
các ký tự ‘V’, ‘X’, ‘L’.
MOV A, #C6H
ACALL WRITECOM
MOV A,#‘V’
ACALL WRITETEXT
MOV A,#‘X’
ACALL WRITETEXT
MOV A,#‘L’
ACALL WRITETEXT
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Gợi ý: Để thực hiện xóa màn hình LCD, dùng lệnh có mã lệnh 01H. Để di chuyển con trỏ đến
tọa độ X (0 hoặc 1 ứng với hàng), Y (0 đến 15 ứng với cột) của màn hình LCD ta thực hiện lệnh
gán địa chỉ DDRAM như đã trình bày. Về việc canh giữa, sinh viên đếm số ký tự trong chuỗi từ
đó tính ra cần viết chuỗi tại vị trí cột bao nhiêu. Sinh viên có thể tham khảo đoạn chương trình
gợi ý sau.
LCD_E BIT P3.3
LCD_RS BIT P3.5
LCDADDREQU 6000H
ORG 2000H
MAIN:
MOV @R0, 30H
MOV DPTR, #LCDADDR
ACALL CLEAR
ACALL INIT_LCD
CLR F0
ACALL DISPLAYSTRING
SETB F0
ACALL DISPLAYSTRING
SJMP $
INIT_LCD: ;…………
CLEAR: ;…………
WRITECOM: ;…………
WRITETEXT: ;…………
WAIT_LCD: ;…………
DISPLAYSTRING:
ACALL COUNT
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
;…? ;R0 = 1 (khi F0 =0), R0 = 2 (khi F0=1)
ACALL GOTOXY
MOV A,#0
LOOP:
;…? ;DPTR = địa chỉ nhãn TEN (khi F0=0) hoặc NHOM
(F0=1) MOV R0,A
MOVC A,@A+DPTR
JZ EXIT
ACALL WRITETEXT
MOV A,R0
INC A
SJMP LOOP
EXIT: RET
GOTOXY: ; Chương trình gán địa chỉ DDRAM ứng với tọa độ XY
MOV A,#0C0H
;….? ;A = A+0x00 khi R0 = 1, A= A+0x40 khi R0 = 2.
;….? ;A = A + R1
ACALL WRITECOM
RET
COUNT: ;Tính vị trí bắt đầu của chuỗi TEN (Khi F0=0)
; và NHOM (F0=1) lưu vào trong R1
MOV R1,#0
;…? ;DPTR = địa chỉ nhãn TEN (khi F0=0) hoặc NHOM
(F0=1)
;…? ; Đếm số ký tự trong chuỗi cho đến khi gặp giá trị 0 và
; lưu vào R1
;…? ; Tính toán và trả về R1 = (16 – R1)/2 (lấy phần
nguyên)
RET
TEN: DB 'VO THI SAU',0
NHOM: DB 'NHOM 1',0
END
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Hướng dẫn thí nghiệm 3.3
“Viết chương trình hiển thị lên dòng thứ 1 và canh giữa tên của thành viên thứ nhất trong
nhóm.
Sau đó 1s, xóa dòng 1 và hiển thị lên dòng thứ 2 và canh giữa tên thành viên thứ hai của nhóm.
Tiếp tục sau đó 1s, xóa dòng 2 và hiển thị đồng thời tên hai thành viên ở hai dòng.”
Công thức chung đoạn mã ngõ ra là một số nguyên 8 bit như sau:
A=256∗Vin−¿ ¿
Với REF+ là 5V là REF- là 0V, ta suy ra điện áp vào bộ ADC là
5∗A
Vin= (V )
256
Hướng dẫn thí nghiệm 3.4
“Viết chương trình con READADC thực hiện đọc giá trị của kênh 0 và trả về giá trị
trong R0. Viết chương trình hiển thị giá trị của kênh 0 của ADC lên LCD dùng chương
trình con READADC đã viết.”
LCD_E BIT P3.3
LCD_RS BIT P3.5
LCDADDREQU 6000H
ADCADDR EQU 4000H
ORG 0
MAIN:
CALL READADC
PUSH 0
MOV DPTR, #LCDADDR
CALL CLEAR
CALL INIT_LCD
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
CALL DISPLAYSTRING
POP ACC
;….? ;Đoạn chương trình hiển thị số trong thanh ghi A theo hệ 10
;lên LCD.
SJMP $
READADC:
MOV DPTR,#ADCADDR ;Start ADC
MOV A,#0
MOVX @DPTR,A
CALL WAIT_LCD ;EOC
MOVX A,@DPTR ;OE
MOV R0,A
MOV P1,A ;Hiển thị A lên các LED tại port 1 để quan sát
RET
INIT_LCD: ;………
CLEAR: ;………
WRITECOM: ;………
WRITETEXT: ;………
WAIT_LCD: ;………
DISPLAYSTRING:
MOV A,#0
LOOP:
MOV DPTR, #MESSAGE
MOV R0,A
MOVC A,@A+DPTR
JZ EXIT
ACALL WRITETEXT
MOV A,R0
INC A
SJMP LOOP
EXIT:
RET
Gợi ý: Bài này thực hiện tương tự như thí nghiệm 3.4, thay vì hiển thị giá trị thanh ghi A theo
hệ 10 lên LCD ta phải tính toán giá trị điện áp vào của bộ ADC dựa trên giá trị trên thanh ghi A
theo công thức:
5∗A
Vin= (V )
256
Lệnh nhân hai số 8 bit A, B là MUL AB có kết quả là một số 16 bit BA = A * B, trong đó 8
bit trọng số cao sẽ được lưu trong B, 8 bit trọng số thấp sẽ được lưu trong A. Phép chia cho 256
tương ứng với phép dịch trái 8 bit.
Về thuật toán thực hiện biểu thức Vin trên, ta có thể làm như sau: Thực hiện phép nhân 5*A
trước, kết quả trả về B sẽ chứa trọng số cao, A sẽ chứa trọng số thấp. Sau đó hình dung phép chia
cho 256 là phép dịch trái dấu chấm thập phân, dịch qua 8 bit. Khi đó B sẽ chính là phần nguyên
của biểu thức Vin, A sẽ là phần thập phân của biểu thức Vin.
Ví dụ:
5∗100 500
Vin= ( V )= =1.953125 (V )
256 256
A = 100
B=5
MUL AB = BA = A*B = 500 = 1 1111 0100
BA/256 = 1 . 1111 0100
Phần nguyên: 1*20= 1 (Được chứa trong B)
Phần thập phân: 1*2-1+1*2-2+1*2-3+1*2-4+1*2-6 = 0.953125 (Được chứa trong A, chú ý là
A = 11110100 là một số nguyên, nhưng ý nghĩa ở đây ta đang xét trong ứng dụng thực hiện
phép chia cho 256 là số thập phân 0.11110100)
Để xử lý phần thập phân của biểu thức Vin chứa trong A, ta tiếp tục lấy A*10 và sẽ có
một chữ số tràn qua B, đó chính là số thứ nhất sau dấu chấm thập phân. Tiếp tục thực
hiện A*10, ta được số thứ 2 sau dấu chấm thập phân.
Ví dụ: Sau khi thực hiện MUL AB như ví dụ trên, B là 1, A chứa 1111 0100 = 244.
Chú ý là ta cần lấy phần thập phân 0.953125 tức là 0.11110100.
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Gán B = 10
MUL AB = BA = A*B = 1001.1000 1000 (Chỗ này bấm máy tính 244*10=2440 =
1001 1000 1000 rồi đặt dấu chấm thập phân đúng chỗ).
Phần nguyên: 1001 = 9 (Được chứa trong B)
Phần thập phân: 1*2-1+1*2-5 = 0.53125 (Được chứa trong A)
Thực hiện tương tự để lấy chữ số thập phân thứ 2 sau dấu chấm. Thuật toán đã được
hướng dẫn xong, sinh viên tự thực hiện việc viết code.
3. Giao tiếp TIMER
Trong bài thí nghiệm đầu tiên, vòng lặp lệnh được dùng để tiêu hao thời gian của vi
điều
khiển. Tuy nhiên, cách sử dụng vòng lặp lệnh đòi hỏi nhiều công sức tinh chỉnh để có
được độ trễ chính xác. Mặt khác, khi sử dụng vòng lặp lệnh sẽ tiêu tốn thời gian hoạt
động của CPU. Để tạo ra các khoảng thời gian chính xác người ta thường dùng ngoại vi
timer.
Timer (bộ định thì) thường được dùng để đo khoảng thời gian. Thực chất Timer là một
bộ đếm với xung đếm có tần số cố định và biết trước. Khi xác định được số xung đếm và
biết chu kỳ của xung thì có thể tính được thời gian. Timer của 8051 có thể hoạt động ở
chế độ 8-bit hoặc 16-bit. Tùy theo số xung đếm cần nhiều hay ít mà có thể cấu hình
Timer ở chế độ tương ứng.
Timer là ngoại vi on-chip của 8051, để cấu hình và điều khiển ngoại vi này, người lập
trình truy xuất vào các thanh ghi tương ứng trong vùng SFR (địa chỉ 80h đến FFh). Đối
với Timer đó là các thanh ghi TMOD, THx, TLx, TCON. Trong đó, THx và TLx chứa
giá trị hiện thời của bộ đếm xung. Ví dụ, để cấu hình Timer0 hoạt động ở chế độ 8-bit
MOV TMOD, #02h
Để khởi tạo giá trị đầu cho Timer0
MOV TH0, #HIGH(-50000) ; giá trị khởi động là -50000
MOV TL0, #LOW(-50000)
Để chờ hết khoảng thời gian đã định trước, người lập trình có thể quan sát cờ TFx. Cờ
này sẽ lên 1 mỗi khi Timerx bị tràn, tức là giá trị bộ đếm xung quay trở lại giá trị 0 (zero)
JNB TF0, $ ; chờ Timer0 tràn sau 50000 chu kỳ máy
Nếu timer hoạt động ở chế độ 16 bit, sau khi timer tràn ta phải nạp lại giá trị đầu cho
timer.
Khi Timer chạy ở chế độ 2, thanh ghi đếm TLx sẽ được tự nạp lại khi timer tràn, vì
vậy chương trình không cần dừng timer để nạp lại giá trị đầu .
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.
Ví dụ, để cấu hình Timer0 hoạt động ở chế độ 8-bit:
MOV TMOD, #02h
Để khởi tạo giá trị đầu cho Timer0
MOV TH0, #(-50) ; giá trị khởi động là -50
MOV TL0, #(-50)
Để khởi động timer, set cờ TR
SETB TR0
Để chờ hết khoảng thời gian đã định trước, người lập trình có thể quan sát cờ TFx. Cờ
này sẽ lên 1 mỗi khi Timerx bị tràn, tức là giá trị bộ đếm xung quay trở lại giá trị 0 (zero)
JNB TF0, $ ; chờ Timer0 tràn sau 50000 chu kỳ máy
Để tạo xung tuần hoàn, ta chỉ cần đảo chân port và xóa cờ tràn TF. Lưu ý là timer chạy
độc lập với CPU, có nghĩa là trong khi CPU đang thực thi câu lệnh, timer vẫn chạy
Xung có thể được tạo ra như sau:
LOOP:
JNB TF0,$
CPL P1.0
CLR TF0
SJMP LOOP
Giải thuật chống rung nút nhấn: Cho kiểm tra trạng thái nút nhấn mỗi một đoạn thời
gian (tần số chống rung), có thể dùng delay vòng lập hoặc timer. Khi phát hiện nút nhấn
được nhấn hãy tăng biến đếm lên 1, khi không nhấn, reset biến đếm về 0. Khi biến đếm
này vượt qua một ngưỡng cho trước (số lần đọc) thì mới xác định là nút nhấn đã nhấn, từ
đó mới xử lý chương trình nhấn nút.
Dựa theo gợi ý giải thuật đưa ra, sinh viên tự viết chương trình.
BÀI CHUẨN BỊ THÍ NGHIỆM 3-4
LẬP TRÌNH GIAO TIẾP LCD, ADC, TIMER.