0% found this document useful (0 votes)
204 views28 pages

VSL Kiet

báo cáo

Uploaded by

sadpoiz102
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
204 views28 pages

VSL Kiet

báo cáo

Uploaded by

sadpoiz102
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 28

BỘ NÔNG NGHIỆP & PHÁT TRIỂN NÔNG THÔN

TRƯỜNG ĐẠI HỌC THỦY LỢI


KHOA ĐIỆN – ĐIỆN TỬ
***

BÁO CÁO
THỰC HÀNH VI XỬ LÝ

Giảng viên hướng dẫn: TẠ THỊ CHINH


Sinh viên thực hiện: LƯU NGỌC LÂM
Mã sinh viên: 2151210695
Lớp: 63TĐH.NB

Hà Nội, 11/2023
MỤC LỤC

MỤC LỤC..................................................................................................................................................1
1. BÀI TẬP THỰC HÀNH BUỔI 1+2.................................................................................................3
Bài 2.1: Viết chương trình xuất số AB ra led đơn trên cổng P1 (AB = 95)........................................3
Bài 2.2: Đọc tín hiệu từ nút nhấn tại cổng P0.0. Mỗi khi nhấn nút thì cổng P0.1 điều khiển led
đơn nhấp nháy AB lần (AB = 95).........................................................................................................3
Bài 2.3: Mỗi khi nhấn nút nối với cổng P0.0, vi điều khiển điều khiển cổng P1 hiển thị 8 led đơn
thể hiện đếm từ 0 đến số AB (AB = 95)................................................................................................3
Bài 3.1: Viết chương trình điều khiển 4 led 7 thanh hiển thị số ABCDEF. Mã số sinh viên :
2151210695 -> ABCDEF = 210695.......................................................................................................4
Bài 4.1: Viết chương trình dùng bộ ngắt định thời 0 để tạo xung vuông tuần hoàn có tần số f =
2kHZ tại P0.0. Biết rằng vi điều khiển sử dụng thạch anh 12MHz...................................................5
Bài 4.2: Dùng bộ ngắt định thời 0 và 1 để tạo đồng thời 2 xung vuông tuần hoàn có tần số lần lượt
là 1kHz và 100Hz tại chân P1.0 và P1.1 khi 8051 sử dụng thạch anh 12MHz..................................6
Bài 4.3: Viết chương trình phát một chuỗi ký tự là tên sinh viên qua cổng truyền thông nối tiếp ở
chế độ UART..........................................................................................................................................7
Bài 4.4: Viết chương trình tùy chọn 1 xung âm tại chân P3.2. Khi xuất hiện xung thì gửi 1 ký tự
@ ra cổng truyền thông nối tiếp ở chế độ UART 8bit, tốc độ baud 9600. Vi điều khiển dùng thạch
anh 12MHz.............................................................................................................................................8
2. BÀI TẬP THỰC HÀNH BUỔI 3.....................................................................................................8
Bài 2.1: Viết chương trình xuất chuỗi “TEN MSSV AB” ra module LCD (AB = 95)......................8
Bài 2.2: Đọc tín hiệu từ nút nhất T1 – T8 (Port 3) và hiện chuỗi “Nut nhan T1” (Ví dụ nút T1
tương ứng với P3.0) được ấn tương ứng............................................................................................10
Bài 3.1: Viết chương trình hiển thị nhiệt độ (số nguyên – VD: 29 độ) ra module LED 7 thanh....11
Bài 3.2: Viết chương trình hiển thị nhiệt độ (số nguyên – VD: 30 độ) ra module LCD..................12
Bài 4.1: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…) trên LED 7 thanh...14
Bài 4.2: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…) trên LCD................15
3. BÀI TẬP THỰC HÀNH BUỔI 4...................................................................................................16
Bài 2.1: Viết chương trình xuất cho LED nối với chân PINA của mạch Arduino nhấp nháy AB
lần. Độ trễ giữa ON và OFF là AB0ms (AB = 95).............................................................................16
Bài 2.2: Đọc tín hiệu từ nút nhấn tại chân PIN0. Mỗi khi nhấn nút thì chân PIN1 điều khiển LED
đơn nhấp nháy AB lần, độ trễ giữa ON và OFF là 500ms (AB = 95)...............................................16
Bài 2.3: Mỗi khi nhấn nút nối với PIN0, vi điều khiển điều khiển cổng PIN1-PIN8 hiển thị 8 LED
đơn thể hiện đếm từ 0 đến 8................................................................................................................17

1
Bài 3.1: Viết chương trình điều khiển 6 LED 7 thanh hiển thị số ABCDEF (2151210695 =>
ABCDEF = 210695).............................................................................................................................18
Bài 4.1: Viết chương trình tạo xung PWM có tần số 2kHz có độ rộng xung là 50%......................21
Bài 4.2: Viết chương trình phát một chuỗi kí tự là tên sinh viên qua cổng truyền thông nối tiếp ở
chế độ UART 8 bit, tốc độ baud 9600.................................................................................................22
Bài 4.3: Viết chương trình chờ nhận 1 xung âm tại chân PIN0. Khi xuất hiện xung thì gửi 1 ký tự
@ ra cổng truyền thông nối tiếp ở chế độ UART 8 bit, tốc độ baud 9600.......................................22
4. BÀI TẬP THỰC HÀNH BUỔI 5...................................................................................................22
Bài 2.1: Viết chương trình xuất chuỗi “TEN MSSV AB” ra module LCD (AB = 95)....................23
Bài 2.2: Đọc tín hiệu từ nút nhấn T1-T8 (Port 3) và hiện chuỗi “ Nut nhan T1” (Ví dụ nút T1
tương ứng P3.0) được ấn tương ứng trên LCD theo chuẩn kết nối LCD 4bit và giao tiếp I2C)....23
Bài 3.1: Viết chương trình hiển thị nhiệt độ (Số nguyên – VD: 29 độ) ra module LED 7 thanh.. .24
Bài 3.2: Viết chương trình hiển thị nhiệt độ (số thập phân chính xác 1 chữ số sau dấu phẩy – VD:
29,5 độ) ra module LCD (sử dụng giao tiếp I2C)..............................................................................25
Bài 4.1: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…) trên LED 7 thanh và
lặp lại....................................................................................................................................................25
Bài 4.2: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…) trên LCD................26

2
1. BÀI TẬP THỰC HÀNH BUỔI 1+2
Bài 2.1: Viết chương trình xuất số AB ra led đơn trên cổng P1 (AB = 95).
ORG 0000H
LOOP:
MOV P1,#95D
JMP LOOP
END

Bài 2.2: Đọc tín hiệu từ nút nhấn tại cổng P0.0. Mỗi khi nhấn nút thì cổng
P0.1 điều khiển led đơn nhấp nháy AB lần (AB = 95).
org 0000H
NUT: MOV P0, #11111111b
JB P0.0, NUT
main:
Mov R0,#0D
LOOP:
cpl p0.1
inc R0
CJNE R0,#80d, LOOP
JMP NUT
END

Bài 2.3: Mỗi khi nhấn nút nối với cổng P0.0, vi điều khiển điều khiển cổng
P1 hiển thị 8 led đơn thể hiện đếm từ 0 đến số AB (AB = 95).
ORG 0000H
NUT:
MOV P0,#11111111B
JB P0.0,NUT
MOV R1,#0D
LOOP:
MOV P1,R1
INC R1
CJNE R1,#40D,LOOP
JMP NUT
END

3
Bài 3.1: Viết chương trình điều khiển 4 led 7 thanh hiển thị số ABCDEF.
Mã số sinh viên : 2151210695 -> ABCDEF = 21.
a. Ngôn ngữ ASSEMBLY

ORG 000H
START:
Mov R0, #04H
Mov R1, #00H
Mov R6, #0EEH
LABEL:
Mov A, R1
Mov DPTR, #Zezo
Movc A, @A+DPTR
Mov P0, A
Mov P2, R6
Mov A, R6
RL A ;;;; CHUYỂN SANG TRÁI 1 ĐƠN VỊ
Mov R6, A
Mov P2, #0FFH
INC R1DEC R0 ;;;;;;giảm giá trị dữ liệu trên thanh ghi R0 xuống 1 đơn vị
Mov A, R0
JZ START ;;;;;;;;;;;;;;;;;;;;;Lệnh JZ (nhảy nếu A = 0)
Zezo: DB 0x5b, 0x06, 0x66, 0x5b, 0x66, 0x3f
RET
END

b. Ngôn ngữ C
#include <at89x52.h>
unsigned char Delay(unsigned long a);
unsigned char Mask(int a);
void main(void)
{
int i;

while(1)
{
P1=0x01;
for (i=0;i<10;i++){
P0=Mask(i);

4
Delay(6000);
}
};
}
unsigned char Delay (unsigned long a)
{
unsigned long b;
for(b=0;b<a;b++){};
return 1;
}
unsigned char Mask(int a)
{
switch (a){
case 2 : return 0x5b;
case 1 : return 0x06;
case 0 : return 0x3F;
case 6 : return 0x7D;
case 9 : return 0x6F;
case 5 : return 0x6D;
default: return 0;
}
}

Bài 4.1: Viết chương trình dùng bộ ngắt định thời 0 để tạo xung vuông
tuần hoàn có tần số f = 2kHZ tại P0.0. Biết rằng vi điều khiển sử dụng
thạch anh 12MHz.
ORG 0H ; Địa chỉ bắt đầu chương trình
SETUP_TIMER:
MOV TMOD, #01H ; Chế độ 16-bit cho bộ định thời 0
MOV TH0, #0FDH ; Giá trị tự định nghĩa Reload (TH0) sau tính toán
MOV TL0, #0FDH ; Giá trị ban đầu cho bộ định thời 0

MOV TCON, #10H ; Bật bộ định thời 0

MAIN_LOOP:
; Chỗ này có thể thêm các lệnh xử lý khác
SJMP MAIN_LOOP ; Lặp vô hạn

TIMER_INTERRUPT:

5
; Xử lý ngắt bộ định thời 0
; Bạn có thể thực hiện các hành động cần thiết khi xảy ra ngắt

RETI ; Trở về chương trình chính sau khi xử lý ngắt


END
Bài 4.2: Dùng bộ ngắt định thời 0 và 1 để tạo đồng thời 2 xung vuông tuần
hoàn có tần số lần lượt là 1kHz và 100Hz tại chân P1.0 và P1.1 khi 8051 sử
dụng thạch anh 12MHz.
ORG 0H ; Địa chỉ bắt đầu chương trình
SETUP_TIMERS:
MOV TMOD, #11H ; Chế độ 16-bit cho bộ định thời 0 và 1

; Tính toán và cấu hình TH0 cho xung vuông 1kHz tại P1.0
MOV TH0, #0EC4H ; Tần số 1kHz
MOV TL0, #0EC4H

; Tính toán và cấu hình TH1 cho xung vuông 100Hz tại P1.1
MOV TH1, #7A12H ; Tần số 100Hz
MOV TL1, #7A12H

MOV TCON, #55H ; Bật bộ định thời 0 và 1, cài đặt chế độ ngắt

SETB P1.0 ; Đặt chân P1.0 lên mức logic 1


SETB P1.1 ; Đặt chân P1.1 lên mức logic 1

MAIN_LOOP:
; Chỗ này có thể thêm các lệnh xử lý khác
SJMP MAIN_LOOP ; Lặp vô hạn

TIMER0_INTERRUPT:
CLR P1.0 ; Đặt chân P1.0 xuống mức logic 0

; Xử lý ngắt bộ định thời 0


; Bạn có thể thực hiện các hành động cần thiết khi xảy ra ngắt

RETI ; Trở về chương trình chính sau khi xử lý ngắt

TIMER1_INTERRUPT:
CLR P1.1 ; Đặt chân P1.1 xuống mức logic 0

6
; Xử lý ngắt bộ định thời 1
; Bạn có thể thực hiện các hành động cần thiết khi xảy ra ngắt

RETI ; Trở về chương trình chính sau khi xử lý ngắt


END
Bài 4.3: Viết chương trình phát một chuỗi ký tự là tên sinh viên qua cổng
truyền thông nối tiếp ở chế độ UART.
Công thức tính giá trị TH1 khi biết tần số thạch anh (12MHz) và tốc độ
truyền thông (9600 baud) như sau:
TH1 = F_OSC32 * baud rate
Với baud rate là 9600, giá trị TH1 sẽ là:
TH1 = 12Mhz * 32 * 9600 = 32 * 9600 * 12MHz = 39
ORG 0H ; Địa chỉ bắt đầu chương trình

MOV TMOD, #20H ; Chế độ 8-bit cho UART


MOV TH1, #39H ; Cấu hình TH1 cho tốc độ 9600 baud
MOV TL1, #39H ; Tương ứng với TH1
SETB TR1 ; Bật bộ định thời 1

SETB TI ; Đặt cờ truyền UART lên mức logic 1

MAIN:
MOV SBUF, #'M' ; Gửi kí tự 'T' qua UART
ACALL DELAY ; Hàm đợi để đảm bảo việc gửi hoàn tất
; Tương tự, gửi các kí tự khác trong chuỗi tên sinh viên
MOV SBUF, #'I'
ACALL DELAY
MOV SBUF, #'N'
ACALL DELAY
MOV SBUF, #'H'
ACALL DELAY
; ... Gửi các kí tự còn lại trong chuỗi tên sinh viên

END_LOOP:
SJMP END_LOOP ; Lặp vô hạn

DELAY:
; Hàm đợi để đảm bảo việc gửi hoàn tất
; Bạn cần điều chỉnh hàm này tùy thuộc vào tốc độ gửi và cần thiết

7
NOP
RET
END

Bài 4.4: Viết chương trình tùy chọn 1 xung âm tại chân P3.2. Khi xuất
hiện xung thì gửi 1 ký tự @ ra cổng truyền thông nối tiếp ở chế độ UART
8bit, tốc độ baud 9600. Vi điều khiển dùng thạch anh 12MHz.
ORG 0H ; Địa chỉ bắt đầu chương trình

MOV TMOD, #20H ; Chế độ 8-bit cho UART


MOV TH1, #39H ; Cấu hình TH1 cho tốc độ 9600 baud
MOV TL1, #39H ; Tương ứng với TH1
SETB TR1 ; Bật bộ định thời 1

SETB EA ; Bật ngắt toàn cục


SETB EX1 ; Bật ngắt ngoại vi 1 (cho P3.2)

MAIN:
SJMP MAIN ; Lặp vô hạn, chờ nhận xung tại P3.2

; Xử lý ngắt ngoại vi 1 (P3.2)


EXTERNAL_INT1:
MOV SBUF, #'@' ; Gửi ký tự "@" qua UART khi nhận được xung
SETB TI ; Đặt cờ truyền UART lên mức logic 1 để gửi ký tự

; Xử lý ngắt ngoại vi khác nếu cần thiết

RETI ; Trở về chương trình chính sau khi xử lý ngắt


END

2. BÀI TẬP THỰC HÀNH BUỔI 3


Bài 2.1: Viết chương trình xuất chuỗi “TEN MSSV AB” ra module LCD
(AB = 95).
ORG 0H ; Địa chỉ bắt đầu của chương trình

START: ; Nhãn cho vùng bắt đầu chương trình


MOV P1, #00H ; Xóa thanh ghi P1
CALL INIT_LCD ; Khởi tạo LCD

MOV DPTR, #Message ; Chuyển địa chỉ của chuỗi "TEN MSSV 95" vào thanh
ghi DPTR

8
CALL DISPLAY_MESSAGE ; Hiển thị chuỗi lên LCD

END_LOOP: ; Nhãn cho vòng lặp cuối cùng


SJMP END_LOOP ; Lặp vô hạn

INIT_LCD: ; Khởi tạo LCD


MOV A, #38H ; Chế độ 2 dòng, 5x7 pixels
CALL COMMAND ; Gửi lệnh khởi tạo LCD
MOV A, #0EH ; Hiển thị bật, con trỏ nhấp nháy
CALL COMMAND ; Gửi lệnh khởi tạo LCD
MOV A, #01H ; Xóa màn hình
CALL COMMAND ; Gửi lệnh khởi tạo LCD
MOV A, #06H ; Di chuyển con trỏ sang phải sau mỗi ký tự
CALL COMMAND ; Gửi lệnh khởi tạo LCD
RET

COMMAND: ; Gửi lệnh điều khiển LCD


MOV P1, A ; Gửi lệnh điều khiển ra LCD
CLR P3.5 ; Giao diện 4 bit: Xóa bit thấp của P3.5
SETB P3.6 ; Giao diện 4 bit: Đặt bit cao của P3.6
CLR P3.7 ; Giao diện 4 bit: Xóa bit cao của P3.7
SETB P3.4 ; Gửi lệnh điều khiển ra LCD
CLR P3.4 ; Kết thúc lệnh
MOV A, P1 ; Dịch 4 bit tiếp theo
ANL A, #0F0H ; Lấy 4 bit cao của thanh ghi A
MOV P1, A ; Gửi lệnh điều khiển ra LCD
SETB P3.4 ; Gửi lệnh điều khiển ra LCD
CLR P3.4 ; Kết thúc lệnh
RET

DISPLAY_CHAR: ; Hiển thị một ký tự lên LCD


MOV P1, A ; Gửi dữ liệu ra LCD
SETB P3.5 ; Đặt chế độ ghi dữ liệu
SETB P3.6 ; Giao diện 4 bit: Đặt bit cao của P3.6
CLR P3.7 ; Giao diện 4 bit: Xóa bit cao của P3.7
SETB P3.4 ; Gửi dữ liệu ra LCD
CLR P3.4 ; Kết thúc lệnh
MOV A, P1 ; Dịch 4 bit tiếp theo
ANL A, #0F0H ; Lấy 4 bit cao của thanh ghi A
MOV P1, A ; Gửi dữ liệu ra LCD
SETB P3.4 ; Gửi dữ liệu ra LCD
CLR P3.4 ; Kết thúc lệnh
RET

9
DISPLAY_MESSAGE: ; Hiển thị chuỗi lên LCD
MOV R0, #0 ; Khởi tạo R0
DISPLAY_LOOP:
MOV A, @DPTR ; Đọc ký tự từ vùng nhớ được chỉ định bởi DPTR
CJNE A, #'9', SKIP_NUM ; Nếu không phải là số, bỏ qua lệnh chuyển ký tự số
về mã ASCII
ADD A, #48 ; Chuyển ký tự số về mã ASCII
SKIP_NUM:
CALL DISPLAY_CHAR ; Gọi hàm để hiển thị ký tự lên LCD
INC DPTR ; Di chuyển đến ký tự tiếp theo
INC R0 ; Tăng giá trị R0
MOV A, R0
CJNE A, #11, DISPLAY_LOOP ; Lặp lại cho đến khi hiển thị hết chuỗi
RET

Message: ; Chuỗi "TEN MSSV 40"


DB "TEN MSSV 95", 0 ; Chú ý dấu kết thúc chuỗi (\0)

END ; Kết thúc chương trình

Bài 2.2: Đọc tín hiệu từ nút nhất T1 – T8 (Port 3) và hiện chuỗi “Nut nhan
T1” (Ví dụ nút T1 tương ứng với P3.0) được ấn tương ứng.
ORG 0H ; Địa chỉ bắt đầu của chương trình

MAIN: ; Nhãn cho vòng lặp chính


MOV A, P3 ; Đọc dữ liệu từ Port 3 (P3) vào thanh ghi A

ANL A, #01H ; Kiểm tra bit thấp nhất của thanh ghi A (nút T1 - P3.0)
JZ T1_Pressed ; Nếu bit này bằng 0, nút T1 được nhấn

ANL A, #02H ; Kiểm tra bit thứ 2 của thanh ghi A (nút T2 - P3.1)
JZ T2_Pressed ; Nếu bit này bằng 0, nút T2 được nhấn

; Tương tự cho các nút còn lại (T3 đến T8)

SJMP MAIN ; Quay lại vòng lặp chính

T1_Pressed:
MOV DPTR, #String_T1 ; Chuyển địa chỉ của chuỗi "Nút nhấn T1" vào
10
thanh ghi DPTR
CALL DisplayString ; Gọi hàm để hiển thị chuỗi
SJMP MAIN ; Quay lại vòng lặp chính

T2_Pressed:
; Xử lý khi nút T2 được nhấn
; Tương tự như trên

;...

DisplayString:
MOV A, @DPTR ; Đọc ký tự từ vùng nhớ được chỉ định bởi DPTR
JZ EndString ; Nếu ký tự là kết thúc chuỗi (\0), kết thúc hiển thị

; Hiển thị ký tự
; (Bạn cần thêm mã để hiển thị ký tự, ví dụ: xuất ra cổng nào đó hoặc hiển
thị trên màn hình)

INC DPTR ; Di chuyển đến ký tự tiếp theo


SJMP DisplayString ; Lặp lại quá trình hiển thị chuỗi

EndString:
RET ; Kết thúc hàm

String_T1: ; Chuỗi "Nút nhấn T1"


DB "Nút nhấn T1", 0 ; Chú ý dấu kết thúc chuỗi (\0)

END ; Kết thúc chương trình

Bài 3.1: Viết chương trình hiển thị nhiệt độ (số nguyên – VD: 29 độ) ra
module LED 7 thanh.
ORG 0H ; Địa chỉ bắt đầu của chương trình

START: ; Nhãn cho vùng bắt đầu chương trình


MOV P1, #00H ; Xóa thanh ghi P1

MOV R2, #29 ; Gán giá trị nhiệt độ (ví dụ: 29 độ) vào thanh ghi R2

MOV A, R2 ; Đặt giá trị nhiệt độ vào thanh ghi A

11
MOV R0, #10 ; Đặt R0 = 10
DIV AB ; Chia A cho B (10)

MOV B, A ; Kết quả của phép chia được lưu vào thanh ghi B
MOV A, R2 ; Đặt giá trị nhiệt độ vào thanh ghi A

ACALL DISPLAY_TENS_PLACE ; Hiển thị chữ số hàng chục của nhiệt


độ
MOV A, B ; Lưu kết quả của phép chia vào thanh ghi A để hiển thị hàng
đơn vị
ACALL DISPLAY_ONES_PLACE ; Hiển thị chữ số hàng đơn vị của
nhiệt độ

END_LOOP: ; Nhãn cho vòng lặp cuối cùng


SJMP END_LOOP ; Lặp vô hạn

DISPLAY_TENS_PLACE: ; Hiển thị chữ số hàng chục của nhiệt độ


MOV P1, A ; Gửi dữ liệu hàng chục ra LED 7 thanh (hoặc module hiển
thị)
; (Thêm mã điều khiển để chọn hàng cần hiển thị)
RET

DISPLAY_ONES_PLACE: ; Hiển thị chữ số hàng đơn vị của nhiệt độ


MOV P1, A ; Gửi dữ liệu hàng đơn vị ra LED 7 thanh (hoặc module hiển
thị)
; (Thêm mã điều khiển để chọn hàng cần hiển thị)
RET

END ; Kết thúc chương trình

Bài 3.2: Viết chương trình hiển thị nhiệt độ (số nguyên – VD: 30 độ) ra
module LCD.
ORG 0H ; Địa chỉ bắt đầu của chương trình

START: ; Nhãn cho vùng bắt đầu chương trình


MOV P1, #00H ; Xóa thanh ghi P1
CALL INIT_LCD ; Khởi tạo LCD

12
MOV DPTR, #TemperatureMsg ; Chuyển địa chỉ của chuỗi
"TEMPERATURE: " vào thanh ghi DPTR
CALL DISPLAY_MESSAGE ; Hiển thị chuỗi "TEMPERATURE: " lên
LCD

MOV A, #3 ; Gán giá trị nhiệt độ hàng chục (ví dụ: 30 độ)
ACALL DISPLAY_DIGIT ; Hiển thị chữ số hàng chục của nhiệt độ lên
LCD

MOV A, #0 ; Gán giá trị nhiệt độ hàng đơn vị


ACALL DISPLAY_DIGIT ; Hiển thị chữ số hàng đơn vị của nhiệt độ lên
LCD

END_LOOP: ; Nhãn cho vòng lặp cuối cùng


SJMP END_LOOP ; Lặp vô hạn

INIT_LCD: ; Khởi tạo LCD


; Thực hiện các bước khởi tạo LCD tại đây
; ...

DISPLAY_MESSAGE: ; Hiển thị chuỗi lên LCD


MOV R0, #0 ; Khởi tạo R0
DISPLAY_LOOP:
MOV A, @DPTR ; Đọc ký tự từ vùng nhớ được chỉ định bởi DPTR
CJNE A, #'0', DISPLAY_CHAR ; Nếu không phải là số, bỏ qua lệnh
chuyển ký tự số về mã ASCII
ADD A, #48 ; Chuyển ký tự số về mã ASCII
DISPLAY_CHAR:
CALL DISPLAY_TO_LCD ; Gọi hàm để hiển thị ký tự lên LCD
INC DPTR ; Di chuyển đến ký tự tiếp theo
INC R0 ; Tăng giá trị R0
MOV A, R0
CJNE A, #13, DISPLAY_LOOP ; Lặp lại cho đến khi hiển thị hết chuỗi
RET

DISPLAY_DIGIT: ; Hiển thị chữ số lên LCD


ADD A, #48 ; Chuyển ký tự số về mã ASCII
CALL DISPLAY_TO_LCD ; Gọi hàm để hiển thị ký tự lên LCD
RET

13
DISPLAY_TO_LCD: ; Hiển thị ký tự lên LCD
; Gửi ký tự đến LCD thông qua các chân kết nối
; (Thực hiện các lệnh cần thiết để gửi ký tự đến LCD)
RET

TemperatureMsg: ; Chuỗi "TEMPERATURE: "


DB "TEMPERATURE: ", 0 ; Chú ý dấu kết thúc chuỗi (\0)

END ; Kết thúc chương trình

Bài 4.1: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…)
trên LED 7 thanh.
ORG 0H ; Địa chỉ bắt đầu của chương trình

START: ; Nhãn cho vùng bắt đầu chương trình


MOV P1, #00H ; Xóa thanh ghi P1
CALL INIT_LED_DISPLAY ; Khởi tạo LED 7 thanh

MOV R2, #0 ; Khởi tạo R2 để đếm từ 0 đến 60

COUNT_LOOP:
MOV A, R2 ; Gán giá trị đếm vào thanh ghi A
CALL DISPLAY_LED ; Hiển thị giá trị đếm trên LED 7 thanh

INC R2 ; Tăng giá trị đếm


CJNE R2, #61, COUNT_LOOP ; Điều kiện lặp từ 0 đến 60 giây

END_LOOP: ; Nhãn cho vòng lặp cuối cùng


SJMP END_LOOP ; Lặp vô hạn

INIT_LED_DISPLAY: ; Khởi tạo LED 7 thanh


; Thực hiện các bước cần thiết để khởi tạo LED 7 thanh
; ...

DISPLAY_LED: ; Hiển thị giá trị đếm trên LED 7 thanh


MOV P1, A ; Gửi dữ liệu đếm ra LED 7 thanh
; (Thêm mã điều khiển để chọn hàng cần hiển thị)
RET

14
END ; Kết thúc chương trình

Bài 4.2: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…)
trên LCD.
ORG 0H ; Địa chỉ bắt đầu của chương trình

START: ; Nhãn cho vùng bắt đầu chương trình


MOV P1, #00H ; Xóa thanh ghi P1
CALL INIT_LCD ; Khởi tạo LCD

MOV R2, #0 ; Khởi tạo R2 để đếm từ 0 đến 60

COUNT_LOOP:
MOV A, R2 ; Gán giá trị đếm vào thanh ghi A
CALL DISPLAY_COUNT_LCD ; Hiển thị giá trị đếm trên LCD

INC R2 ; Tăng giá trị đếm


CJNE R2, #61, COUNT_LOOP ; Điều kiện lặp từ 0 đến 60 giây

END_LOOP: ; Nhãn cho vòng lặp cuối cùng


SJMP END_LOOP ; Lặp vô hạn

INIT_LCD: ; Khởi tạo LCD


; Thực hiện các bước khởi tạo LCD tại đây
; ...

DISPLAY_COUNT_LCD: ; Hiển thị giá trị đếm trên LCD


MOV A, R2 ; Gán giá trị đếm vào thanh ghi A
ACALL DISPLAY_TO_LCD ; Hiển thị giá trị đếm lên LCD
RET

DISPLAY_TO_LCD: ; Hiển thị giá trị lên LCD


; Gửi ký tự đến LCD thông qua các chân kết nối
; (Thực hiện các lệnh cần thiết để gửi ký tự đến LCD)
RET

END ; Kết thúc chương trình

15
3. BÀI TẬP THỰC HÀNH BUỔI 4
- Mã sinh viên: 2151210695 => AB = 95
Bài 2.1: Viết chương trình xuất cho LED nối với chân PINA của mạch
Arduino nhấp nháy AB lần. Độ trễ giữa ON và OFF là AB0ms (AB = 95).
const int buttonPin = PIN0; // chân PIN0 được kết nối với nút nhấn
const int ledPin = PIN4; // chân PIN1 được kết nối với LED

void setup() {
pinMode(buttonPin, INPUT); // PIN0 được đặt làm INPUT
pinMode(ledPin, OUTPUT); // PIN1 được đặt làm OUTPUT
}

void loop() {
if (digitalRead(buttonPin) == HIGH) { // nếu nút nhấn được nhấn
for (int i = 0; i < 95; i++) {
digitalWrite(ledPin, HIGH); // bật LED
delay(400); // đợi 500ms
digitalWrite(ledPin, LOW); // tắt LED
delay(400); // đợi 500ms trước khi bật lại LED
}
}
}

Bài 2.2: Đọc tín hiệu từ nút nhấn tại chân PIN0. Mỗi khi nhấn nút thì chân
PIN1 điều khiển LED đơn nhấp nháy AB lần, độ trễ giữa ON và OFF là
500ms (AB = 95).
const int buttonPin = PIN0; // chân PIN0 được kết nối với nút nhấn
const int ledPin = PIN1; // chân PIN1 được kết nối với LED

void setup() {
pinMode(buttonPin, INPUT); // PIN0 được đặt làm INPUT
pinMode(ledPin, OUTPUT); // PIN1 được đặt làm OUTPUT
}

void loop() {
if (digitalRead(buttonPin) == HIGH) { // nếu nút nhấn được nhấn
for (int i = 0; i <95 ; i++) {
digitalWrite(ledPin, HIGH); // bật LED
delay(500); // đợi 500ms

16
digitalWrite(ledPin, LOW); // tắt LED
delay(500); // đợi 500ms trước khi bật lại LED
}
}
}

Bài 2.3: Mỗi khi nhấn nút nối với PIN0, vi điều khiển điều khiển cổng
PIN1-PIN8 hiển thị 8 LED đơn thể hiện đếm từ 0 đến 8.
const int buttonPinT1 = 5;
const int ledPin1 = 1;
const int buttonPinT3 = 6;
const int ledPin3 = 2;
const int buttonPinT5 = 7;
const int ledPin5 = 3;
const int buttonPinT7 = 8;
const int ledPin7 = 4;

int buttonStateT1 = 0;
int buttonStateT3 = 0;
int buttonStateT5 = 0;
int buttonStateT7 = 0;

void setup() {
pinMode(ledPin1, OUTPUT);
pinMode(ledPin3, OUTPUT);
pinMode(ledPin5, OUTPUT);
pinMode(ledPin7, OUTPUT);

pinMode(buttonPinT1, INPUT_PULLUP);
pinMode(buttonPinT3, INPUT_PULLUP);
pinMode(buttonPinT5, INPUT_PULLUP);
pinMode(buttonPinT7, INPUT_PULLUP);
}

void loop() {
buttonStateT1 = digitalRead(buttonPinT1);
buttonStateT3 = digitalRead(buttonPinT3);
buttonStateT5 = digitalRead(buttonPinT5);
buttonStateT7 = digitalRead(buttonPinT7);

17
if (buttonStateT1 == HIGH) {
digitalWrite(ledPin1, HIGH);
} else {
digitalWrite(ledPin1, LOW);
}
if (buttonStateT3 == HIGH) {
digitalWrite(ledPin3, HIGH);
} else {
digitalWrite(ledPin3, LOW);
}
if (buttonStateT5 == HIGH) {
digitalWrite(ledPin5, HIGH);
} else {
digitalWrite(ledPin5, LOW);
}
if (buttonStateT7 == HIGH) {
digitalWrite(ledPin7, HIGH);
} else {
digitalWrite(ledPin7, LOW);
}
}

Bài 3.1: Viết chương trình điều khiển 6 LED 7 thanh hiển thị số ABCDEF
(2151214240 => ABCDEF = 210695).
#define SEG_A(x) digitalWrite(1,x)
#define SEG_B(x) digitalWrite(2,x)
#define SEG_C(x) digitalWrite(3,x)
#define SEG_D(x) digitalWrite(4,x)
#define SEG_E(x) digitalWrite(5,x)
#define SEG_F(x) digitalWrite(6,x)
#define SEG_G(x) digitalWrite(7,x)
#define SEG_DP(x) digitalWrite(8,x)
#define BT1 11
#define BT2 12
#define COL_1(x) digitalWrite(9,x)
#define COL_2(x) digitalWrite(10,x)
unsigned char DEM = 0;
void setup() {

18
// put your setup code here, to run once:
pinMode(1,OUTPUT);
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(4,OUTPUT);
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
pinMode(7,OUTPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(10,OUTPUT);
pinMode(11,INPUT);
pinMode(12,INPUT);
}

void loop() {
// put your main code here, to run repeatedly:
count();
SEG7_Out(DEM);
}
void SEG7_Send(unsigned char data)
{
unsigned char check, soBitDich=0;

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_A(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_B(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_C(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_D(check);

19
check = data & (0x01<<soBitDich++);
check = check!=0?1:0;
SEG_E(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_F(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_G(check);

check = data & (0x01<<soBitDich++);


check = check!=0?1:0;
SEG_DP(check);
}

void SEG7_Out(unsigned char dem)


{
unsigned char
MaCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x
00};
unsigned char so_dem = MaCode[dem];
unsigned char HangChuc, DonVi;
int t=0;
//34
HangChuc = dem/10;
DonVi = dem%10;
HangChuc = MaCode[HangChuc];//tu giai ma cho no
DonVi = MaCode[DonVi];

while(t<50)
{
COL_1(0);//cap nguon cho led 7 doan 1
SEG7_Send(HangChuc);//xuat ma hien thi led
delay(5);//tao tre hien thi
COL_1(1);//ngung cap nguon cho led 7 doan

COL_2(0);//cap nguon cho led 7 doan 2


SEG7_Send(DonVi);//xuat ma hien thi led

20
delay(5);//tao tre hien thi
COL_2(1);//ngung cap nguon cho led 7 doan
t++;
}
delay(1);
}
void count(){
int st1,st2,st3;
int last1 = 1;
int last2 = 1;
int last3 = 1;
st1 = digitalRead(BT1);
st2 = digitalRead(BT2);
if(st1 != last1)
{
if(st1 == 0)
{
DEM++;
}
}
last1 = st1;
if(st2 != last2)
{
if(st2 == 0)
{
DEM--;
}
}
last2 = st2;
}

Bài 4.1: Viết chương trình tạo xung PWM có tần số 2kHz có độ rộng xung
là 50%.
const int pwmPin = 9; // Chọn chân PWM, ví dụ: chân số 9 trên Arduino Uno

void setup() {
// Khai báo chân làm chân PWM
pinMode(pwmPin, OUTPUT);

// Bắt đầu tạo xung PWM với tần số 2kHz


21
// Đặt độ rộng xung là 50% (đối với Arduino, giá trị độ rộng nằm trong
khoảng từ 0 đến 255)
analogWrite(pwmPin, 127); // 127 là 50% của 255
}

void loop() {
// Có thể thực hiện các công việc khác trong hàm loop nếu cần
}

Bài 4.2: Viết chương trình phát một chuỗi kí tự là tên sinh viên qua cổng
truyền thông nối tiếp ở chế độ UART 8 bit, tốc độ baud 9600.
void setup() {
Serial.begin(9600); // Khởi tạo cổng Serial với tốc độ 9600 baud
}
void loop() {
String studentName = "Lưu Ngọc Lâm";
Serial.println(studentName); // Gửi chuỗi kí tự qua cổng UART

delay(1000); // Đợi 1 giây trước khi gửi lại (có thể thay đổi nếu cần)
}

Bài 4.3: Viết chương trình chờ nhận 1 xung âm tại chân PIN0. Khi xuất
hiện xung thì gửi 1 ký tự @ ra cổng truyền thông nối tiếp ở chế độ UART
8 bit, tốc độ baud 9600.
void setup() {
Serial.begin(9600); // Khởi tạo cổng Serial với tốc độ 9600 baud
pinMode(0, INPUT); // Chân 0 là chân đầu vào để nhận xung
}

void loop() {
if (digitalRead(0) == HIGH) { // Kiểm tra nếu có xung tại chân 0
Serial.print('@'); // Gửi ký tự '@' qua cổng UART
delay(1000); // Đợi 1 giây trước khi gửi lại (có thể thay đổi nếu cần)
}
}

4. BÀI TẬP THỰC HÀNH BUỔI 5

22
Bài 2.1: Viết chương trình xuất chuỗi “TEN MSSV AB” ra module LCD
(AB = 95).
#include <LiquidCrystal.h>//Khai báo thư viện
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);//Khai báo các chân RS, E, D4-D7 kết
nối với Arduino
void setup() {
lcd.begin(16, 2);//Khởi tạo màn hình LCD và xác định kích thước màn hình
LCD là 16x2
}
void loop() {
lcd.clear();//Xóa màn hình và đặt con trỏ về vị trí đầu tiên (0, 0)
lcd.setCursor(6,0);//Di chuyển con trỏ đến cột tương ứng
lcd.print("LƯU NGỌC LÂM");//Xuất ra màn hình từ vị trí con trỏ
lcd.setCursor(5,1);
lcd.print("MSV 95");
delay(1000);
}

Bài 2.2: Đọc tín hiệu từ nút nhấn T1-T8 (Port 3) và hiện chuỗi “ Nut nhan
T1” (Ví dụ nút T1 tương ứng P3.0) được ấn tương ứng trên LCD theo
chuẩn kết nối LCD 4bit và giao tiếp I2C).
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F,16,2);
char line1[16];
char line2[16];
void setup() {
// put your setup code here, to run once:
lcd.init();
lcd.backlight();
}
void moni(){
lcd.setCursor(2,0);
sprintf(line1,"NUT NHAN T1");
lcd.print(line1);
lcd.setCursor(0,1);
sprintf(line2,"NUT NHAN T1");
lcd.print(line2);
}
void loop(){

23
moni();
}

Bài 3.1: Viết chương trình hiển thị nhiệt độ (Số nguyên – VD: 29 độ) ra
module LED 7 thanh.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// Khai báo địa chỉ I2C của màn hình LCD


#define LCD_ADDRESS 0x27

// Khai báo chân kết nối cảm biến nhiệt độ DS18B20 với Arduino
#define ONE_WIRE_BUS 2

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

void setup() {
lcd.init();
lcd.backlight();
sensors.begin();
}
void loop() {
sensors.requestTemperatures(); // Đọc nhiệt độ từ cảm biến
float temperatureC = sensors.getTempCByIndex(0); // Đọc nhiệt độ đơn vị
Celsius từ cảm biến
if (temperatureC != DEVICE_DISCONNECTED_C) {
lcd.setCursor(0, 0);
lcd.print("Nhiet do: ");
lcd.print(temperatureC, 1); // Hiển thị nhiệt độ với 1 chữ số sau dấu phẩy
lcd.print(" C");
}
delay(1000); // Đợi 1 giây trước khi đọc lại nhiệt độ (có thể thay đổi tùy ý)
}

24
Bài 3.2: Viết chương trình hiển thị nhiệt độ (số thập phân chính xác 1 chữ
số sau dấu phẩy – VD: 29,5 độ) ra module LCD (sử dụng giao tiếp I2C).
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <OneWire.h>
#include <DallasTemperature.h>
// Khai báo địa chỉ I2C của màn hình LCD
#define LCD_ADDRESS 0x27

// Khai báo chân kết nối cảm biến nhiệt độ DS18B20 với Arduino
#define ONE_WIRE_BUS 2
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);
void setup() {
lcd.init();
lcd.backlight();
sensors.begin();
}
void loop() {
sensors.requestTemperatures(); // Đọc nhiệt độ từ cảm biến
float temperatureC = sensors.getTempCByIndex(0); // Đọc nhiệt độ đơn vị
Celsius từ cảm biến
if (temperatureC != DEVICE_DISCONNECTED_C) {
lcd.setCursor(0, 0);
lcd.print("Nhiet do: ");
lcd.print(temperatureC, 1); // Hiển thị nhiệt độ với 1 chữ số sau dấu phẩy
lcd.print(" C");
}
delay(1000); // Đợi 1 giây trước khi đọc lại nhiệt độ (có thể thay đổi tùy ý)
}

Bài 4.1: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…)
trên LED 7 thanh và lặp lại.
const int digitPins[] = {2, 3, 4, 5, 6, 7, 8}; // Các chân kết nối với LED 7 đoạn
(A đến G)

const byte numbers[10][7] = {


{1, 1, 1, 1, 1, 1, 0}, // 0

25
{0, 1, 1, 0, 0, 0, 0}, // 1
{1, 1, 0, 1, 1, 0, 1}, // 2
{1, 1, 1, 1, 0, 0, 1}, // 3
{0, 1, 1, 0, 0, 1, 1}, // 4
{1, 0, 1, 1, 0, 1, 1}, // 5
{1, 0, 1, 1, 1, 1, 1}, // 6
{1, 1, 1, 0, 0, 0, 0}, // 7
{1, 1, 1, 1, 1, 1, 1}, // 8
{1, 1, 1, 1, 0, 1, 1} // 9
};

void setup() {
for (int i = 0; i < 7; ++i) {
pinMode(digitPins[i], OUTPUT);
}
}

void loop() {
for (int sec = 0; sec <= 60; ++sec) {
displayNumberOn7Segment(sec % 10); // Hiển thị chữ số hàng đơn vị
delay(5); // Đợi một khoảng thời gian ngắn

displayNumberOn7Segment(sec / 10); // Hiển thị chữ số hàng chục


delay(5); // Đợi một khoảng thời gian ngắn
}
}

void displayNumberOn7Segment(int number) {


for (int i = 0; i < 7; ++i) {
digitalWrite(digitPins[i], numbers[number][i]);
}
}

Bài 4.2: Viết chương trình hiển thị đếm thời gian thực 0 – 60s (0, 1, 2, 3,…)
trên LCD.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define LCD_ADDRESS 0x27 // Địa chỉ của mô-đun LCD I2C

26
LiquidCrystal_I2C lcd(LCD_ADDRESS, 16, 2);

void setup() {
lcd.init();
lcd.backlight();
}
void loop() {
for (int sec = 0; sec <= 60; ++sec) {
lcd.setCursor(0, 0);
lcd.print("Thoi gian: ");
lcd.print(sec);
delay(1000); // Đợi một giây trước khi tăng giá trị giây lên
lcd.clear(); // Xóa màn hình để hiển thị số tiếp theo
}
}

27

You might also like