You are on page 1of 65

1

3.1 Vòng lặp và lệnh nhảy

2
Lệnh nhảy có điều kiện và nhảy không điều kiện

• Lệnh nhảy có điều kiện là một lệnh nhảy đến một địa
chỉ đích nếu nó thỏa mãn điều kiện yêu cầu.
– DJNZ, JZ, JNC...
• Lệnh nhảy không điều kiện là một lệnh nhảy đến địa
chỉ đích không cần điều kiện nào.
• Các lệnh nhảy không điều kiện:
– LJMP(Long Jump - Nhảy dài)
– SJMP(Short Jump - Nhảy ngắn)

3
Vòng lặp trong 8051

• Lặp lại một chuỗi các lệnh trong một số lần nào đó
gọi là một vòng lặp.
– Các lệnh nhảy của 8051 Khởi tạo
• Trước tiên thực hiện tác vụ Nhãn
• Sau đó kiểm tra điều kiện
Tác vụ
– DJNZ, JZ, JNC

Kiểm tra
Nhảy nếu
điều kiện
điều kiện
là đúng Không nhảy
nếu điều kiện
là sai
4
Lệnh DJNZ(1/2)
MOV R2,#02H
• Giảm và nhảy nếu không bằng 0 CLR A

DJNZ Rn, đích HERE


INC A
MOV R2,#02H
CLR A
DEC R2,
HERE: INC A kiểm tra
Nhảy nếu
DJNZ R2,HERE R2≠0
Không nhảy
nếu R2 = 0
– Rn là một trang các thanh ghi R0 - R7.
– Đích là một nhãn. Một nhãn(HERE) là địa chỉ ROM của
lệnh tiếp sau(INC A).
– Tác vụ: tăng A lên 1(với R2=2,1,0) A=2
5
DJNZ(2/2)

• Kiểu địa chỉ trực tiếp


DJNZ địa-chỉ-trực-tiếp (direct), đích
MOV 30H,#02 ;X=giá trị ở địa chỉ RAM 30H
CLR A ;A=0
HERE: INC A ;tăng A thêm 1
DJNZ 30H,HERE;Giảm X và
;nhảy tới HERE nếu X≠0
– Direct có nghĩa là “địa chỉ của RAM truy cập một cách trực
tiếp”.

6
Ví dụ 3-1
Viết một chương trình
(a) xóa ACC, sau đó
(b) cộng 3 vào thanh ghi ACC mười lần.

Giải:
;Chương trình này cộng giá trị 3 tới thanh
ghi ACC mười lần

MOV A,#0 ;A=0, xóa ACC


MOV R2,#10 ;nạp số đếm vào R2=10
AGAIN: ADD A,#03 ;cộng 03 với ACC
DJNZ R2,AGAIN ;lặp lại tới khi R2=0
;(10 lần)
MOV R5,A ;cất A vào R5

7
Ví dụ 3-2
Hỏi số lần lặp lớn nhất của vòng lặp mà ví dụ 3-1 có thể lặp?

Giải:

Do thanh ghi R2 để chứa số đếm là thanh ghi 8-bit, vòng lặp có


thể lặp số lần cực đại là 256 lần bằng cách thiết lập R2=0.
Do đó, R2=0HFFH, FEH, ..., 2, 1, 0(tổng số 256 lần lặp lại
các lệnh ADD&DJNZ).

8
Vòng lặp lồng nhau

• Một vòng lặp có thể lặp lại nhiều nhất là 256 lần.
• Nếu muốn lặp lại một tác vụ lớn hơn 256 lần, phải sử
dụng các vòng lặp bên trong vòng lặp.
• Đó được gọi là vòng lặp lồng. vòng lặp ngoài
• Ví dụ:
vòng lặp
– Vòng lặp trong là 256 trong
– Vòng lặp ngoài là 2
tác vụ
– Tổng số 256*2=512 lần

9
Ví dụ 3-3 (1/2)
Viết một chương trình
(a) nạp giá trị 55H vào thanh ghi tích lũy (thanh ghi ACC), và
(b) Làm phép bù thanh ghi ACC 700 lần.
Giải: MOV R3,#10

Sử dụng các thanh ghi NEXT


R2 và R3 chứa số đếm. MOV R2,#70
700=10 ×70 AGAIN

Vòng trong: R2=70 DJNZ R2, AGAIN


Vòng ngoài: R3=10
DJNZ R3, NEXT

10
Ví dụ 3-3 (2/2)
MOV A,#55H ;A=55H
MOV R3,#10 ;R3=10,số đếm của vòng ngoài
NEXT: MOV R2,#70 ;R2=70,số đếm của vòng trong
AGAIN:CPL A ;lấy bù thanh ghi A
DJNZ R2,AGAIN;lặp 70 lần (cho vòng trong)
DJNZ R3,NEXT MOV R3,#10
NEXT
MOV R2,#70
AGAIN

DJNZ R2, AGAIN

DJNZ R3, NEXT

11
Lệnh JZ
MOV A, R5
• Nhảy đến địa chỉ đích nếu A = 0
JZ đích Nhảy nếu
A=0
MOV A,R5 Kiểm tra

JZ NEXT Không nhảy


MOV R5,#55H nếu A ≠0

NEXT: ... MOV R5,#55H

NEXT

– Lệnh này kiểm tra nội dung của thanh ghi ACC và nhảy
nếu ACC có giá trị 0.
12
Lệnh JNZ
MOV A, R5
• Nhảy nếu thanh ghi A khác 0
JNZ đích Nhảy nếu
A≠0
MOV A,R5 Test

JNZ NEXT
Không nhảy
MOV R5,#55H nếu A =0
NEXT: ... MOV R5,#55H

NEXT

– Lệnh này kiểm tra nội dung của thanh ghi ACC và nhảy
nếu ACC là khác 0.
13
Ví dụ 3-4
Viết một chương trình để khẳng định nếu R5 chứa giá trị 0.
Nếu vậy, đưa giá trị 55H vào trong nó.

Giải: MOV A, R5

MOV A,R5 Nhảy nếu


A≠0 Test
JNZ NEXT
MOV R5,#55H Không nhảy
NEXT: ... nếu A =0
MOV R5,#55H

NEXT

14
Lệnh JNC

• Nhảy nếu cờ carry không được thiết ADD A, #01H

lập(nếu CY=0)
Nhảy nếu
JNC đích CY=0 Test
MOV A,#0FFH
Không nhảy
ADD A,#01H nếu CY ≠0
JNC NEXT INC R5
INC R5
NEXT
NEXT: ...
– Cờ CY trong thanh ghi PSW.
– Lệnh này kiểm tra cờ CY, và nếu nó là 0 thì sẽ nhảy đến
địa chỉ đích. 15
Ví dụ 3-5
Tính tổng của các số 79H, F5H, và E2H.
Đặt giá trị của tổng vào thanh ghi R0 (byte thấp) và R5 (byte cao).
Giải: CY A
MOV A,#0 ;xóa A(A=0)
MOV R5,A ;xóa R5(R5=0) R5 R0
ADD A,#79H ;A=0+79H=79H
JNC N_1 ;nếu CY=0,cộng số tiếp theo
INC R5 ;nếu CY=1, tăng R5 thêm 1
N_1: ADD A,#0F5H ;A=79+F5=6E và CY=1(R5=0)
JNC N_2 ;nhảy nếu CY=0
INC R5 ;nếu CY=1, tăng R5
N_2: ADD A,#0E2H ;A=6E+E2=50 và CY=1(R5=1)
JNC OVER ;nhảy nếu CY=0
INC R5 ;nếu CY=1, tăng R5
OVER:MOV R0,A ;bây giờ R0=A=50H,và R5=02
16
Bảng 3-1: Các lệnh nhảy có điều kiện của
8051
Lệnh Tác dụng
JZ(Jump Zero) Nhảy nếu A=0
JNZ(Jump not zero) Nhảy nếu A≠0
DJNZ Rn, đích Giảm và nhảy nếu byte≠0
So sánh A với byte và nhảy nếu khác nhau
CJNE A,byte,đích
(A≠byte)

CJNE thanh ghi,#data,đích So sánh thanh ghi với #data và nhảy nếu
không bằng nhau (byte ≠ #data)
JC(Jump carry) Nhảy nếu CY=1
JNC(Jump no carry) Nhảy nếu CY=0
JB(Jump bit) Nhảy nếu bit=1
JNB(Jump no bit) Nhảy nếu bit=0
JBC(jump bit clear bit) Nhảy nếu bit=1 và xóa bit 17
Lệnh nhảy dài(LJMP - Long Jump)
ROM address
0000
• Là một lệnh 3-byte
– Byte đầu tiên là opcode
1120 LJMP Đích
– Hai byte tiếp theo là các địa 1123 CPL A
chỉ đích (địa chỉ thực)
• LJMP được sử dụng để A010 Đích: MOV R0,A
nhảy tới vị trí địa chỉ trong
không gian 64K byte mã FFFF
lệnh của 8051. Đích=A010 opcode=02A010

Bits 23 16 15 8 7 0
opcode = 02 địa chỉ đích

18
LJMP

• Nhảy tới địa chỉ mới


LJMP địa-chỉ-đích-16-bit.
Dòng Addr. Opcode Mnemonic Toán hạng
17 0015 020015 HERE: LJMP HERE
18 0018 END

– opcode của lệnh LJMP là 02.


– Khi thực hiện Dòng 17, nhảy tới địa chỉ đích 0015H.
– Trình dịch Assembler cho 8051 có thể dịch nhãn “HERE”
thành giá trị 0015H.

19
Lệnh nhảy ngắn (SJMP - Short Jump)
Nhảy tiến
ROM address
• Là lệnh 2-byte 0000
– Byte đầu tiên là opcode.
Opcode 8030H
– Byte thứ hai là địa chỉ tương đối. 1120 SJMP Đích
– Địa chỉ này được quy chiếu tới 1122 CPL A
như là một địa chỉ tương đối vì
địa chỉ đích là có quan hệ tương 1152 Đích: MOV R0,A
đối với PC.
– Địa chỉ tương đối là một số có FFFF
dấu 8-bit.
Bits 15 8 7 0 Khi dịch: PC=1122, đích=1152
ĐCTĐ = đích-PC=1152-1122=30H
opcode = 80 địa chỉ tương đối
Khi chạy: PC=1122, ĐCTĐ=30
đích=PC+ĐCTĐ=1122+30=1152H
20
SJMP

• Nhảy đến một địa chỉ mới


SJMP địa-chỉ-tương-đối-8-bit
Dòng Addr. Opcode Mnemonic Toán hạng
17 0015 80FE HERE: SJMP HERE
18 0017 END

Khi Dịch chương trình


Nhãn “HERE” có địa chỉ là 0015H.
PC=0017H. Nhảy lùi
Địa chỉ tương đối = Địa chỉ đích-PC = 0015H-0017H=FFFEH
Khi chạy chương trình
Địa chỉ đích = PC + Địa chỉ tương đối = 0017H+FFFEH
(Bỏ đi CARRY) = 0015H 21
Lệnh SJMP nhảy tại chỗ dùng dấu $

• Đôi khi, ta muốn vi điều khiển dừng lại và chờ đợi tại
một vị trí trong chương trình.
• Ta có thể sử dụng
Dòng PC Opcode Mnemonic Toán hạng
17 0015 80FE HERE: SJMP HERE
18 0017 END
• Ta cũng có thể sử dụng lệnh dưới đây:
SJMP $

22
Địa chỉ tương đối (Relative Address)

• Địa chỉ đích cần phải ở trong khoảng -128 to +127


bytes so với giá trị PC hiện thời của bộ đếm chương
trình.
– Nhảy tiến: 0 ~ 127 (0 ~ 7FH)
– Nhảy lùi: -1 ~ -128 (FFH ~ 80H)
• Địa chỉ đích (thực) = PC + địa chỉ tương đối
– Ví dụ 1: PC=1001H, địa chỉ tương đối=40H địa chỉ
đích=1001H+40H=1041H
– Ví dụ 2: PC=1001H, địa chỉ tương đối=FFFEH (-210)
 địa chỉ đích=1001H+FFFEH=0FFFH

23
Lệnh nhảy tuyệt đối AJMP

• Lệnh nhảy tuyệt đối(Absolute jump - AJMP)


AJMP địa-chỉ-đích-11-bit
– Địa chỉ đích cần phải ở trong khoảng 2K bytes của bộ nhớ
chương trình (từ 0000H tới 07FFH).
– Mã lệnh (opcode) của AJMP có thể là 01H, 21H,…,E1H

Bits 15 13 12 8 7 0
ĐC đích opcode địa chỉ đích

00001
24
Ví dụ 3-6 (1)
Sử dụng file list dưới đây, kiểm tra lại sự tính toán các địa chỉ
nhảy tiến của trình dịch.
Line PC Opcode Mnemonic Operand
01 0000 ORG OOOO
02 0000 7800 MOV R0,#0
03 0002 7455 MOV A,#55H
04 0004 6003 JZ NEXT
05 0006 08 INC R0
06 0007 04 AGAIN: INC A
07 0008 04 INC A
08 0009 2477 NEXT: ADD A,#77H
09 000B 5005 JNC OVER
10 000D E4 CLR A
11 000E F8 MOV R0,A
12 OOOF F9 MOV R1,A
13 OO1O FA MOV R2,A
14 OO11 FB MOV R3,A
15 OO12 2B OVER: ADD A,R3
16 OO13 50F2 JNC AGAIN
17 0015 80FE HERE: SJMP HERE
18 OO17 END 25
Ví dụ 3-6 (2)
Giải:
Khi địa chỉ đích > PC  nhảy tiến

JZ NEXT (6003H)
Opcode=60; địa chỉ đích=NEXT=0009H; PC=0006H Dịch
Địa chỉ tương đối
= địa chỉ đích-PC=0009-0006=0003
Địa chỉ đích=0006H+0003H=0009H Chạy
JNC OVER (5005H)
Opcode=50; địa chỉ đích=OVER=0012H; PC=000DH Dịch

Địa chỉ tương đối


= địa chỉ đích-PC=0012-000D=0005
Địa chỉ đích=000DH+0005H=0012H Chạy

26
Ví dụ 3-7
Kiểm tra lại sự tính toán các địa chỉ nhảy lùi trong ví dụ 3-6.
Giải:
Địa chỉ đích < PC  nhảy lùi
JNC AGAIN (50F2H)
Opcode=50; địa chỉ đích=AGAIN=0007H; PC=0015H Dịch
Địa chỉ tương đối
= địa chỉ đích-PC=0007H-0015H=-14=FFF2H
Địa chỉ đích =0015H + FFF2H = 0007H Chạy

SJMP HERE (80FEH)


Opcode=80; địa chỉ đích=HERE=0015H; PC=0017H Dịch

Địa chỉ tương đối


= địa chỉ đích-PC=0015H-0017H=-2=FFFEH
Địa chỉ đích=0017H+FFFEH=0015H Chạy
27
3.2 Các lệnh gọi
chương trình con

28
Lệnh CALL

• Một lệnh chuyển điều khiển khác là lệnh CALL, lệnh


này sử dụng để gọi một thủ tục phụ (chương trình
con).
• Chương trình con thường được sử dụng để thực hiện
các tác vụ mà các tác vụ này cần được thực hiện
nhiều lần trong chương trình.
• Cách này làm cho chương trình có cấu trúc chặt chẽ
hơn và hơn nữa làm tiết kiệm không gian bộ nhớ. 
• Trong 8051 có 2 lệnh để gọi chương trình con:
– LCALL(long call)
– ACALL(absolute call) 29
Hình 3-1. Gọi chương trình con của 8051
Assembly
;Chương trình CHÍNH (MAIN) gọi chương trình con
ORG 0
MAIN: LCALL SUBR_1
LCALL SUBR_2
LCALL SUBR_3
HERE: SJMP HERE
;----kết thúc chương trình CHÍNH (MAIN)
SUBR_1: ....
....
RET
;----kết thúc chương trình con 1
SUBR_2: ....
....
RET
;----kết thúc chương trình con 2
SUBR_3: ....
....
RET
;----kết thúc chương trình con 3
END ;kết thúc file asm 30
Lưu đồ móc nối với chương trình con

Chương trình
chính

Chương trình con

 31
Lệnh LCALL (Long Call)

• Là lệnh 3-byte
– Byte đầu là opcode.
– Hai byte tiếp sau là địa chỉ đích.
• LCALL được sử dụng để nhảy tới một vị trí địa chỉ
bất kỳ trong 64K byte của không gian bộ nhớ chương
trình của 8051.

Bits 23 16 15 8 7 0
opcode = 12 địa chỉ đích

32
LCALL

• Nhảy tới địa chỉ mới


LCALL địa-chỉ-đích-16-bit
Dòng Addr. Opcode Mnemonic Toán hạng
04 0004 120300 LCALL DELAY
05 0007 74AA MOV A,#0AAH
Địa chỉ quay về Địa chỉ đích
...
11 0300 ORG 300H
12 0300 7DFF DELAY: MOV R5,#0FFH
...
15 0304 22 RET
– Opcode của LCALL là 12.
Chương trình con DELAY
– Địa chỉ đích là 0300.
– Địa chỉ quay về là 0007 33
LCALL và địa chỉ bộ nhớ

Chương trình
ROM addr. chính
0000 Chương trình
ROM addr. con DELAY
0300 MOV R5,#0FFH;

0004 LCALL DELAY;


0007 MOV A,#0AAH;
0009
địa chỉ 0304 RET;
quay về

34
Ví dụ 3-8
Viết một chương trình bật tắt các bit của cổng P1 bằng cách gửi
tới nó các giá trị 55H và AAH xen kẽ nhau. Đặt một khoảng thời
gian trễ giữa các lần gửi dữ liệu tới cổng P1.
Giải:
ORG 0
BACK: MOV A,#55H ;nạp vào A giá trị 55H
MOV P1,A ;gửi 55H tới cổng 1
LCALL DELAY ;trễ một thơi gian
MOV A,#0AAH ;nạp vào A giá trị AA
MOV P1,A ;gửi AAH tới cổng 1
LCALL DELAY
SJMP BACK ;lặp lại

;---chương trình con delay ở đây


ORG 300H ;đặt CTC delay ở địa chỉ 300H
DELAY:MOV R5,#OFFH ;R5=255(FF hex), số đếm
AGAIN:DJNZ R5,AGAIN ;dừng ở đây cho đến khi R5=0
RET ;quay về CT gọi nó (khi R5=0)
END ;kết thúc file
35
Ví dụ 3-9 (1/2)
Xem xét nội dung của stack sau khi thực hiện lệnh LCALL đầu tiên
trong chương trình dưới đây.
Giải: (a)
001 0000 ORG 0
002 0000 7455 BACK: MOV A,#55H ;nạp 55H vào A
003 0002 F590 MOV P1,A ;gửi 55H ra cổng 1
004 0004 120300 LCALL DELAY ;gọi delay
005 0007 74AA MOV A,#0AAH ;nạp AAH vào A
006 0009 F590 MOV P1,A ;gửi AAH ra cổng 1
007 000B 120300 LCALL DELAY
008 000E 80F0 SJMP BACK ;lặp lại tác vụ
009 0010
010 0010 ;---chương trình con
011 0300 ORG 300H
012 0300 DELAY:
013 0300 7DFF MOV R5,#OFFH ;R5=255
014 0302 DDFE AGAIN: DJNZ R5,AGAIN ;dừng ở đây
015 0304 22 RET ;quay về CT chính
016 0305 END ;kết thúc file
36
Ví dụ 3-9 (2/2)

Giải: (b)
Khi lệnh LCALL đầu được thực hiện, địa chỉ địa chỉ Nội
stack dung
của lệnh “MOV A,#0AAH” được cất vào
stack. Chú ý rằng byte thấp của địa chỉ được 0A
cất trước và byte cao được cất vào sau. Lệnh
09 00
cuối cùng của chương trình con được gọi
phải là lệnh RET để ra lệnh cho CPU lấy các 08 07
byte trên đỉnh của stack đưa tới PC và lại tiếp
tục thực hiện lệnh ở địa chỉ 07. Biểu đồ hình SP = 09
bên minh họa cho nội dung trong stack sau
khi thực hiện lệnh LCALL đầu tiên.

37
Phương thức gọi một chương trình con

• Sau khi thực hiện chương trình con, 8051 cần phải
biết nơi quay về trong chương trình chính.
• Phương thức gọi một chương trình con:
– Một chương trình con được gọi bằng các lệnh CALL.
– 8051 đẩy PC hiện thời vào stack.
– 8051 copy địa chỉ đích tới PC.
– 8051 nạp các lệnh từ vị trí địa chỉ mới.
– Khi lệnh RET được nạp, chương trình con kết thúc.
– 8051 lấy địa chỉ quay về từ stack.
– 8051 copy địa chỉ quay về tới PC.
– 8051 nạp các lệnh từ địa chỉ mới. 38
Ví dụ 3-10 (1/3)
Xem xét nội dung của stack sau khi thực hiện lệnh LCALL đầu
tiên trong chương trình sau đây.
01 0000 ORG 0
02 0000 7455 BACK: MOV A,#55H ;nạp 55H vào A
03 0002 F590 MOV P1,A ;gửi 55H ra port1
04 0004 7C99 MOV R4,#99H
05 0006 7D67 MOV R5,#67H
06 0008 120300 LCALL DELAY ;gọi trễ
07 000B 74AA MOV A,#0AAH ;nạp AAH vào A
08 000D F590 MOV P1,A ;gửi AAH ra port 1
09 000F 120300 LCALL DELAY
10 0012 80EC SJMP BACK ;lặp
11 0014 ;---chương trình con
12 0300 ORG 300H
13 0300 C004 DELAY:PUSH 4 ;PUSH RAM 04H
14 0302 C005 PUSH 5 ;PUSH RAM 05H
15 0304 7CFF MOV R4,#0FFH;R4=FFH
16 0306 7DFF NEXT: MOV R5,#0FFH;R5=255
17 0308 DDFE AGAIN:DJNZ R5,AGAIN
18 030A DCFA DJNZ R4,NEXT
19 030C D005 POP 5 ;POP tới RAM 05H
20 030E D004 POP 4 ;POP tới RAM 04H
21 0310 22 RET ;quay về CT chính
22 0311 END ;kết thúc file 39
Ví dụ 3-10 (2/3)
Giải:
Stack quản lý nơi CPU sẽ trở về sau khi hoàn thành chương trình
con. Vì lý do này, số các lệnh PUSH và lệnh POP phải luôn bằng
nhau trong bất kỳ một chương trình con nào.

Sau lệnh LCALL đầu Sau lệnh PUSH 4 Sau PUSH 5

0B 0B 0B 67 R5

0A 0A 99 R4 0A 99 R4

09 00 PCH 09 00 PCH 09 00 PCH

08 0B PCL 08 0B PCL 08 0B PCL

SP=09 SP=0A SP=0B


40
Ví dụ 3-10 (3/3)
Giải:
Cũng lưu ý rằng các lệnh PUSH và POP cần phải chỉ định địa chỉ
trực tiếp của thanh ghi được push hoặc pop.
Đây là nội dung stack

Sau lệnh POP 5 Sau POP 4 Sau lệnh RET

0B 0B 0B

0A 99 R4 0A 0A

09 00 PCH 09 00 PCH 09

08 0B PCL 08 0B PCL 08

SP=0A SP=09 SP=07


41
Lệnh ACALL(Absolute Call)

• Là lệnh 2-byte
– Địa chỉ đích phải trong khoảng 2K bytes của bộ nhớ
chương trình.
– Sử dụng ACALL có thể tiết kiệm không gian bộ nhớ hơn
so với sử dụng LCALL.
– Opcode (theo byte) của ACALL là 11H, 31H,…,F1H

Bits 15 13 12 8 7 0
đích opcode địa chỉ đích

10001
42
ACALL

• Nhảy tới một địa chỉ mới


ACALL địa-chỉ-đích-11-bit
Dòng PC Opcode Mnemonic Toán hạng
04 0004 7100 ACALL DELAY
05 0006 74 AA MOV A,#0AAH
...
11 0300 ORG 300H
12 0300 7DFF DELAY: MOV R5,#0FFH
...
15 0304 22 RET
– Opcode của ACALL là 10001B (5 bits).
– Địa chỉ đích là 0300H=0000 0011 0000 0000B (11 bits).
– Mã máy là 0111 0001 0000 0000 B = 7100H 43
Ví dụ 3-11
Lập trình viên sử dụng chip vi điều khiển Atmel AT89C1051 cho
sản phẩm của họ. Chip này chỉ có 1K bytes của bộ nhớ flash
ROM bên trong. Vậy sử dụng lệnh nào trong các lệnh LCALL và
ACALL là hữu ích hơn để lập trình cho chip này?

Trả lời:

Lệnh ACALL là hữu ích hơn vì nó là lệnh 2-byte. Nó sẽ tiết kiệm


được một byte cho mỗi lần sử dụng lệnh gọi chương trình con.

44
Ví dụ 3-12
Viết lại chương trình ở ví dụ 3-8 sao cho hiệu quả hơn.
Giải:
ORG 0
MOV A,#55H ;A=01010101B=55H
BACK: MOV P1,A ;đưa tgh. A tới port 1
ACALL DELAY ;gọi delay
CPL A ;A=10101010B=0AAH ;bù
SJMP BACK ;lặp vô hạn
;---đây là chương trình con delay
DELAY: MOV R5,#OFFH ;R5=255, số đếm
AGAIN: DJNZ R5,AGAIN ;nhảy nếu R5 giảm về 0
RET ;trở về CT gọi
END ;kết thúc

45
3.3 Tính toán
khoảng thời gian trễ

 Ví dụ 3-8 đã sử dụng một chương trình con tạo trễ.


 Làm thế nào tính toán chính xác khoảng thời gian trễ?
 Làm thế nào tạo ra các thời gian trễ khác nhau?

46
Chu kỳ máy(1/2)

• Để CPU thực hiện được một lệnh, nó cần một số chu


kỳ xung clock.
• Trong họ 8051, các chu kỳ xung clock này được quy
thành các chu kỳ máy (machine cycles).
– Ví dụ:Lệnh RET cần 2 chu kỳ máy
• 8051 có một bộ dao động bên trong chip để phát ra các
chu kỳ máy.
• Bộ dao động này cần các xung clock bên ngoài(từ bộ
dao động thạch anh)để chạy. 

47
Chu kỳ máy(2/2)

• Quan hệ giữa 2 bộ dao động:


– Độ dài của một chu kỳ máy bằng 12 chu kỳ dao động thạch
anh.
– Tần số của chu kỳ máy bằng 1/12 tần số dao động thạch
anh.
• Tần số của thạch anh ngoài có thể từ từ 4 MHz tới
30MHz.
• Thạch anh có tần số 11.0592MHz rất thường được sử
dụng để hệ thống của 8051 tương thích với cổng nối
tiếp của máy tính PC.
48
Bộ dao động của 8051 

C2 xung clock chu kỳ


ngoài Bộ dao máy (MC)
30pF XTAL2
động nội

C1
XTAL1 Chu kỳ của MC
30pF = 12 × chu kỳ dao động ngoài
Tần số của MC
GND
= 1/12 × tần số dao động ngoài
dao động ngoài

chu kỳ máy 49
Ví dụ 3-13
Dưới đây là tần số của các thạch anh sử dụng cho 3 hệ thống
8051. Tính chu kỳ của chu kỳ máy cho mỗi hệ thống.
(a) 11.0592 MHz (b) 16 MHz (c) 20 MHz

Giải:

(a) 11.0592MHz/12 = 921.6 KHz


chu kỳ máy (MC) là 1/921.6 KHz = 1.085 s (micro giây)
(b) Chu kỳ dao động = 1/16 MHz = 0.0625 s
chu kỳ máy (MC) = 0.0625 s ×12 = 0.75 s
(c) 20 MHz/12 = 1.66 MHz
MC = 1/1.66 MHz = 0.60 s

50
Ví dụ 3-14
Một hệ thống 8051 sử dụng dao động 11.0592 MHz, tính thời gian
để nó thực hiện mỗi lệnh dưới đây.
(a) MOV R3,#55 (b) DEC R3 (c) DJNZ R2, target
(d) LJMP (e) SJMP (f) NOP (g) MUL AB
Giải:
Chu kỳ máy cho hệ thống 11.0952 MHz là 1.085 s.
Tham khảo số chu kỳ máy cho mỗi lệnh của 8051, tính được.

Lệnh Số chu kỳ máy Thời gian thực hiện


(a) MOV R3,#55 1 1×1.085 s = 1.085 s
(b) DEC R3 1 1×1.085 s = 1.085 s
(c) DJNZ R2,target 2 2×1.085 s = 2.17 s
(d) LJMP 2 2×1.085 s = 2.17 s
(e) SJMP 2 2×1.085 s = 2.17 s
(f) NOP 1 1×1.085 s = 1.085 s
(g) MUL AB 4 4×1.085 s = 4.34 s
51
Ví dụ 3-15
Tìm khoảng thời gian trễ của chương trình con DELAY trong
chương trình dưới đây, nếu tần số của thạch anh là 11.0592 MHz.
MOV A,#55H
AGAIN: MOV P1,A
ACALL DELAY
CPL A
SJMP AGAIN
;---Time delay Chu kỳ máy
DELAY: MOV R3,#200 1
HERE: DJNZ R3,HERE 2
RET 2
Giải:
Thời gian trễ là
[1+(200 × 2)+2] × 1.085 s = 437.255 s.
52
Tính thời gian trễ

• Hai cách để tạo được thời gian trễ lớn là


– sử dụng lệnh NOP(Ví dụ 3-16)
– sử dụng vòng lặp trong vòng lặp (vòng lặp lồng nhau)
(Ví dụ 3-17)
• Chương trình con tạo trễ gồm 2 phần
– thiết đặt một bộ đếm(khởi tạo)
– vòng lặp
• Thông thường tính thời gian trễ dựa vào các lệnh bên
trong vòng lặp và bỏ qua các chu kỳ xung của các
lệnh bên ngoài vòng lặp.
53
Ví dụ 3-16
Tính thời gian trễ cho chương trình con dưới đây, giả sử tần số
của thạch anh là 11.0592 MHz.
Chu kỳ máy
DELAY: MOV R3,#250 1
HERE: NOP 1
NOP 1
NOP 1
NOP 1
DJNZ R3,HERE 2
RET 2
Giải:
Vòng lặp HERE & hai lệnh ngoài vòng lặp
{ [250 (1+1+1+1+2)] + 3 } × 1.085 s
= (1500+3) × 1.085 s = 1630.755 s.
54
Ví dụ 3-17
Với chu kỳ máy là 1.085 s, tìm thời gian trễ trong chương trình con
dưới đây.
DELAY: Machine Cycle
MOV R2,#200 1
AGAIN: MOV R3,#250 1
HERE: NOP 1
NOP 1
DJNZ R3,HERE 2
DJNZ R2,AGAIN 2
RET 2
Giải:
vòng lặp HERE = 250 (1+1+2)=1000 MCs
vòng lặp AGAIN = 200(1000+1+2) =200600 MCs
= 200600 × 1.085 s = 217651 s
toàn bộ chương trình con = 200603 MCs = 217654.255 s 55
Tính toán trễ cho các Version khác của 8051

• Hai yếu tố ảnh hưởng đến thời gian trễ


– Tần số của thạch anh
– Thiết kế của 8051

• Số chu kỳ xung clock trong một chu kỳ máy thay đổi


phụ thuộc vào các version khác nhau của họ IC 8051.
Chip/NSX Xung clock/Chu kỳ máy
Bảng AT89C51 Atmel 12
3-2
P89C54X2 Philips 6
DS5000 Dallas Semi 4
DS89C420/30/40/50 Dallas Semi 1
56
Ví dụ 3-18
Từ Bảng 3-2, tính chu kỳ máy (MC) trong các trường hợp dưới
đây nếu XTAL=11.0592 MHz.
(a) AT89C51 (b) P89C54X2 (c) DS5000 (d) DS89C4x0

Giải:
(a) 11.0592MHz/12 = 921.6 KHz
MC là 1/921.6 KHz = 1.085 s (micro giây) = 1085 ns
(b) 11.0592MHz/6 =1.8432 MHz, MC là 1/1.8432MHz = 542 ns
(c) 11.0592MHz/4 =2.7648 MHz, MC là 1/2.7648MHz = 360 ns
(d) 11.0592MHz/1 =11.0592 MHz, MC là 1/11.0592MHz =90 ns

57
Tính trễ cho Vi điều khiển DS89C4x0

• Số chu kỳ máy (MC) để thực hiện 1 lệnh là khác nhau


phụ thuộc vào các version khác nhau của 8051.
• Tham khảo các web site: www.maxim-ic.com hoặc
www.MicroDigitalEd.com
Instruction 8051 DS89C4x0
Bảng 3-3: So sánh MOV R3,#value 1 2
số chu kỳ máy của DEC Rx 1 1
8051 và DS89C4x0 DJNZ 2 4
LJMP 2 3
SJMP 2 3
NOP 1 1
MUL AB 4 9 58
Ví dụ 3-19
Cho một hệ thống sử dụng chip AT8051 và DS89C4x0 với thạch
anh 11.0592 MHz, tính thời gian để thực hiện mỗi lệnh dưới đây.
(a) MOV R3,#55 (b) DEC R3 (c) DJNZ R2, target
(d) LJMP (e) SJMP (f) NOP (g) MUL AB
Giải:
Chu kỳ máy của các hệ thống với xung clock 11.0952 MHz đã
được tính ở ví dụ 3-18. Bảng 3-3 cũng thể hiện số chu kỳ máy cho
mỗi lệnh.
Lệnh AT89C51 DS89C4x0
(a) MOV R3,#55 1×1085ns=1085ns 2×90ns=180ns
(b) DEC R3 1×1085ns=1085ns 1×90ns= 90ns
(c) DJNZ 2×1085ns=2170ns 4×90ns=360ns
(d) LJMP 2×1085ns=2170ns 3×90ns=270ns
(e) SJMP 2×1085ns=2170ns 3×90ns=270ns
(f) NOP 1×1085ns=1085ns 1×90ns= 90ns
(g) MUL AB 4×1085ns=4340ns 9×90ns=810ns
59
Ví dụ 3-20
Tính thời gian trễ của chương trình con dưới đây nếu nó chạy trên
chip DS89C420, giả sử tần số của thạch anh là 11.0592 MHz.
Số chu kỳ máy của DS89C420
DELAY: MOV R3,#250
HERE: NOP 1
NOP 1
NOP 1
NOP 1
DJNZ R3,HERE 4
RET
Giải:
Thời gian trễ trong vòng lặp HERE là
[250 (1+1+1+1+4)] × 90 ns = 2000 × 90 ns = 180 s
So sánh AT89C51 (ví dụ 3-16) với DS89C420: 1627 s/180 s = 9
60
Ví dụ 3-21 (1/2)
Viết một chương trình bật tắt các bit của cổng P1 sau mỗi 200ms
cho AT89C51. Giả sử rằng tần số của thạch anh là 11.0592 MHz.
Giải:
MOV A,#55H
AGAIN: MOV P1,A
ACALL DELAY
CPL A
SJMP AGAIN
DELAY: MOV R5,#2 1
HERE1: MOV R4,#180 1
HERE2: MOV R3,#255 1
HERE3: DJNZ R3,HERE3 2
DJNZ R4,HERE2 2
DJNZ R5,HERE1 2
RET 2 61
Ví dụ 3-21 (2/2)
Chúng ta chỉ tính đến thời gian trễ tiêu tốn bởi lệnh DJNZ.
Giá trị xấp xỉ của thời gian trễ bên trong vòng lặp HERE1 là:
vòng lặp HERE1 = 2 × 180 × 255 × 2MC × 1.085 s
• = 199206 s
Nếu muốn tính thời gian trễ chính xác, nên tính thêm trễ do các lệnh
MOV trong các vòng lặp HERE1/HERE2/HERE3 và vòng lặp
AGAIN .

62
Ví dụ 3-22(1/2)
Viết một chương trình bật tắt các bit của cổng P1 sau mỗi 200ms
(như ví dụ 3-21) cho chip DS89C4x0. Thạch anh là 11.0592 MHz.
Giải:
MOV A,#55H
AGAIN: MOV P1,A
ACALL DELAY
CPL A
SJMP AGAIN
DELAY: MOV R5,#9 2
HERE1: MOV R4,#242 2
HERE2: MOV R3,#255 2
HERE3: DJNZ R3,HERE3 4
DJNZ R4,HERE2 4
DJNZ R5,HERE1 4
RET 63
Ví dụ 3-22 (2/2)
Nếu chỉ tính trễ do lệnh DJNZ.
Giá trị xấp xỉ của thời gian trễ bên trong vòng lặp HERE1 là:
vòng lặp HERE1 = 9 × 242 × 255 × 4MC × 90 ns
= 199940 ns
Cần chính xác hơn, cộng thêm trễ do các lệnh MOV trong các vòng
HERE1/HERE2/HERE3 và AGAIN .

64
Bộ định thời (Timer)
• Việc sử dụng các lệnh để phát ra thời gian trễ không
phải là phương pháp thiết thực nhất.
• Để đạt được thời gian trễ chính xác hơn, chúng ta sử
dụng bộ định thời (timer) sẽ trình bày ở phần sau.
• Khi cần ứng dụng yêu cầu thời gian trễ chính xác đối
với bộ vi điều khiển 8051, ta phải sử dụng
oscilloscope để đo lường chính xác khoảng thời gian
trễ.

65

You might also like