Tải bản đầy đủ (.doc) (37 trang)

Ứng dụng ic lập trình AT89C51: Dùng bàn phím điều khiển motor, relay, đèn... pdf

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2 MB, 37 trang )

Ứng dụng ic lập trình AT89C51: Dùng
bàn phím điều khiển motor, relay, đèn
Chúng ta biết, một "vật thể tự động hoàn chỉnh" phải gồm có: Ngả vào - Bộ nhớ - Ngả
ra. Ngả vào là chỉ tác động bên ngoài đi vào vật thể, như ở con người, chúng ta cómắt để
ghi nhận các thực thể xuất hiện ở dạng quang năng, có tai để nghe biết các sóng âm,có
mũi để nhận ra mùi,có lưỡi để nhận biết vị và có lớp da bao bọc toàn thân để cảm nhận
ra sự nóng lạnh, cứng mềm, nặng nhẹ Đó là ngủ quan của con người. Bộ nhớ được
dùng đề lưu giữ các chương trình, chương trình là "trí tuệ" mà thực thể có thể truy cập,
lấy ra thao tác mỗi khi gặp các đối ứng cần giải quyết và Ngả ra chính là các tạo thể trang
bị trên các vật thể nó chấp hành theo các chương trình, như trên cơ thể của chúng ta các
thực thể thấy được như tứ chi hai tay hai chân, tim, phổi, gan, ruột là các tạo thể luôn
vận hành theo các chương trình đã có trong bộ nhớ. Khi con người đứng gần chổ quá
nóng, chúng ta biết nóng và đã kịp đi ra xa chổ nóng, đó là phản ứng rất cơ bản của một
vật thể tự động hoàn chỉnh.Con người là sinh vật thông minh có khả năng học hỏi các
chứng vật hiện diện chung quanh trong thiên nhiên chung quanh và con người còn muốn
tự mình tạo ra các "vật thể tự động hoàn chỉnh" nữa. Ước muốn này đã có bước tiến vượt
bậc từ khi người ta chế tạo ra được các ic lập trình, nó hoạt động theo các chương trình
đã có trong các bộ nhớ. Trong lần này chúng ta sẽ nói đến tính năng nhập thông tin từ
bên ngoài vào bên trong của các ic lập trình, cơ bản nhất là dùng các phím nhấn, sau đó
sẽ mở rộng qua các cách lấy thông tin qua các cảm biến, như: quang trở, nhiệt trở, vị trở,
từ trở, ẩm trở, áp trở, phong trở, động trở, Với các cảm biến này, chúng ta có thể mô
phỏng nhiều chức năng giống như ngủ quan của các sinh vật vậy.
Trước khi nói đến điều cao siêu, chúng ta hãy tìm hiểu một hệ vận hành cơ bản và đơn
giản cái đã. Các phím nhấn dùng với ic lập trình AT89C51Chúng ta biết ic lập trình
AT89C51 có 4 cảng 8 bit nên tổng cộng có 32 chân có thể xuất nhập dữ liệu dạng bit.
Cách nhập dữ liệu đơn giản nhất là dùng các phím nhấn. Phím nhấn chỉ làm việc theo
logic nhị giá, nghĩa là đóng hoặc hở. Với các phím nhấn, người ta có thể dùng đơn lẻ hay
tổ hợp theo dạng matrix. Hình vẽ dưới đây cho thấy:
Các
phím gắn trên ma trận 4x4, người ta nói matrix 4x4 có 4 hàng và 4 cột. Trên ma trận 4x4
chúng ta chỉ dùng có 8 dây mà có thể gắn được đấn 16 phím, đó là một ưu điểm của loại


bàn phím matrix, dùng số chân ít mà gắn được nhiều phím. Với các phím đơn lập thì mỗi
phím thường gắn trên một chân của IC, vậy trên một cảng 8 chân chúng ta chỉ có thể gắn
được 8 phím.Các phím nhấn phân ra làm 2 kiểu: Kiểu phím nhấn thường hở và kiểu phím
nhấn thường đóng. Khi sử dụng các phím nhấn, chúng ta thường gặp vấn đề sau: Sự rung
phím.Vậy sự rung phím là gì? Hình
vẽ cho thấy: Khi phím hở thì nó cho mức áp cao, ngay khi phím được nhấn xuống, nó sẽ
kéo mức áp xuống mức thấp, nhưng do hiện tượng rung phím, lúc này có sự rung động ở
tiếp xúc điểm, khiến cho tiếp điểm lúc dính lúc hở và mức áp sẽ dao động lúc lên lúc
xuống và phải sau một lúc mới ổn định được ở mức thấp. Khi bỏ phím nhấn ra, chúng ta
cũng gặp hiện tượng tương tự nhưng ít tác hại hơn. Khi dùng phím nhấn với các ic lập
trình có phản ứng cực nhanh hiện tượng rung phím sẽ gây ra các điều khiển sai. Khi viết
chương trình cho các phím nhấn, chúng ta phải chú ý đến ảnh hưởng của hiện tượng rung
phím, nhất là mỗi khi phím được đóng lại.Trong thực hành, người ta thường dùng một
đoạn chương trình làm chậm khoảng 3ms đến 10ms và cho dò lại lần nữa trạng thái của
phím để tránh sự sai lầm có thể xẩy ra do hiện tượng rung phím.* Mạch AT89C51 dùng
8 phím nhấn đơn lập
Khi dùng sơ đồ mạch điện này, trạng thái bit 1 trên các chân của cảng p1 được xem như
không có nhấn phím, khi có nhấn phím thì chân có phím được nhấn sẽ xuất hiện bit 0. Khi
một trong 8 chân của cảng p1 có chân ở bit 0, chúng ta biết là có nhấn phím, như vậy
chúng ta sẽ viết câu lệnh tìm xem trên cảng p1 có xuất hiện bit 0 hay không? Nếu không
có bit 0 trên p1 thì tiếp tục dò tìm, khi có chân có bit 0 thì hiểu là đã có phím bị nhấn
xuống, lúc đó chuyển qua tìm xem phím nào đã được nhấn và rồi tiếp theo là cho chạy
chương trình tương ứng với phím đã được nhấn. Sau đây là một đoạn chương trình dùng
dò xem có phím nhấn không?loop: ; đặt tên nhãn cho lệnh nhẩy call do_key ; cho gọi
chương trình dò phím, tên nhãn do_key jnb f0, ttuc ; nhẩy theo bit của f0, f0=0, tiếp tục
dò phím call tim_phim ; cho gọi trình xác định phím nào được nhấnttuc: ; tên nhãn cho
lệnh nhẩy jmp loop ; nhẩy về tên nhãn loop, bắt đầu lại công việc dò phím do_key: ; tên
nhãn dùng cho lệnh nhẩy clr f0 ; cho xóa bit f0, bit kiểm tra có phím nhấn hay
không? mov a, p1 ; chuyển trạng thái bit trên p1 vào thanh ghi a orl a, #00000000b ; lấy
logic OR trị trong a với 00000000b, để tìm bit 0 trên p1 cpl a ; đảo trị trong thanh ghi a jz

key_ret ; nếu trị trong a là 0, nhẩy đến key_ret, không có phím nhấn call del ; gọi chương
trình trể mov a, p1 ; lại chuyển trạng thái của p1 vào a, kiểm tra lần nữa orl a,
#00000000b ; lại cho lấy logic OR trị trong a với 00000000b cpl a ; đảo trị trong a để dò
xem có phím nhấn không jz key_ret ; nhẩy đến tên nhãn key_ret nếu không có phím nào
được nhấn setb f0 ; nếu có phím nhấn, cho set bit kiểm tra f0 mov b,a ; cho chuyển trị
trong a cho cất vào b để dùng xác định phím nào được nhấnkey_ret: ; tên nhãn dùng cho
lệnh nhẩy mov a, p1 ; cho chuyển trạng thái cảng p1 vào a orl a, #00000000b ; lấy logic
OR trị trong a với 00000000b cpl a ; đảo trị trong thanh ghi a jz key_ret1 ; nhẩy đến tên
nhãn key_ret1, nếu thanh a bằng 0 jmp key_ret ; nhẩy đến tên nhãn key_ret, tiếp tục
kiểm tra p1key_ret1: ret ; quay lại sau lệnh: call do_keytim_phim: ; chương trình xác định
phím nào đã được nhấn
Hình động trên đây cho thấy cách viết các câu lệnh dùng dò xem có phím nhấn hay
không?* Mạch AT89C51 dùng 16 phím gắn trên ma trận
4x4
Hình vẽ cho thấy, 16 phím nhấn gắn trên ma trận 4x4. Ở đây 4 hàng cho nối vào p2.0,
p2.1, p2.2, p2.3, chúng ta gọi 4 hàng này là ngả ra OUTPUT và 4 cột cho nối vào p2.4,
p2.5, p2.6, p2.7 và gọi 4 cột là ngả vào INPUT. Có thể thấy:Trên các cảng p1 cho gắn 8
Led và trên cảng p3 chúng ta cũng cho gắn 8 Led. Từ sơ đồ mạch điện này, chúng ta sẽ
lập trình để dùng các phím trên bảng ma trận điều khiển các Led. Cách viết chương
trình vận hành các phím ráp theo kiểu ma trận 4x4:Trước hết người ta đặt các hàng
làm ngả ra OUTPUT và đặt các cột làm ngả vào INPUT.Khởi đầu cho các ngả vào ở bit 1
và cho các ngả ra ở bit 0, và chạy trình dò phím, để xem có phím nào đã được nhấn
xuống không?* Khi đã xác nhận là đã có nhấn phím rồi thì cho chạy chương trình tìm
phím nhấn. Lúc này mỗi lần chỉ cho một chân INPUT ở bit 0, khởi đầu cho cột 1 ở bit 0 rồi
tìm xem trong 4 hàng, xem trên ngả ra OUTPUT nào đang ở bit 0, làm vậy sẽ xác định
được một trong 4 phím của cột 1.* Khi chỉ cho cột 2 ở bit 0, rồi tìm xem ở hàng nào đang
ở bit 0, làm vậy sẽ xác định được một trong 4 phím của cột 2. * Khi chỉ cho cột 3 ở bit 0,
rồi tìm xem ở hàng nào đang ở bit 0, làm vậy sẽ xác định được một trong 4 phím của cột
3.* Khi chỉ cho cột 4 ở bit 0, rồi tìm xem ở hàng nào đang ở bit 0, làm vậy sẽ xác định
được một trong 4 phím của cột 4.

Sau đây là một chương
trình mẫu:org 0000b
start: ; đặt tên nhãn dùng cho lệnh nhẩy
clr p2.0 ; cho Led chỉ thị trên chân p2.0 sáng ; vào chương trình dò phím
do_phim: ; đoạn chương trình dùng để dò phím
mov p1, #00001111b ; đặt 4 chân Input lên 1 và 4 chân Output xuống 0
mov a, p1 ; cho chuyển hiện trạng của cảng p1 vào a
orl a, #11110000b ; lấy logic OR a với trị 11110000b
cpl a ; đảo các trị trong thanh ghi a
jz do_phim ; nếu a bằng 0 thì tiếp tục dò phím, nếu a khác 0 thì tìm phím nhấn
jmp tim_phim ; nhẩy đến chương trình tìm phím nhấn
; vào chương trình tìm phín nhấn
tim_phim: ; đoạn chương trình tìm phín nhấn
mov a, p1 ; chuyển hiện trạng của cảng p1 vào thanh ghi a
cjne a, #11101110b, tt1 ; chỉ cho chân p1.0 là 0, tìm phím trên p1.4
jmp chtrinh1 ; nếu đúng phím cho chạy chương trình 1
tt1: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11011110b, tt2 ; chỉ cho chân p1.0 là 0, tìm phím trên p1.5
jmp chtrinh2
tt2: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #10111110b, tt3 ; chỉ cho chân p1.0 là 0, tìm phím trên p1.6
jmp chtrinh3
tt3: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #01111110b, tt4 ; chỉ cho chân p1.0 là 0, tìm phím trên p1.7
jmp chtrinh4
;
tt4: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11101101b, tt5 ; chỉ cho chân p1.1 là 0, tìm phím trên p1.4
jmp chtrinh5
tt5: ; đặt tên nhãn dùng cho lệnh nhẩy

cjne a, #11011101b, tt6 ; chỉ cho chân p1.1 là 0, tìm phím trên p1.5
jmp chtrinh6
tt6: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #10111101b, tt7 ; chỉ cho chân p1.1 là 0, tìm phím trên p1.6
jmp chtrinh7
tt7: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #01111101b, tt8 ; chỉ cho chân p1.1 là 0, tìm phím trên p1.7
jmp chtrinh8
;
tt8: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11101011b, tt9 ; chỉ cho chân p1.2 là 0, tìm phím trên p1.4
jmp chtrinh9
tt9: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11011011b, tt10 ; chỉ cho chân p1.2 là 0, tìm phím trên p1.5
jmp chtrinh10
tt10: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #10111011b, tt11 ; chỉ cho chân p1.2 là 0, tìm phím trên p1.6
jmp chtrinh11
tt11: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #01111011b, tt12 ; chỉ cho chân p1.2 là 0, tìm phím trên p1.7
jmp chtrinh12
;
tt12: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11100111b, tt13 ; chỉ cho chân p1.3 là 0, tìm phím trên p1.4
jmp chtrinh13
tt13: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #11010111b, tt14 ; chỉ cho chân p1.3 là 0, tìm phím trên p1.5
jmp chtrinh14
tt14: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #10110111b, tt15 ; chỉ cho chân p1.3 là 0, tìm phím trên p1.6

jmp chtrinh15
tt15: ; đặt tên nhãn dùng cho lệnh nhẩy
cjne a, #01110111b, start ; chỉ cho chân p1.3 là 0, tìm phím trên p1.7
jmp chtrinh16
; Các chương trình ứng với các phím nhấn
chtrinh1:
chtrinh2:
chtrinh3:
chtrinh4:
chtrinh5:
chtrinh6:
chtrinh7:
chtrinh8:
chtrinh9:
chtrinh10:
chtrinh11:
chtrinh12:
chtrinh13:
chtrinh14:
chtrinh15:
chtrinh16:
end Các thí dụ cho thấy cách dùng bàn phím trong điều khiển1. Cách dùng phím
kiểu đơn lậpMột thí dụ về cách dùng các phím nhấn đơn lập
Phâ
n tích mạch:Sơ đồ cho thấy, chúng ta cấp điện cho ic lập trình AT89C51 với chân 20 cho
nối masse và chân 40 cho nối vào đường nguồn 5V. Trên chân 9 gắn tụ C1 (10uF) và điện
trở R1 (10K) dùng tạo tính năng reset mỗi khi mạch được cấp nguồn. Trên chân 18, 19
gắn thạch anh định tần, chúng ta dùng thạch anh 12MHz. Để mạch chỉ làm việc với bộ
nhớ trong chúng ta cho chân 31 nối vào đường nguồn 5V.Đề làm thực hành với các phím
nhấn đơn lập, chúng ta dùng 4 phím nhấn, gắn trên các chân p1.2, p1.3, p1.4, p1.5 của

cảng p1 và gắn 8 Led trên cảng p3 để hiển thị tác dụng của các phím nhấn.Ở đây chúng
ta sẽ tạo tính năng cho 4 phím nhấn như sau: phím S1 cho mở phím, phím S4 cho tắt
phím, phím S2 cho 8 Led trên p3 tuần tự dời qua phải và phím S3 cho 8 Led trên p3 dời
qua trái.Tóm lại công dụng của các phím như sau: * Nhấn nút S1 vào mode khởi động,
cho mở phím.* Nhấn nút S2, 8 Led trên cảng p3 dời bit qua phải* Nhất nút S3, 8 Led trên
cảng p3 dời bit qua trái* Nhấn nút S4 vào mode tắt phím Chương trình nguồn:UpDown
EQU 00H ; đặt tên bit 00h là updownStartEnd EQU 01H ; đặt tên bit 01h là
startendLAMPCODE EQU 21H ; đặt tên thanh ghi 21h là lampcodeORG 0000H ; địa chỉ
thanh ghi khởi đầuJMP MAIN ; nhẩy đến tên nhãnORG 30H ; vùng địa chỉ bên ngoài chức
năng ngắtMAIN: ; đặt tên nhãn dùng cho lệnh nhẩyMOV SP,#5FH ; chọn địa chỉ làm ngăn
xếpMOV P3,#0FFH ; đặt trị 11111111b vào cảng p3 để tắt 8 led; điều kiện khởi đầuCLR
UpDown ; đặt bit 0 vào bit updownCLR StartEnd ; đặt bit 0 vào bit startendMOV
LAMPCODE,#0FEH ; chuyển trị 11111110b vào lampcodeLOOP: ; đặt tên nhãn dùng cho
lệnh nhẩyCALL KEY ; gọi chương trình dò phím, tên nhãn keyJNB F0,LNEXT ; cho nhẩy
theo bit f0CALL KEYPROC ; gọi chương trình xử lý phímLNEXT: ; đặt tên nhãn dùng cho
lệnh nhẩyCALL LAMP ; gọi chương trình điều khiển 8 Led trên cảng p3JMP LOOP ; quay lại
tên nhãn loopDELAY: ;chương trình tạo trểMOV R7,#100 ; đặt trị 100 vào thanh ghi
r7D1: ; đặt tên nhãn dùng cho lệnh nhẩyMOV R6,#100 ; đặt trị 100 vào thanh ghi r6DJNZ
R6,$ ; nhẩy tại chổ, chờ trị trong r6 bằng 0DJNZ R7,D1 ; giảm trị trong r7 theo bước -1,
r7=0?, định hướng nhẩyRET ; qua lại sau lệnh call delay;
KEYPROC: ; chương trình xử lý phímMOV A,B ; chuyển trị trong b vào thanh ghi aJB
ACC.2,KeyStart ; xét bit acc.2 để định hướng nhẩy JB ACC.3,KeyOver ; xét bit acc.3 để
định hướng nhẩyJB ACC.4,KeyUp ; xét bit acc.4 để định hướng nhẩyJB
ACC.5,KeyDown ; xét bit acc.5 để định hướng nhẩyJMP KEY_RET ; nhẩy về tên nhãn
key_retKeyStart: ; trình vào mode khởi độngSETB StartEnd ; đặt bit startend lên 1, cho
khởi độngJMP KEY_RET ; nhẩy đến tên nhãn key_retKeyOver: ; trình cho tắt, kết thúcCLR
StartEnd ; đặt bit startend xuống 0, kết thúcJMP KEY_RET ; nhẩy đến tên nhãn
key_retKeyUp: ; trình cho 8 Led dời qua phảiSETB UpDown ; đặt bit updown lên 1, dời
qua phảiJMP KEY_RET ; nhẩy đến tên nhãn key_retKeyDown: ; trình cho 8 Led dời qua
tráiCLR UpDown ; đặt bit updown xuống 0, dời qua tráiKEY_RET: ; đặt tên nhãn dùng cho

lệnh nhẩyRET ; quay lại sau lệnh call keyprocKEY: ; đặt tên nhãn dùng cho lệnh nhẩy,
trình dùng dò phímCLR F0 ; xóa bit f0ORL P1,#00111100B ; lấy logic OR trị 00111100b và
cảng p1MOV A,P1 ; chuyển trị hiện có của p1 vào thanh ghi aORL A,#11000011B ;lấy
logic OR a và 11000011b, xét trạng thái 4 phímCPL A ; lấy bù a, đảo 8 bit trong thanh ghi
aJZ K_RET ; xét trị trong thanh a, có bằng 0 không? để nhẩyCALL DELAY ; cho gọi
chương trình trểOR P1,#00111100B ; lại lấy logia OR trị 00111100b cho cảng p1MOV
A,P1 ; lại chuyển trị hiện có của cảng p1 vào thanh ghi aORL A,#11000011B ; cho lấy
logic OR trị trong a và trị 11000011bCPL A ; lại cho bù a, đảo 8 bit trong thanh ghi aJZ
K_RET ; lại xét trị trong thanh a, có bằng 0? để nhẩyMOV B,A ; chuyển trị trong a vào
thanh bSETB F0 ; đặt bit kiểm tra f0 lên 1, báo đã có phím nhấnK_RET: ; đặt tên nhãn
dùng cho lệnh nhẩyORL P1,#00111100B ;Lấy logic OR trị hiện có trong p1 và
00111100bMOV A,P1 ; chuyển trị hiện có trên cảng p1 vào thanh ghi aORL A,#11000011B
; lấy logic OR trị trong a và 11000011bCPL A ; lấy bù a, đảo 8 bit trong thanh ghi aJZ
K_RET1 ; xét trị trong a có bằng 0 không? để nhẩyJMP K_RET ; nhẩy đến tên nhãn
k_retK_RET1: ; đặt tên nhãn dùng cho lệnh nhẩyRET ; quay lại sau lệnh call
keyD500MS: ;chương trình làm trểPUSH PSW ; tạm cho cất trị trong thanh ghi psw vào
ngăn xếpSETB RS0 ; đặt trị rs0 trong thanh ghi trạng thái psw lên 1MOV
R7,#200 ; chuyển trị 200 vào thanh ghi r7D51: ; đặt tên nhãn dùng cho lệnh nhẩyMOV
R6,#250 ; đặt trị 250 vào thanh ghi r6D52: ; đặt tên nhãn dùng cho lệnh nhẩyNOP ; dòng
không tác vụNOP ; dòng không tác vụNOP ; dòng không tác vụNOP ;dòng không tác
vụDJNZ R6,D52 ; giảm trị trong r6 theo bước -1, r6=0?, chọn hướng nhẩyDJNZ
R7,D51 ; giảm trị trong r7 theo bước -1, r7=0?, chọn hướng nhẩyPOP PSW ; lấy lại trị
trước đó cho thanh ghi pswRET ; quay lại sau lệnh gọi call d500msLAMP: ; chương trình
điều khiển 8 Led trên cảng p3JB StartEnd,LampStart ; chọn hướng nhẩy theo bit
startendMOV P3,#0FFH ; đặt trị 11111111b vào cảng p3, tắt hết 8 LedJMP
LAMPRET ; nhẩy về tên nhãn lampretLampStart: ; đặt tên nhãn cho lệnh nhẩy, trình dời 8
bit trong a qua tráiJB UpDown,LAMPUP ; nhẩy theo bit updownMOV
A,LAMPCODE ; chuyển trị trong lampcode cho thanh ghiRL A ; cho quay vòng 8 bit trong
thanh ghi aqua hướng tráiMOV LAMPCODE,A ; chuyển trị trong a vào lampcodeMOV
P3,A ; cho xuất trị trong a ra cảng p3CALL D500MS ; gọi chương trình làm chậm

d500msJMP LAMPRET ; nhẩy về tên nhãn lampretLAMPUP: ; đặt tên nhãn cho lệnh nhẩy,
trình cho dời 8 bit qua phảiMOV A,LAMPCODE ; chuyển trị trong lampcode vào thanh ghi
aRR A ; cho quay vòng 8 bit trong a qua hướng phảiMOV LAMPCODE,A ; chuyển trị trong
a vào lampcodeMOV P3,A ; xuất trị trong a ra cảng p3CALL D500MS ;cho gọi chương trình
trể d500msLAMPRET: ; đặt tên nhãn cho lệnh nhẩyRET ; quay lại sau lệnh callEND ; dừng
biên dịch tại dòng này Phân tích cách viết các câu lệnh chương trình nguồn trên:Tìm hiểu
thêm một cách viết khác. Bạn xem thí dụ sau: Trong thí dụ này, chúng ta gắn 4 phím
trên cảng p3 và dùng các phím này điều khiển trạng thái nhấp nháy của 8 Led đặt trên
cảng p1.
Chương trình nguồn viết như sau:
ORG 0000H ; Khởi đầu từ thanh ghi 0000h
LJMP START ; nhẩy đến tên nhãn start; các thanh ghi chuyên dùng cho chức năng ngắt
ORG 0003H ; vị trí chạy ngắt INT0
RETI
ORG 000BH ; vị trí chạy ngắt TF0
RETI
ORG 0013H ; vị trí chạy ngắt INT1
RETI
ORG 001BH ; vị trí chạy ngắt TF1
RETI
ORG 0023H ; vị trí chạy ngắt RI var TI
RETI
;
CLEAR: ; đặt tên nhãn cho lệnh nhẩy
RET
;
START: ; đặn tên nhãn cho khời đầu
CALL CLEAR ; gọi chương trình clear; trình dò phím
STAR1: ; đặt tên nhãn dùng cho lệnh nhẩy
MOV P3,#0FFH ; đặt trị 11111111b vào p3, định trạng thái đầu

JNB P3.4,FUN0 ; dò bit 0 trên chân p3.4, để nhẩy
JNB P3.5,FUN1 ; dò bit 0 trên chân p3.5 để nhẩy
JNB P3.2,FUN2 ; dò bit 0 trên chân p3.2 để nhẩy
JNB P3.3,FUN3 ; dò bit 0 trên chân p3.3 để nhẩy
JNB F0,STAR1 ; nhẩy theo bit f0, f0=1, có nhấn phím
RET ; quay lại sau lệnh call start
;
FUN0: ; tên nhãn dùng cho phím p3.4
CALL DL10MS ; gọi chương trình trể 10ms, tránh rung phím
JB P3.4,STAR1 ; kiểm tra lại phím nhấn trên p3.4
WAITL0: ; trình chờ bỏ phím
JNB P3.4,WAITL0 ; chờ bỏ phím
SETB F0 ; đặt bit kiểm tra f0 lên 1
FUN01: ; đặt tên nhãn dùng cho lệnh nhẩy
CALL FUN00 ; cho gọi chương trình fun00
CALL STAR1 ; quay lại tên nhãn star1
JMP FUN01 ; nhẩy về tên nhãn fun01
; Viết tương dạng như trên
FUN1:
CALL DL10MS ;
JB P3.5,STAR1
WAITL1:
JNB P3.5,WAITL1 ;
SETB F0
FUN10:
CALL FUN11
CALL STAR1
JMP FUN10
; Viết tương dạng như trên
FUN2:

CALL DL10MS ;
JB P3.2,STAR1
WAITL2:
JNB P3.2,WAITL2 ;
SETB F0
FUN20:
CALL FUN22
CALL STAR1
JMP FUN20
; viết tương dạng như trên
FUN3:
CALL DL10MS ; gọi trể 10ms tránh ảnh hưởng của rung phím
JB P3.3,STAR1 ; kiểm tra lần nữa phím trên p3.3
WAITL3: ; tên nhãn
JNB P3.3,WAITL3 ; chờ bỏ phím ra
CLR F0 ; xóa bit f0, về trạng thái chờ nhấn phím
MOV P1,#0FFH ; đặt trị 11111111b để tắt 8 Led trên p1
JMP STAR1 ; quay lại tên nhãn star1
; trình cho Led sáng lan lên
FUN00:
MOV A,#0FEH
FUN000:
MOV P1,A
CALL DL05S
JNB ACC.7,OUT
RL A
JMP FUN000
OUT: RET
; trình cho các Led sáng nhẩy
FUN11:

MOV A,#0FEH
FUN111:
MOV P1,A
CALL DL05S
JZ OUT
RL A
ANL A,P1
JMP FUN111
; trình cho các 4 Led nhấp nháy xen kẻ
FUN22:
MOV A,#0AAH
MOV P1,A
CALL DL30S
CPL A
MOV P1,A
CALL DL30S
RET
; chương trình làm trểDL512:
MOV R2,#0FFH
LOOP1:
DJNZ R2,LOOP1
RET
DL10MS:
MOV R3,#14H
LOOP2:
CALL DL512
DJNZ R3,LOOP2
RET
DL05S:
MOV R4,#0AH

LOOP3:
CALL DL10MS
DJNZ R4,LOOP3
RET
DL30S:
MOV R5,#03H
LOOP4:
CALL DL05S
DJNZ R5,LOOP4
RETend
Một thí dụ khác nữa: Dùng 8 phím trên cảng 1 để điều khiển các động thái của một
motor DCTrước hết tìm hiểu nguyên lý vận hành của các thành phần dùng trong mạch
điện:1. Tìm hiểu ic điều khiển motor:
IC BA6209 có 10 chân, công dụng của các chân như sau:Chân 1 cho nối masse, chân 7
cho nối nguồn VCC1, chân 8 lấy nguồn VCC2 qua một điện trở 10 ohm. Mức áp chuẩn
định tốc độ quay chọn theo diode Zener trên chân số 4. Chân số 3 và số 9 mắc tụ lọc và
chân số 2 và chân số 10 cấp điện cho motor. Ngang motor gắn một tụ lọc nhiễu ồn phát
ra từ motor. Tín hiệu điều khiển đưa vào trên chân 5 và chân 6. Bản logic cho thấy:* Khi
chân 5 Fin và chân 6 Rin đều ở mức áp thấp, thì mức áp ngả ra trên chân 2, 10 đều ở
mức áp thấp: Motor không quay.* Khi chân Fin ở mức áp cao, chân Rin ở mức áp thấp, thì
chân 2 ở mức cao và chân 10 ở mức áp thấp: Motor quay thuận.* Khi chân Fin ở mức áp
thấp, chân Rin ở mức áp cao, thì chân 2 ở mức thấp và chân 10 ở mức áp cao: Motor
quay ngược.* Khi chân 5 Fin và chân 6 Rin đều ở mức áp cao, thì mức áp ngả ra trên
chân 2, 10 đều ở mức áp thấp: Motor không quay. Phân tích trên cho thấy, chúng ta có
thể dùng 3 chân 4, 5, 6 của ic lập trình để điều khiển các trạng thái quay của
motor 2. Tìm hiểu nguyên lý làm việc của motor DC.Motor DC gồm có:* Phần tĩnh là một
nam châm vĩnh cữu, đặt cố định, một bên là cực nam thì bên kia là cực bắc.* Phần quay
gồm có các cuộn dây ứng quấn trên các từ cực. Trên trục quay người ta đặt một cổ lấy
điện bằng các vòng đồng, dùng chổi than đè lên cổ lấy điện để cấp điện cho các cuộn dây
ứng đặt trên phần quay, cuộn dây có điện sẽ trở thành các nam châm điện.Do tương tác,

các nam châm (ở đây là nam châm vĩnh cữu của phần tĩnh và nam châm điện trên phần
quay) đặt gần nhau, khi có tên cực giống nhau sẽ đẩy nhau và khác tên thì sẽ hút nhau,
điều này sẽ làm quay phần ứng, khi phần ứng quay nó đồng thời làm quay cổ lấy điện,
điều này sẽ làm đảo chiều dòng chảy qua các cuộn dây ứng, như vậy các nam châm sẽ lại
đổi cực tính, do vậy cuộn dây sẽ luôn phải ở trạng thái quay.
Chúng ta
biết, khi được cấp điện thì motor DC sẽ quay, mức áp cấp cho motor càng cao thì motor
quay càng nhanh. Và nếu Bạn dùng lực làm quay một motor DC thì trên 2 cực của motor
DC sẽ phát ra điện áp ứng, nếu motor bị kéo quay càng nhanh thì mức điện áp ứng phát
ra càng cao. Điều này cho thấy motor DC khi được cấp điện nó sẽ quay, và khi bị kèo
quay nó sẽ phát ra điện. Dùng luật ohm, chúng ta có thể viết hệ thức sau: dòng điện I =
(điện áp cung cấp) - (điện áp ứng) / điện trở R của cuộn ứngTrong đó: (điện áp ứng) là
một hàm của tốc độ quay. Khi motor quay càng chậm, điện áp ứng phát ra càng yếu và
ngược lại. (lực quay) là một hàm của dòng điện I. Khi dòng điện càng lớn thì lực kéo càng
mạnh.Điều này cho thấy: Khi bị tải nặng, tốc độ quay của motor sẽ có khuynh hướng bị
chậm lại, tốc độ quay giảm sẽ làm cho điện áp ứng giảm, hệ thức trên cho thấy dòng điện
I sẽ tăng lên, dòng điện I tăng sẽ gia tăng khả năng mang tải của motor DC, nhờ phản
ứng này, mà motor DC có khả năng mang tải rất tốt. Khi dùng motor DC chúng ta chú ý
các điểm sau:* Điện áp DC cấp cho motor DC càng cao, motor quay càng nhanh.* Đảo
chiều điện áp cấp điện, chiều quay của motor sẽ đổi chiều quay.* Điện trở phần ứng càng
nhò, dòng chảy qua motor DC càng lớn, lực quay sẽ càng mạnh.* Khi motor DC quay, từ
hai chổi quét điện sẽ luôn phát ra nhiễu ồn rất lớn, phải dùng tụ và cuộn dây để lọc
nhiễu.* Không để motor bị kẹt trục không quay, điều này sẽ khiến cho dòng chảy qua
motor sẽ rất lớn, motor có thể bị cháy.3. Phân tích sơ đồ điều khiển các động thái của
motor dùng ic AT89C51Mạch điện cho
thấy:
8 nút nhấn dùng điều khiển 2 motor DC gắn trên xe đều cho kết nối trên cảng p1. Motor
DC gắn bên phải qua ic BA6209, chân p3.0 điều khiển chiều quay thuận, chân p3.1 điều
khiển chiều quay nghịch và chân p3.2 điều khiển tốc độ quay. Motor DC gắn bên trái qua
ic BA6209, với chân p3.3 điều khiển chiều quay thuận, chân p3.4 điều khiển chiều quay

ngược và chân p3.5 điều khiển tốc độ quay.4. Viết chương trình nguồn theo yêu cầu
trên:org 0000h
qua0: jb p1.0, qua1 call del ; gọi trình làm trể, tránh ảnh hưởng rung phím
jnb p1.0, $
jmp chay_toi ; Cho chạy tới, 2 motor quay cùng chiều
qua1: jb p1.1, qua2 call del
jnb p1.1, $
jmp chay_lui ; chạy lùi, 2 motor cho quay ngược chiều
qua2: jb p1.2, qua3 call del
jnb p1.2, $
jmp queo_trai ; quẹo trái, motor trái dừng, motor phải quay tới
qua3: jb p1.3, qua4 call del
jnb p1.3, $
jmp queo_phai ; quẹo phải, motor phải dừng và motor trái quay tới
qua4: jb p1.4, qua5 call del
jnb p1.4, $
jmp dung ; dừng, cả 2 motor đều dừng, không quay
qua5: jb p1.5, qua6 call del
jnb p1.5, $
jmp cham_lai ; chậm lại, 2 motor quay với tốc độ chậm
qua6: jb p1.6, qua7 call del
jnb p1.6, $
jmp quay_trai ; quay vòng qua trái, motor trái quay ngược, motor phải quay thuận
qua7: jb p1.7, qua0 call del
jnb p1.7, $
jmp quay_phai ; quay vòng qua phải, motor trái quay thuận, motor phải quay
ngượcchay_toi: ; trình cho chạy tới
setb p3.0
clr p3.1
setb p3.2

setb p3.3
clr p3.4
setb p3.5
jmp qua0 ; trở lại chương trình qué phím
chay_lui: ; trình cho chạy lùi
clr p3.0
setb p3.1
setb p3.2
clr p3.3
setb p3.4
setb p3.5
jmp qua0 ; trở lại trình quét phím
queo_trai: ; cho quẹo trái
setb p3.0
clr p3.1
setb p3.2
setb p3.3
clr p3.4
clr p3.5
jmp qua0 ; trở lại trình quét phímqueo_phai: ; cho quẹo phải
setb p3.0
clr p3.1
clr p3.2
setb p3.3
clr p3.4
setb p3.5
jmp qua0 ; trở lại trình quét phím
dung: ; cho dừng
setb p3.0
clr p3.1

clr p3.2
setb p3.3
clr p3.4
clr p3.5
jmp qua0 ; trở lại trình quét phím
cham_lai: ; cho chậm lại
setb p3.0
clr p3.1
setb p3.3
clr p3.4
mov r4, #100
llai: setb p3.2
setb p3.5
call delay
clr p3.2
clr p3.5
call delay
djnz r4, llai
jmp qua0 ; trở lại trình quét phímquay_trai: ; cho quay vòng qua trái
setb p3.0
clr p3.1
setb p3.2
clr p3.3
setb p3.4
setb p3.5
jmp qua0 ; trở lại trình quét phímquay_phai: ; cho quay vòng qua phải
clr p3.0
setb p3.1
setb p3.2
setb p3.3

clr p3.4
setb p3.5
jmp qua0 ; trở lại trình quét phímdel: ; đặt tên nhãn dùng cho lệnh nhẩy mov r3, # 10 ;
nạp trị 10 vào thanh ghi r3 mov r4, #200 ; nạp trị 200 vào thanh ghi r4v_r4: ; đặt tên
nhãn dùng cho lệnh nhẩy djnz r4, $ ; giảm -1 đến khi trị trong r4 băng 0 djnz r3,
v_r4 ;giảm trị trong r3 theo bước -1, r3 0?, định hướng nhẩy ret ; quay lại sau lệnh call
del
delay: ; đặt tên nhãn cho trình làm trể
mov r5, #100 ; nạp trị 100 vào thanh ghi r5v_r6: ; đặt tên nhãn dùng cho lệnh nhẩy mov
r6, #250 ; nạp trị 250 vào thanh ghi r5
djnz r6, $ ; giảm theo bước -1 cho đến khi bằng 0
djnz r5, v_r6 ; giảm r5 theo bước -1, r5=0? chọn hướng nhẩy
ret ; quay lại sau lệnh call delay
end ; dừng biên dịch tại dòng này
Phân tích các câu lệnh viết trong chương trình trên:2. Cách dùng phím kiểu ma
trận Chúng ta sẽ viết chương trình nguồn cho kiểu bàn phím ma trận 4x4 như hình vẽ.
Trong bài thực hành này, chúng ta sẽ cho lấy mã có trong bảng xuất ra trên cảng p3 khi
nhấn một trong các phím trên ma trận 4x4. org 0000h ; Khởi đầu từ thanh nhớ 0000h
mov p2, #11111111b ; đặt các chân Input lên 1
k1: ; tên nhãn
mov p1, #00000000b ; đặt các chân Ouput xuống 0
mov a, p2 ; chuyển hiện trạng của p2 vào a
anl a, #00001111b ; lấy logic AND để che 4 bit cao
cjne a, #00001111b, k1 ; kiểm tra xem có phím nhấn chưa?
k2: ; đặt tên nhãn
call delay ; gọi chương trình trể tránh rung phím
mov a, p2 ; chuyển trạng thái p2 vào a
anl a, #00001111b ; lấy logic AND che 4 bit cao
cjne a, #00001111b, tim_hang ; so sánh để nhẩy

jmp k2 ; nhẩy về k2
tim_hang: ; đặt tên nhãn
mov p1, #11111110b ; đặt hàng 0, xuống bit 0
mov a, p2 ; chuyển p2 vào a
anl a, #00001111b ; lấy logic AND, che 4 bit cao
cjne a, #00001111b, hang_0 ; so sánh để nhẩy
;
mov p1, #11111101b ; đặt hàng 1, xuống bit 0
mov a, p2 ; chuyển p2 vào a
anl a, #00001111b ; lấy logic AND, che 4 bit cao
cjne a, #00001111b, hang_1 ; so sánh để nhẩy
;
mov p1, #11111011b ; đặt hàng 2, xuống bit 0
mov a, p2 ; chuyển p2 vào a
anl a, #00001111b ; lấy logic AND, che 4 bit cao
cjne a, #00001111b, hang_2 ; so sánh để nhẩy
;
mov p1, #11110111b ; đặt hàng 3, xuống bit 0
mov a, p2 ; chuyển p2 vào a
anl a, #00001111b ; lấy logic AND, che 4 bit cao
cjne a, #00001111b, hang_3 ; so sánh để nhẩy
;
hang_0: ; tìm ra một trong 4 phím hàng 0
mov dptr, #m_hang_0
jmp tim_phim ; qua trình tìm phím
hang_1: ; tìm ra một trong 4 phím hàng 1
mov dptr, #m_hang_1
jmp tim_phim ; qua trình tìm phím
hang_2: ; tìm ra một trong 4 phím hàng 2
mov dptr, #m_hang_2

jmp tim_phim ; qua trình tìm phím
hang_3: ; tìm ra một trong 4 phím hàng 3
mov dptr, #m_hang_3
jmp tim_phim ; qua trình tìm phím
;
tim_phim: ; đặt tên nhãn cho trình tìm phím
rrc a ; cho 8 bit trong a quay vòng có qua bit cờ C
jnc out ; kiểm tra bit 0 vào bit cờ C để nhẩy
inc dptr ; cho tăng trị trong bảng lên một nhịp
jmp tim_phim ; quay lại tên nhãn tim_phim
out: ; đặt tên nhãn
clr a ; xóa sạch trị trong thanh a
movc a, @a+dptr ; lấy mã trong bảng theo a và cất vào a
mov p3, a ; chuyển kết quả ra cảng p3
jmp k1 ; nhẩy về k1
m_hang_0: ; đặt tên bảng
db 01h, 02h, 03h, 04h ; mã trong bảng hàng 0
m_hang_1: ; đặt tên bảng
db 05h, 06h, 07h, 08h ; mã trong bảng hàng 1
m_hang_2: ; đặt tên bảng
db 09h, 0ah, 0bh, 0ch ; mã trong bảng hàng 2
m_hang_3: ; đặt tên bảng
db 0dh, 0eh, 0fh, 00h ; mã trong bảng hàng 3
;
delay: ; trình làm trể
mov r5, #100 ; đặt trị 100 vào thanh ghi r5
v_r6: ; đặt tên nhãn cho lệnh nhẩy mov r6, #100 ; đặt trị 100 vào thanh ghi r6
djnz r6, $ ; giảm theo bước -1 trị trong r6 cho đến khi bằng 0
djnz r5, v_r6 ; giảm trị trong r5 theo bước -1, r5=0?, chọn hướng nhẩy
ret ; quay lại sau lệnh call delay

end ; dừng biên dịch tại dòng này
Giải thích cách dùng các câu lệnh trên:
Bước 1: viết trình dò xem có phím nào được nhấn xuống không.
Bước 2: Dò có phím nhấn không, tránh ảnh hưởng của rung phím
Bước 3: Tìm xem phím trên hàng nào đã được nhấn xuống

Bước 4 và Bước 5: Tìm xem phím nào đã được nhấn xuống và xuất kết quả

×