You are on page 1of 96

Chương 9

Lập trình cho Timer của 8051

1
9.1 Lập trình cho Bộ định thời (Timer)
của 8051

2
Kiến trúc bên trong của 8051

Các ngắt ngoài


On-chip Timer/Counter

Interrupt ROM for


On-chip Timer 1 Các đầu
Control program
RAM Timer 0 vào bộ
code
đếm

CPU

Bus Serial
4 I/O Ports
OSC Control Port

P0 P1 P2 P3 TxD RxD
Address/Data
Hình 1-2. Sơ đồ khối bên trong Vi điều khiển 8051
3
Các Timer /Counter

• 8051 có 2 bộ timer/counter: timer/counter 0 và


timer/counter 1. Chúng có thể được sử dụng làm:
1. Bộ định thời (timer) để làm bộ tạo thời gian trễ.
– Nguồn xung clock là từ bộ dao động thạch anh bên trong
8051.
2. Bộ đếm sự kiện (counter).
– Nguồn xung bên ngoài đưa vào một chân đầu vào để
đếm số lượng sự kiện và được chứa trong các thanh ghi.
– Các xung này thể hiện số người đi qua cửa, hoặc số vòng
quay bánh xe, hoặc một sự kiện nào đó có thể chuyển đổi
được thành dạng xung.
4
Timer

• Các bộ timer của 8051 sử dụng nguồn xung bằng


1/12 tần số của dao động thạch anh (XTAL) làm
đầu vào của các timer.
• Bởi vì đầu vào của timer là xung chuẩn, là một
sóng vuông có chu kỳ cố định, ta có thể đếm số
xung để tính ra thời gian trễ.
8051
bộ dao động
÷ 12 Timer
XTAL
P1 tới
LCD
TH0
Set
TL0
Timer 0 5
Counter

• Để đếm số lượng sự kiện


• Nguồn xung ngoài đưa vào chân Tx (x=0 hoặc 1).
• Sử dụng Tx để ký hiệu cho T0 hoặc T1.
– Chân đầu vào xung đếm T0 (P3.4) của Bộ đếm 0
– Chân đầu vào xung đếm T1 (P3.5) của Bộ đếm 1
8051
TH0
P1 tới
TL0
LCD
Vcc P3.4
SW T0
6
Hình 4-1. Sơ đồ chân của 8051
PDIP/Cerdip

P1.0 1 40 Vcc
P1.1 2 39 P0.0(AD0)
P1.2 3 38 P0.1(AD1)
P1.3 4 8051 37 P0.2(AD2)
P1.4 5 36 P0.3(AD3)
P1.5 6 (8031) 35 P0.4(AD4)
P1.6 7 34 P0.5(AD5)
P1.7 8 33 P0.6(AD6)
RST 9 32 P0.7(AD7)
(RXD)P3.0 10 31 EA/VPP
(TXD)P3.1 11 30 ALE/PROG
(INT0)P3.2 12 29 PSEN
(INT1)P3.3 13 28 P2.7(A15)
(T0)P3.4 14 27 P2.6(A14)
(T1)P3.5 15 26 P2.5(A13)
(WR)P3.6 16 25 P2.4(A12)
(RD)P3.7 17 24 P2.3(A11)
XTAL2 18 23 P2.2(A10)
XTAL1 19 22 P2.1(A9)
GND 20 21 P2.0(A8) 7
Hình 9-8: Timer/Counter 0

đầu vào timer

XTAL
÷ 12
oscillator
C/T = 0

TH0 TL0
C/T = 1
đầu vào counter
Chân T0
1:start
Chân 3.4
TR0 TF0
0:stop

Gate 1. giám sát bằng JNB


2. ngắt
INT0
Chân 3.2
điều khiển bằng
phần cứng Sec 9.2  8
Hình 9-9: Timer/Counter 1

đầu vào timer

XTAL
÷ 12
oscillator
C/T = 0

TH1 TL1
C/T = 1
đầu vào counter
Chân T1
1:start
Chân 3.5 TR1
0:stop TF1

Gate 1. Giám sát bằng JNB


2. ngắt
INT1 Pin
Pin 3.3
điều khiển phần cứng

9
Các thanh ghi sử dụng cho Timer/Counter

• TH0, TL0 (Các thanh ghi của Timer 0)


• TH1, TL1 (Các thanh ghi của Timer 1)
• TMOD (Thanh ghi chế độ Timer)
• TCON (Thanh ghi điều khiển Timer)
• Vì 8052 có 3 bộ timer/counter, nên định dạng của các
thanh ghi điều khiển này khác nhau.
– T2CON (thanh ghi điều khiển Timer), TH2 và TL2 chỉ sử
dụng cho 8052.

10
Các thanh ghi cơ sở của Timer

• Các bộ định thời Timer 0 và Timer 1 có độ rộng 16


bit.
– Mỗi bộ định thời 16-bit có thể được truy cập bằng 2 thanh
ghi riêng rẽ chứa byte thấp và và byte cao.
– Timer 0: các thanh ghi TH0 & TL0
• Byte cao của Timer 0, byte thấp của Timer 0
– Timer 1: các thanh ghi TH1 & TL1
• Byte cao của Timer 1, byte thấp của Timer 1
– Các thanh ghi này chứa
• Thời gian trễ của timer
• Số lượng sự kiện của counter
11
Các thanh ghi của Timer

TH0 TL0

D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

Timer 0

TH1 TL1

D15 D14 D13 D12 D11 D10 D9 D8 D7 D6 D5 D4 D3 D2 D1 D0

Timer 1
12
Thanh ghi TCON (1/2)

• Thanh ghi điều khiển Timer: TCON


– 4 bit trên cho timer/counter, 4 bit dưới cho ngắt (interrupt)
• TR (bit điều khiển hoạt động)
– TR0 của Timer/counter 0; TR1 của Timer/counter 1.
– TRx được thiết lập bằng phần mềm để bật các
timer/counter chạy hoặc ngừng.
• TRx=0: off (stop)
• TRx=1: on (start)
(MSB) (LSB)
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Timer 1 Timer0 cho Interrupt
13
Thanh ghi TCON (2/2)

• TF (cờ timer, cờ điều khiển)


– TF0 của timer/counter 0; TF1 của timer/counter 1.
– TFx giống như cờ carry. Ban đầu, TFx=0. Khi thanh ghi
TH-TL chuyển từ FFFFH tới 0000, thì TFx được set lên 1.
• TFx=0 : chưa tới cực đại
• TFx=1: đạt cực đại

(MSB) (LSB)
TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Timer 1 Timer0 for Interrupt
14
Bảng 9-2: Các lệnh cho thanh ghi điều
khiển Timer
Với timer 0
SETB TR0 = SETB TCON.4
CLR TR0 = CLR TCON.4

SETB TF0 = SETB TCON.5


CLR TF0 = CLR TCON.5
Với timer 1
SETB TR1 = SETB TCON.6
CLR TR1 = CLR TCON.6

SETB TF1 = SETB TCON.7


CLR TF1 = CLR TCON.7

TCON: Timer/Counter Control Register


TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 15
Thanh ghi TMOD

• Thanh ghi chế độ Timer: TMOD


MOV TMOD,#21H
– Là thanh ghi 8-bit
– Để thiết lập chế độ làm việc cho các timer
• 4 bit dưới để thiết lập cho Timer 0 (Đặt là 0000 nếu không sử dụng)
• 4 bit trên để thiết lập cho Timer 1 (Đặt là 0000 nếu không sử dụng)
– Không được định địa chỉ bit

(MSB) (LSB)
GATE C/T M1 M0 GATE C/T M1 M0
Timer 1 Timer 0
16
Hình 9-3. Thanh ghi TMOD

GATE Bit điều khiển cổng. Khi GATE được set, Timer/counter
chỉ được cho phép hoạt động nếu cả chân INTx ở mức
cao và chân điều khiển TRx được set. Khi GATE bị xóa,
timer được cho phép hoạt động chỉ cần bit TRx được set.
C/T Bit lựa chọn làm Timer hoặc Counter. Đặt = 0 để sử dụng
làm timer (nguồn xung từ bộ dao động nội). Đặt = 1 để
sử dụng làm counter (nguồn xung từ chân Tx vào).
M1 Bit 1 để chọn chế độ
M0 Bit 0 để chọn chế độ

(MSB) (LSB)
GATE C/T M1 M0 GATE C/T M1 M0
Timer 1 Timer 0 17
C/T (Counter/Timer)

• Bit này dùng để chọn chức năng làm bộ định thời để


tạo thời gian trễ hoặc làm bộ đếm sự kiện.
• C/T = 0 : timer
• C/T = 1 : counter

18
Hình 9-8: Timer/Counter 0

đầu vào timer

XTAL
÷ 12
oscillator
C/T = 0

TH0 TL0
C/T = 1
đầu vào counter
Chân T0
1:start
Chân 3.4
TR0 TF0
0:stop

Gate 1. giám sát bằng JNB


2. ngắt
INT0
Chân 3.2
điều khiển bằng
phần cứng Sec 9.2  19
Gate

• Các timer có các cách để điều khiển chạy và dừng.


– GATE=0
• Điều khiển từ bên trong
• Start và stop của timer được điều khiển bằng phần mềm.
• Thiết lập/xóa bit TR0 (hoặc TR1) để start/stop timer.
– GATE=1
• Điều khiển từ bên ngoài
• Dùng phương pháp cứng để start và stop timer bằng phần mềm kết
hợp với một tín hiệu bên ngoài.
• Timer/counter được phép hoạt động chỉ khi chân INT0 (hoặc INT1)
có sự chuyển lên mức 1 và chân điều khiển TR0 (hoặc TR1) đã
được set lên 1.
• INT0: P3.2, chân 12; INT1: P3.3, chân 13. 20
M1, M0

• M0 và M1 để chọn chế độ làm việc (mode) cho các


timer 0 & 1.
M1 M0 Chế độ Chế độ làm việc
0 0 0 Chế độ timer 13-bit
8-bit THx + 5-bit TLx (x= 0 hoặc 1)
0 1 1 Chế độ timer 16-bit
8-bit THx + 8-bit TLx (x= 0 hoặc 1)
1 0 2 Chế độ tự nạp lại 8-bit
Ở chế độ tự nạp lại 8-bit cho timer/counter;
THx giữ giá trị cần nạp lại để nạp lại vào TLx
mỗi khi TLx tràn.
21
1 1 3 Chế độ timer riêng rẽ
Ví dụ 9-1
Chỉ ra chế độ nào và bộ timer nào sẽ được chỉ định ở mỗi lệnh
dưới đây.
(a) MOV TMOD,#01H (b) MOV TMOD,#20H
(c) MOV TMOD,#12H
Giải: (MSB) (LSB)
GATE C/T M1 M0 GATE C/T M1 M0
Timer 1 Timer 0

timer 1 timer 0

(a) TMOD = 00000001, chế độ 1 của timer 0 được chọn.


(b) TMOD = 00100000, chế độ 2 của timer 1 được chọn.
(c) TMOD = 00010010
chế độ 2 của timer 0, và chế độ 1 của timer 1 được chọn.
22
Ví dụ 9-2 
Tìm tần số của xung clock cấp cho timer và chu kỳ của nó trong
các hệ thống dùng 8051 có các thạch anh với tần số dao động sau
đây.
(a) 12 MHz (b) 16 MHz (c) 11.0592 MHz
Giải:
Bộ dao động
XTAL
÷ 12

(a) 1/12 × 12 MHz = 1 MHz và T = 1/1 MHz = 1 s


(b) 1/12 × 16 MHz = 1.333 MHz và
T = 1/1.333 MHz = 0.75 s
(c) 1/12 × 11.0592 MHz = 921.6 KHz;
T = 1/921.6 KHz = 1.085 s 23
Ví dụ 9-3

Tìm giá trị cho TMOD nếu ta muốn lập trình cho timer 0 ở chế độ 2,
sử dụng bộ dao động XTAL của 8051 làm nguồn xung clock, và
dùng lệnh để start và stop bộ timer.

(MSB) (LSB)
Giải: GATE C/T M1 M0 GATE C/T M1 M0
Timer 1 Timer 0

TMOD= 0000 0010 Timer 1 không sử dụng.


Timer 0, chế độ 2,
C/T = 0 để sử dụng nguồn xung clock của
XTAL (timer)
gate = 0 để sử dụng phương pháp điều khiển
start and stop bên trong (bằng phần mềm).
24
Chế độ 1 của Timer (Mode 1)

• Dưới đây, chúng ta sử dụng timer 0 để minh họa.


• Bộ định thời (timer) 16-bit (TH0 và TL0)
• TH0-TL0 được tăng liên tục khi TR0 được set lên 1.
Và TH0-TL0 sẽ ngừng tăng khi TR0 được xóa.
• Bộ timer làm việc với xung clock bên trong hệ thống.
Tức là, cứ sau 12 xung clock của bộ dao động XTAL,
bộ timer sẽ đếm lên 1 đơn vị.
• Khi bộ định thời (TH0-TL0) đạt đến giá trị cực đại
(maximum) là FFFFH, nó sẽ quay về 0000, khi đó cờ
TF0 được set lên 1.
25
• Lập trình viên nên kiểm tra TF0 để dừng timer 0.
Lập trình cho Chế độ 1

XTAL
oscillator
÷ 12 như MC
của 89C51

C/T = 0

TH TL TF
Start timer cờ tràn
TF chuyển lên mức
TR
cao khi FFFF 0
26
Các bước thực hiện với Chế độ 1 (1/3)

1. Chọn chế độ 1 cho timer 0


– MOV TMOD,#01H
2. Thiết đặt giá trị ban đầu tới TH0 và TL0.
– MOV TH0,#0FFH
– MOV TL0,#0FCH
3. Tốt nhất nên xóa cờ tràn: TF0=0.
– CLR TF0
4. Khởi động (start) bộ timer.
– SETB TR0

27
Các bước thực hiện với Chế độ 1 (2/3)

5. VĐK 8051 bắt đầu đếm lên bằng cách tăng giá trị của
TH0-TL0.
TH0-TL0= FFFCH,FFFDH,FFFEH,FFFFH,0000H

TR0=1 TR0=0
TH0 TL0
Start timer Stop timer

FFFC FFFD FFFE FFFF 0000


Tràn
TF0=0 TF0=0 TF0=0 TF0=0 TF0=1

TF0 Giám sát TF0 cho đến khi TF0=1


28
Các bước thực hiện với Chế độ 1(3/3)

6. Khi TH0-TL0 chuyển từ FFFFH tới 0000, 8051 sẽ


set TF0=1.
– TH0-TL0= FFFEH, FFFFH, 0000H ( TF0=1)
7. Giám sát cờ timer (TF) để kiểm tra nếu nó được set.
– AGAIN: JNB TF0, AGAIN
8. Xóa TR0 để stop quá trình đếm.
– CLR TR0
9. Xóa cờ TF để sử dụng cho lần tiếp sau.
– CLR TF0

29
Giá trị đếm thiết đặt ban đầu

• Giá trị đếm ban đầu = FFFC.


• Số lần đếm = FFFFH-FFFCH+1 = 4
– Ta cộng thêm 1 bởi vì nó cần thêm 1 xung clock để chuyển
từ FFFF tới 0, khi đó cờ TF mới được set lên 1.
• Thời gian trễ = 4 chu kỳ máy (MC) đối với 89C51
• Nếu MC=1.085 s, thì thời gian trễ = 4.34 s
• Hình 9-4 trình bày công thức để tính thời gian trễ sử
dụng chế độ 1 của timer với tần số thạch anh
XTAL=11.0592 MHz.
• Các ví dụ 9-4 đến 9-9 trình bày cách tính và tạo ra
thời gian trễ bằng timer. 30
Hình 9-4. Tính toán trễ cho Timer với
XTAL = 11.0592 MHz 

(a) dạng hex (b) dạng decimal

(FFFF – YYXX + 1) × 1.085 s Đổi các giá trị YYXX của thanh
trong đó YYXX là các giá trị ghi TH, TL thành dạng thập
thiết đặt ban đầu cho TH, TL. phân để được một số thập phân
Chú ý rằng các trị số YYXX NNNNN, sau đó lấy
biểu diễn theo dạng hex. (65536 – NNNNN) × 1.085 s

31
Tính các giá trị cho Timer

• Giả sử XTAL = 11.0592 MHz .


• Làm thế nào để tính được các giá trị cần cho TH, TL?
– Chia thời gian trễ muốn có cho 1.085 s.
20ms ÷ 1.085 s = 18433
– Lấy 65536 –n, với n là số thập phân vừa tính được ở Bước
1 trên.
65536-18433=47103=B7FFH
– Đổi kết quả ở Bước 2 sang dạng hex, trong đó yyxx là giá
trị ban đầu để nạp tới các thanh ghi của timer.
– Nạp TH = yy và TL = xx.
TH=B7H, TL=FFH
• Xem Ví dụ 9-10
32
Ví dụ 9-4 (1/4)
Trong chương trình dưới đây, ta tạo ra một sóng vuông có hệ số lấp
đầy 50% (có phần mức cao và mức thấp bằng nhau) trên chân P1.5.
Dùng Timer 0 để tạo thời gian trễ.
Phân tích chương trình.

;mỗi vòng lặp là một nửa xung


MOV TMOD,#01 ;Timer 0,mode 1(16-bit)
HERE: MOV TL0,#0F2H ;Giá trị Timer = FFF2H
MOV TH0,#0FFH
P1.5
CPL P1.5
ACALL DELAY 50% 50%
SJMP HERE Toàn bộ xung
33
Ví dụ 9-4 (2/4)
;tạo trễ bằng sử dụng timer 0
DELAY:
SETB TR0 ;start timer 0
AGAIN:JNB TF0,AGAIN
CLR TR0 ;stop timer 0
CLR TF0 ;xóa cờ timer 0
RET

FFF2 FFF3 FFF4 FFFF 0000

TF0 = 0 TF0 = 0 TF0 = 0 TF0 = 0 TF0 = 1


34
Ví dụ 9-4 (3/4)
Giải:
Trong chương trình trên lưu ý các bước sau.
1. Nạp cho TMOD = 0000 0001.
2. Nạp FFF2H vào TH0 – TL0.
3. P1.5 được lật đi lật lại giữa 2 mức cao và thấp của xung.
4. Gọi chương trình con DELAY tạo trễ bằng sử dụng timer.
5. Trong ctc DELAY, khởi động timer 0 bằng lệnh “SETB TR0”.
6. Timer 0 đếm lên theo từng xung clock, xung này được cung cấp
từ bộ dao động thạch anh.
Khi timer đếm lên, nó qua lần lượt các trạng thái FFF3, FFF4, FFF5,
FFF6, FFF7, FFF8, FFF9, FFFA, FFFB, FFFC, FFFFD, FFFE,
FFFFH. Thêm 1 xung nữa tới, nó chuyển tới 0000, làm cờ timer
được thiết lập (TF0 = 1). Ở thời điểm này, lệnh JNB hoàn
thành. 35
Ví dụ 9-4 (4/4)
7. Timer 0 được dừng bằng lệnh “CLR TR0”. Chương trình con
DELAY kết thúc, và quá trình được lặp lại.
8. Nhớ rằng để xóa cờ TF0 bằng lệnh “CLR TF0”.

Chú ý rằng để lặp lại quá trình, ta cần phải nạp lại giá trị cho các
thanh ghi TL và TH, và khởi động timer một lần nữa (trong
chương trình con).

36
Ví dụ 9-5
Trong Ví dụ 9-4, tính toán khoảng thời gian trễ trong chương trình
con DELAY tạo ra bằng timer. Giả sử rằng XTAL = 11.0592
MHz.
Giải:
Bộ timer làm việc bằng xung clock bên trong hệ thống.
tần số của xung = 11.0592/12 = 921.6 KHz
chu kỳ máy = 1 /921.6 KHz = 1.085 s (microsecond)
số lần đếm = FFFFH – FFF2H +1 = 14 (dạng thập phân).
thời gian trễ = số đếm × 1.085 s = 14 × 1.085 s = 15.19 s
cho một nửa xung phát ra.
Với toàn bộ cả chu kỳ của xung, đó là T = 2 × 15.19 s = 30.38 s.

37
Ví dụ 9-6 (1/2)

Trong Ví dụ 9-5, tính toán tần số chính xác của sóng vuông phát
ra trên chân P1.5.

Giải:

Theo tính toán ở Ví dụ 9-5, ta không tính đến thời gian tiêu tốn do
các lệnh khác trong vòng lặp.
Để tính được thời gian chính xác hơn, ta phải cộng thêm vào các
chu kỳ máy như dưới đây.

38
Ví dụ 9-6 (2/2)
HERE: MOV TL0,#0F2H 2
MOV TH0,#0FFH 2
CPL P1.5 1
ACALL DELAY 2
SJMP HERE 2
;----------trễ sử dụng timer 0
DELAY:
SETB TR0 1
AGAIN: JNB TF0,AGAIN 14
CLR TR0 1
CLR TF0 1
RET 2 0
Total 28
T = 2 × 28 × 1.085 s = 60.76 s, và F = 16458.196 Hz.
39
Ví dụ 9-7 (1/2)
Tính thời gian trễ được tạo ra bằng timer 0 trong đoạn lệnh dưới
đây, sử dụng cả 2 cách như ở Hình 9-4. Không cần tính thêm thời
gian tiêu tốn do các lệnh khác.
CLR P2.3
MOV TMOD,#01 ;Timer 0,mode 1(16-bit)
HERE: MOV TL0,#3EH ;Timer value=B83EH
MOV TH0,#0B8H
SETB P2.3
SETB TR0 ;khởi động timer 0
AGAIN:JNB TF0,AGAIN
CLR TR0
CLR TF0 P2.3
CLR P2.3
40
Ví dụ 9-7 (2/2)
Giải:
2 cách (a) hoặc (b).
(a) (FFFF – B83E + 1) = 47C2H = 18370 dạng thập phân và
18370 × 1.085 s = 19.93145 ms.
(b) Do TH-TL = B83EH = 47166 (dạng thập phân) ta có
65536 – 47166 = 18370. Điều này có nghĩa là bộ định thời
đếm từ B83EH tới FFFF, sau đó nó tràn qua 0 sẽ trải qua tổng
cộng 18370 chu kỳ xung clock, trong đó mỗi xung clock là
1.085s. Do đó, ta có 18370 × 1.085 s = 19.93145 ms là độ
rộng của xung phát ra.

41
Ví dụ 9-8 (1/2)

Thay đổi giá trị trong TL và TH ở Ví dụ 9-7 để nhận được thời gian
trễ lớn nhất có thể có được. Tính thời gian trễ bằng ms. Trong tính
toán, bỏ qua thời gian tiêu tốn do các lệnh khác trong vòng lặp.
Giải:
Cho TH0=TL0=0 có nghĩa rằng bộ timer sẽ đếm từ 0000 đến FFFF,
và tràn về 0000 để set cho cờ TF0.
Kết quả là, nó đếm qua tổng số 65536 số đếm. Do đó, ta có
thời gian trễ = (65536 – 0) × 1.085 s = 71.1065 ms.

42
Ví dụ 9-8 (2/2)

CLR P2.3 ;xóa P2.3


MOV TMOD,#01 ;Timer 0,mode1(16-bit)
HERE: MOV TL0,#0 ;TL0=0, byte thấp
MOV TH0,#0 ;TH0=0, byte cao
SETB P2.3 ;SET mức cao cho P2.3
SETB TR0 ;start timer 0
AGAIN: JNB TF0,AGAIN ;giám sát cờ timer 0
CLR TR0 ;stop timer 0
CLR TF0 ;xóa cờ timer 0
CLR P2.3
43
Ví dụ 9-9 (1/2) 
Chương trình sau đây phát ra một sóng vuông liên tục ở chân P1.5
sử dụng timer 1 để tạo trễ. Tính tần số của sóng vuông này nếu
XTAL = 11.0592 MHz. Trong tính toán bỏ qua thời gian tiêu tốn
của các lệnh trong vòng lặp.
MOV TMOD,#10H ;timer 1, mode 1
AGAIN:MOV TL1,#34H ;timer value=7634H
MOV TH1,#76H
SETB TR1 ;start
BACK: JNB TF1,BACK
CLR TR1 ;stop
CPL P1.5 ;cho nửa xung tiếp
CLR TF1 ;xóa cờ timer 1
SJMP AGAIN ;nạp lại timer 1
44
Ví dụ 9-9 (2/2) 

Giải:
Ở chế độ 1, chương trình cần phải nạp lại cho các thanh ghi TH1,
TL1 mỗi khi khởi động timer nếu ta muốn có một sóng liên tục.
FFFFH – 7634H + 1 = 89CCH = 35276 số đếm
Nửa chu kỳ = 35276 × 1.085 s = 38.274 ms
Cả chu kỳ = 2 × 38.274 ms = 76.548 ms
Tần số = 1/ 76.548 ms = 13.064 Hz.

45
Ví dụ 9-10 (1/2) 

Giả sử rằng XTAL = 11.0592 MHz.


Ta cần nạp giá trị nào tới các thanh ghi của timer nếu ta muốn có
thời gian trễ là 5 ms (mili giây)?
Viết chương trình cho timer 0 để tạo ra một xung độ rộng 5 ms
trên chân P2.3.

Giải:
XTAL = 11.0592 MHz  MC = 1.085 s.
5 ms / 1.085 s = 4608 MCs.
Để có được thời gian trễ đó ta cần nạp vào TL0 và TH0 giá trị
65536 – 4608 = 60928 = EE00H.
Do đó, ta có TH0 = EE và TL0 = 00. 46
Ví dụ 9-10 (2/2) 

CLR P2.3
MOV TMOD,#01 ;Timer 0,mode 1
HERE: MOV TL0,#0
MOV TH0,#0EEH
SETB P2.3 ;SET P2.3 mức cao
SETB TR0 ;start
AGAIN: JNB TF0,AGAIN
CLR TR0 ;stop
CLR TF0 5ms
CLR P2.3 P2.3
47
Ví dụ 9-11 (1/2) 

Giả sử rằng XTAL = 11.0592 MHz, viết một chương trình để phát
ra một sóng vuông có tần số 2 kHz trên chân P1.5.
Giải:
Ví dụ này tương tự Ví dụ 9-10, chỉ khác là ta cần lật trạng thái
của bit để phát ra sóng vuông. Xem các bước sau đây.
(a) Chu kỳ của sóng vuông = 1 / tần số = 1 / 2 kHz = 500 s.
(b) Nửa chu kỳ = 500 s /2 = 250 s.
(c) 250 s / 1.085 s = 230
65536 – 230 = 65360 = FF1AH.
(d) TL1 = 1AH và TH1 = FFH

48
Ví dụ 9-11 (2/2) 

MOV TMOD,#10H ;timer 1, mode 1


AGAIN:MOV TL1,#1AH ;timer value = FF1AH
MOV TH1,#0FFH
SETB TR1 ;start
BACK: JNB TF1,BACK
CLR TR1 ;stop
CPL P1.5
CLR TF1 ;xóa cờ timer 1
SJMP AGAIN

49
Ví dụ 9-12 (1/2) 

Dùng XTAL = 11.0592 MHz, viết một chương trình để phát ra


một sóng vuông tần số 50 Hz trên chân P2.3.

Giải:
Theo các bước sau đây.
(a) Chu kỳ của sóng vuông = 1 / 50 Hz = 20 ms.
(b) Mỗi phần mức cao hoặc thấp của sóng vuông = 10 ms.
(c) 10 ms / 1.085 s = 9216
65536 – 9216 = 56320 dạng thập phân = DC00H dạng hex.
(d) TL1 = 00H và TH1 = DCH.

50
Ví dụ 9-12 (2/2)

MOV TMOD,#10H ;timer 1, mode 1


AGAIN: MOV TL1,#00 ;Timer value = DC00H
MOV TH1,#0DCH
SETB TR1 ;start
BACK: JNB TF1,BACK
CLR TR1 ;stop
CPL P2.3
CLR TF1 ;xóa cờ timer 1
SJMP AGAIN ;nạp lại timer do
;chế độ 1 không tự
;động nạp lại
51
Ví dụ 9-13
Kiểm tra chương trình dưới đây và tính thời gian trễ bằng giây.
Bỏ qua thời gian tiêu tốn do các lệnh trong vòng lặp.
MOV TMOD,#10H
MOV R3,#200
AGAIN: MOV TL1,#08
MOV TH1,#01
SETB TR1
BACK: JNB TF1,BACK
CLR TR1
CLR TF1
DJNZ R3,AGAIN
Giải:
TH1-TL1 = 0108H = 264 dạng thập phân
65536 – 264 = 65272.
Một lần trễ của timer = 65272 × 1.085 s = 70.820 ms
Tổng thời gian trễ = 200 × 70.820 ms = 14.164024 s 52
Chế độ 0 của Timer (Mode 0)

• Chế độ 0 được sử dụng để tương thích với MSC-48


• Chế độ 0 là giống hoàn toàn chế độ 1 ngoại trừ nó là
một bộ định thời 13-bit thay vì 16-bit.
• Bộ đếm có thể đếm giá trị từ 0000 đến 1FFF
– 213-1= 2000H-1=1FFFH
• Khi timer đạt cực đại là 1FFFH, nó tràn tới 0000, và
TF0 được thiết lập lên 1.
TH0 TL0

D15 D14 D13 D12 D11 D10 D9 D8 D7  


D6 D5 D4 D3 D2 D1 D0
53
Timer 0
Chế độ 3 của Timer (Mode 3)

• Với Timer/Counter 0
– Sử dụng làm bộ định thời Timer:
• TH0 và TL0 có thể làm các bộ timer 8-bit.
– Sử dụng làm bộ đếm Counter:
• TL0 có thể làm một bộ counter 8-bit.
• Với Timer/Counter 1
– Không sử dụng được

54
Chế độ 2 của Timer (Mode 2)

• Timer 8-bit
– TL0 được tăng lên (hoặc tràn) liên tục khi TR0=1.
• Tự nạp lại
– TH0 tự động nạp giá trị cho TL0 khi TL0=00H.
– TH0 không thay đổi giá trị.
– Ta cần xóa TF0 sau khi TL0 tràn.

• Xem các Ví dụ 9-14 đến 9-16

55
Lập trình chế độ 2

XTAL
oscillator
÷ 12

C/T = 0

cờ tràn
TL TF
reload TF chuyển lên mức
TR TH cao khi FF 0
56
Các bước thực hiện của Chế độ 2 (1/3)

1. Chọn chế độ 2 timer 0


– MOV TMOD,#02H
2. Thiết đặt giá trị ban đầu cho TH0.
– MOV TH0,#FCH
3. Xóa cờ TF0=0.
– CLR TF0
4. Start bộ timer.
– SETB TR0
– Chú ý rằng lệnh SETB TR0 không nạp giá trị của TH0
vào TL0. Vì vậy TL0 vẫn là 00H.
57
Các bước thực hiện của Chế độ 2 (2/3)

5. VĐK 8051 bắt đầu đếm lên bằng sự tăng của TL0.
– TL0= ..., FCH,FDH,FEH,FFH,FCH
TR0=1 TH0=FCH TL0=FCH TF0=1
tự nạp lại xóa TF0
Start timer

00 01 ... FE FF FC FD
tràn 00H
TF0 = 0 TF0 = 0 TF0 = 0 TF0 = 0 TF0 = 1 TF0 = 1 TF0 =0
TH0=FCH
tràn 00H
TL0=00H
FE FF FC FD

TF0 = 0 TF0 = 0 TF0 = 1 TF0 = 1 58


tự nạp lại: TL= FCH tức thì
Các bước thực hiện của Chế độ 2 (3/3)

6. Khi TL0 chuyển từ FFH tới 00, 8051 set TF0=1.


Lúc đó, TL0 được tự động nạp lại bằng giá trị chứa
trong TH0. 00H
– TL0= FCH, FDH, FEH, FFH, FCH(TF0=1)
– 8051 tự nạp lại TL0=TH0=FCH.
– Quay lại Bước 6 (tức là, TL0 được tiếp tục tăng).
• Chú ý rằng ta cần phải xóa TF0 khi TL0 tràn. Như
vậy, ta có thể giám sát TF0 trong quá trình tiếp sau.
• Xóa TR0 để dừng quá trình đếm.

59
Ví dụ 9-14 (1/2)

Dùng XTAL = 11.0592 MHz, tính


(a) tần số của sóng vuông được phát ra trên chân P1.0 ở chương
trình dưới đây
(b) tần số nhỏ nhất có thể đạt được trong chương trình này, và giá
trị của TH cần để có được tần số đó.
MOV TMOD,#20H ;Timer 1,mode 2
MOV TH1,#5 ;không cần nạp TH1 lần nữa
SETB TR1 ;start (không stop TR1=0)
BACK:JNB TF1,BACK
CPL P1.0
CLR TF1 ;xóa cờ timer 1
60
SJMP BACK ;chế độ 2 là tự nạp lại
Ví dụ 9-14 (2/2)

Giải:
(a) Trong chế độ 2 ta không cần nạp lại cho TH1 vì chế độ 2 là tự
nạp lại.
Nửa chu kỳ = (FFH – 05 +1) × 1.085 s = 272.33 s
Cả chu kỳ = 2 × 272.33 s = 544.67 s
Tần số = 1.83597 kHz.
(b) Để có được tần số nhỏ nhất, ta cần có chu kỳ lớn nhất và để
đạt được điều đó thì TH1 = 00.
Cả chu kỳ = 2 × 256 × 1.085 s = 555.52 s
Tần số = 1.8kHz.
61
Ví dụ 9-15 
Tính tần số của sóng vuông phát ra trên chân P1.0.
Giải:
MOV TMOD,#2H ;Timer 0,mode 2
MOV TH0,#0
AGAIN:MOV R5,#250 ;lặp 250 lần
ACALL DELAY
CPL P1.0
SJMP AGAIN
DELAY:SETB TR0 ;start
BACK: JNB TF0,BACK
CLR TR0 ;stop
CLR TF0 ;xóa TF
DJNZ R5,DELAY ;timer 2: tự nạp lại
RET
T = 2 (250 × 256 × 1.085 s) = 138.88 ms, và tần số = 72 Hz. 62
Trình dịch Assembler và các giá trị âm

• Do ở chế độ 2, bộ định thời là timer 8-bit, ta có thể để


cho trình dịch assembler tính toán giá trị cho TH.
• Ví dụ (với AT89C51), nếu ta muốn tạo ra thời gian trễ
là 200 MC, thì ta có thể sử dụng
MOV TH1,#38H
hoặc
MOV TH1,#-200
• Cách 1: 256-200 = 56 = 38H
• Cách 2: -200 = -C8H 
số bù 2 của –200 = 100H – C8H = 38 H
63
Ví dụ 9-16

Giả sử rằng ta đang lập trình cho các timer ở chế độ 2, tính các giá
trị (theo dạng hex) để nạp vào TH cho mỗi trường hợp sau đây.
(a) MOV TH1,#-200 (b) MOV TH0,#-60 (c) MOV TH1,#-3
(d) MOV TH1,#-12 (e) MOV TH0,#-48
Giải:
Nhiều trình dịch assembler cho 8051 hỗ trợ cách này.
-200 = -C8H  số bù 2 của –200 = 100H – C8H = 38 H
Thập phân Dạng bù 2 (giá trị trong TH)
-200 = - C8H 38H
- 60 = - 3CH C4H
- 3 FDH
- 12 F4H
- 48 D0H 64
Ví dụ 9-17 (1/2)

Tính (a) tần số của sóng vuông được phát ra bằng đoạn chương
trình ở trang sau, và (b) hệ số lấp đầy (duty cycle) của sóng này.

Giải:
“MOV TH0,#-150” sử dụng 150 xung clock.
Chương trình con DELAY có trễ = 150 × 1.085 s = 162.25 s.
Mức logic cao của xung là dài gấp đôi mức logic thấp (66% duty
cycle).
Toàn bộ chu kỳ = phần logic cao + phần logic thấp
= 325.5 s + 162.25 s = 488.25 s
Tần số = 2.048 kHz.
65
Ví dụ 9-17 (2/2)
MOV TMOD,#2H ;Timer 0,mode 2
MOV TH0,#-150 ;Đếm=150
AGAIN:SETB P1.3
ACALL DELAY high
ACALL DELAY
CLR P1.3 low
ACALL DEALY
SJMP AGAIN

DELAY:SETB TR0 ;start


BACK: JNB TF0,BACK
CLR TR0 ;stop
CLR TF0 ;xóa TF
RET 66
9.2 Lập trình cho Bộ đếm (Counter)

67
Counter (1/2)

• Các timer trong 8051 cũng được sử dụng làm các bộ


đếm (counter) để đếm các sự kiện xảy ra bên ngoài 
8051 bằng cách thiết lập cho C/T=1.
• Counter đếm lên khi nhận được các xung từ
– T0: đầu vào timer 0 (chân 14, P3.4)
– T1: đầu vào timer 1 (chân 15, P3.5) 8051
P1
Counter 0 TH0
đến
TL0
LCD
Vcc P3.4
khóa T0
68
Counter (2/2)

• Khi một timer được sử dụng làm counter, nó sẽ tăng


thêm 1 khi có 1 xung bên ngoài 8051 đưa tới
– TH0 & TL0 của counter 0.
– TH1 & TL1 của counter 1.

8051
P1
Counter 1 TH1
đến
TL1
LCD
Vcc P3.5
khóa T1
69
Bảng 9-1: Các chân của cổng 3 sử dụng cho các
Timer 0 và 1
Chân Cổng Chức năng Miêu tả
14 P3.4 T0 Đầu vào của Timer/Counter 0
15 P3.5 T1 Đầu vào của Timer/Counter 1

(MSB) (LSB)
GATE C/T=1 M1 M0 GATE C/T=1 M1 M0
Timer 1 Timer 0

70
Chế độ 1 của Counter (Mode 1)

• Là Counter 16-bit (TH0 và TL0)


• TH0-TL0 được tăng thêm 1 khi TR0 được set lên 1
và có xuất hiện một xung bên ngoài (tại chân T0).
• Khi counter (TH0-TL0) đạt tới giá trị cực đại là
FFFFH, nó sẽ chuyển tới 0000, và TF0 được set lên 1.
• Lập trình viên nên giám sát TF0 liên tục và dừng bộ
đếm counter 0.
• Lập trình viên có thể thiết đặt giá trị ban đầu cho
TH0-TL0 và lấy TF0 làm bit chỉ báo khi điều kiện
thỏa mãn. (ví dụ: đếm đủ 100 người đi vào).
71
Hình 9-5. (a) Counter 0 với đầu vào ngoài
(Chế độ 1)

Đầu vào cờ tràn


ngoài
TH0 TL0 TF0
Timer 0
Chân 3.4
TF0 chuyển mức
C/T = 1 TR0 cao khi FFFF 0

72
Hình 9-5. (b) Counter 1 với đầu vào ngoài
(Chế độ 1)

Đầu vào cờ tràn


ngoài
TH1 TL1 TF1
Timer 1
Chân 3.5
TF1 chuyển mức
C/T = 1 TR1 cao khi FFFF 0

73
Chế độ 2 của Counter (Mode 2)

• Là counter 8-bit.
– TL0 được tăng thêm 1 nếu TR0=1 và có xung bên ngoài tới.
• Tự nạp lại
– TH0 nạp giá trị cho TL0 khi TF0=1.
– Ta cần phải xóa TF0 sau khi TL0 tràn.
• Xem Hình 9.6, 9.7 của mạch logic
• Xem các Ví dụ 9-18, 9-19

74
Hình 9.6: Counter 0 với đầu vào ngoài
(Chế độ 2)

cờ tràn
Đầu vào
ngoài TL0 TF0
Timer 0
nạp lại
Chân 3.4
TR0 TH0

C/T = 1 TF0 chuyển mức


cao khi FFFF 0

75
Hình 9.7: Counter 1 với đầu vào ngoài
(Chế độ 2)

cờ tràn
Đầu vào TL1 TF1
ngoài
Timer 1 reload
Chân 3.5 TR1 TH1

C/T = 1 TF1 chuyển mức


cao khi FFFF 0

76
Ví dụ 9-18 (1/2)
Giả sử rằng các xung clock được nhận vào ở chân T1, viết một
chương trình cho counter 1 ở chế độ 2 để đếm số xung và hiển thị
trạng thái của số đếm trong TL1 trên P2.
Giải:
Ta sử dụng timer 1 làm bộ đếm sự kiện và nó đếm các xung nhận
vào ở chân 3.5.
8051

P2 tới các
LED
P3.5
P2 được nối với 8 LED và T1
đầu vào T1 để nhận xung.
77
Ví dụ 9-18 (2/2)
MOV TMOD,#01100000B ;mode 2, counter 1
MOV TH1,#0
SETB P3.5 ;để T1 làm đầu vào
AGAIN:SETB TR1 ;start
BACK: MOV A,TL1
MOV P2,A ;hiển thị trên P2
JNB TF1,BACK ;tràn
CLR TR1 ;stop
CLR TF1 ;xóa TF=0
SJMP AGAIN ;lặp lại
Lưu ý vai trò của lệnh “SETB P3.5” ở chương trình trên. Vì các
cổng được thiết lập mặc định là đầu ra khi 8051 bật nguồn, ta cần
phải để P3.5 làm đầu vào bằng cách thiết lập nó lên mức logic cao. 78
Ví dụ 9-19 (1/3)
Giả sử rằng có một nguồn xung tần số 1-Hz được nối tới đầu vào
chân P3.4.
Viết một chương trình để hiển thị bộ đếm counter 0 lên LCD.
Thiết đặt giá trị ban đầu cho TH0 là -60.
Giải:
Lưu ý rằng ở vòng đếm đầu tiên, bộ đếm sẽ đếm từ 0 và đếm tới
256 sự kiện, vì sau khi RESET, TL0=0. Để giải quyết vấn đề này,
ta nạp cho TH0 giá trị -60 ở đầu chương trình.
8051

P1 tới
LCD
P3.4
R4 R3 R2
1 Hz clock T0
79
Ví dụ 9-19 (2/3)

ACALL LCD_SET_UP ;khởi tạo cho LCD


MOV TMOD,#00000110B ;Counter 0,mode2
MOV TH0,#C4H ;C4H=-60
SETB P3.4 ;để T0 làm đầu vào
AGAIN:SETB TR0 ;start counter
BACK: MOV A,TL0 ;đếm mỗi 60 sự kiện
ACALL CONV ;đổi và cất R2,R3,R4
JNB TF0,BACK ;lặp lại nếu TF0=0
CLR TR0 ;stop
CLR TF0
SJMP AGAIN
80
Ví dụ 9-19 (3/3)
;đổi số nhị phân 8-bit thành mã ASCII
CONV: MOV B,#10 ;chia cho 10
DIV AB
MOV R2,B ;cất digit thấp
MOV B,#10 ;chia cho 10 một lần nữa
DIV AB
ORL A,#30H ;chuyển thành mã ASCII
MOV R4,A
MOV A,B
ORL A,#30H R4 R3 R2
MOV R3,A
MOV A,R2
ORL A,#30H
MOV R2,A ;gọi ACALL LCD_DISPLAY 81
RET
GATE=1 trong thanh ghi TMOD

• Các phần trước ta đều làm việc với bit GATE=0.


– Bộ timer được khởi động bằng các lệnh “SETB TR0” và
“SETB TR1” cho các timer 0 và 1.
• Nếu GATE=1, ta có thể sử dụng phần cứng để điều
khiển start và stop các timer.
– Trước hết cần thiết phải “SETB TR0” và “SETB TR1”
cho các timer 0 và 1.
– INT0 (P3.2, chân 12) để start và stop cho timer 0
– INT1 (P3.3, chân 13) để start và stop cho timer 1
– Việc này cho phép ta có thể start hoặc stop timer từ bên
ngoài ở bất kỳ thời gian nào thông qua 1 khóa đóng mở.
82
9.3
Lập trình Timer 0 và Time 1 trong
8051 bằng C

83
Các Timer trong C

• Trong lập trình C cho 8051 ta có thể truy cập các


thanh ghi trực tiếp timer TH, TL, và TMOD sử dụng
file đầu đề reg51.h
– Xem Ví dụ 9-20
• Tạo trễ bằng các Timers 0 và 1 sử dụng chế độ 1
– Xem Ví dụ 9-22 và Ví dụ 9-25
• Tạo trễ bằng các Timers 0 và 1 sử dụng chế độ 2
– Xem Ví dụ 9-23 và 9-24

84
Ví dụ 9-20 (1/2)

Viết chương trình C cho 8051 để lật liên tục các bit của P1 với
trễ một khoảng thời gian. Sử dụng Timer 0, chế độ 16-bit.
Giải:
#include <reg51.h>
void T0Delay(void);
void main(void) {
while(1) { //lặp vô tận
P1=0x55;
T0Delay(); //trễ
P1=0xAA;
T0Delay(); }} 85
Ví dụ 9-20 (2/2)

Giả sử XTAL=11.0592MHz với chip AT89C51


FFFFH-3500H+1=CB00H=51968
1.085s 51968  56.384ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0x00; TH0=0x35; //giá trị khởi tạo
TR0=1; //mở T0
while (TF0==0); //chờ TF tràn
TR0=0; //tắt T0
TF0=0; } //xóa TF0 86
Ví dụ 9-25 (1/3)

Một khóa SW được nối với P1.7. Viết 1 chương trình C cho
8051 để giám sát khóa đó và tạo ra xung trên P1.5 có các
tần số sau đây.
SW=0: 500 Hz; SW=1: 750 Hz. Sử dụng Timer 0, chế độ 1.
Giả sử XTAL=11.0592MHz với chip AT89C51

Giải:
#include <reg51.h>
sbit mybit=P1^5;
sbit SW=P1^7;
void T0Delay(void); 87
Ví dụ 9-25 (2/3)
void main(void) {
SW=1; //để P1.7 làm đầu vào
while(1) { //lặp mãi mãi
mybit=~mybit; //lật
if (SW==0)
T0Delay(0); //500Hz trễ
else
T0Delay(1); //750Hz trễ
}}

88
Ví dụ 9-25 (3/3)
void T0Delay(unsigned char c) {
TMOD=0x01; //Timer 0, Mode 1
if (c==0) { TL0=0x67; TH0=0xFC };
// FFFFH-FC67H+1=921, khoảng 999.285s, 500 Hz
else { TL0=0x9A; TH0=0xFD };
// FFFFH-FD9AH+1=614, khoảng 666.19s, 750 Hz
TR0=1;
while (TF0==0);
TR0=0;
TF0=0;
} 89
Tạo thời gian trễ với các kiểu chip khác nhau

• Mặc dù số xung clock cho một chu kỳ máy là khác


nhau với các phiên bản VĐK khác nhau, nhưng tần số
của xung cho các bộ timer luôn là 1/12 tần số của dao
động thạch anh.
– Để bảo đảm sự tương thích với 8051 nguyên bản
• Cùng một mã chương trình chạy trên AT89C51 và
DS89C420 sẽ tạo ra thời gian trễ khác nhau.
– Do trình dịch C và do khác số chu kỳ máy cho các lệnh
• Tình dịch C là một yếu tố trong tạo trễ vì các trình
dịch C cho 8051 khác nhau sẽ tạo ra mã hex có kích
cỡ khác nhau. Vì vậy, ta chỉ có thời gian trễ gần đúng.
– Xem Ví dụ 9-21 90
Ví dụ 9-21 (1/3)

Viết chương trình C cho 8051 để lật liên tục bit P1.5 sau mỗi
50 ms. Sử dụng Timer 0, chế độ 1 cho (a) AT89C51 và
(b) DS89C420.
Giải:
#include <reg51.h>
void T0Delay(void);
sbit mybit=P1^5;
void main(void) {
while(1) { //vòng lặp vô tận
mybit=~mybit;
T0Delay(); }} 91
Ví dụ 9-21 (2/3)

(a) Giả sử XTAL=11.0592MHz với chip AT89C51


FFFFH-4BFDH+1=B403H=46083
1.085s 46083  50ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0xFD; TH0=0x4B; //giá trị khởi tạo
TR0=1; //bật mở T0
while (TF0==0); //BACK: JNZ TF0,BACK
TR0=0; //tắt T0
TF0=0; } //xóa TF0 92
Ví dụ 9-21 (3/3)

(b) Giả sử XTAL=11.0592MHz với chip DS89C4x0


FFFFH-4BFDH+1=B403H=46083
1.085s 46083  50ms

void T0Delay() {
TMOD=0x01; //Timer 0, Mode 1
TL0=0xFD; TH0=0x4B; //giá trị khởi tạo
TR0=1; //mở T0
while (TF0==0); //BACK: JNZ TF0,BACK
TR0=0; //tắt T0
TF0=0; } //xóa TF0 93
Lập trình các Counter của 8051 bằng C

• Các xung bên ngoài đưa tới T0 (P3.4) và T1 (P3.5).


• Xem Ví dụ 9-26.

94
Ví dụ 9-26 (1/2)

Giả sử một xung clock bên ngoài tần số 1-Hz được đưa vào T1
(P3.5). Viết một chương trình C cho counter 1 trong chế độ
2 để đếm lên và hiển thị trạng thái đếm được của TL1 trên
cổng P1. Bắt đầu đếm từ 0H.

Giải:
P1 được nối tới 8 LEDs.
TH1
T1 nối với xung 1Hz ngoài. P1
LEDs
TL1
P3.5
1Hz T1
95
Ví dụ 9-26 (2/2)
#include <reg51.h>
sbit T1=P3^5;
void main(void) {
T1=1; //để T1 làm đầu vào
TMOD=0x60; //counter 1, mode 2
TH1=0; //giá trị nạp lại
while(1) { //lặp vô tận
do {TR1=1; P1=TL1;} while (TF1==0);
TR1=0; TF1=0; //xóa cờ
}}
96

You might also like