Professional Documents
Culture Documents
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
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
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
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
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
9
Các thanh ghi sử dụng cho Timer/Counter
10
Các thanh ghi cơ sở của Timer
TH0 TL0
Timer 0
TH1 TL1
Timer 1
12
Thanh ghi TCON (1/2)
(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
(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)
18
Hình 9-8: Timer/Counter 0
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
timer 1 timer 0
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
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)
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
29
Giá trị đếm thiết đặt ban đầu
(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
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.085s. 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)
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ả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)
49
Ví dụ 9-12 (1/2)
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)
• 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.
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)
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
59
Ví dụ 9-14 (1/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
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
67
Counter (1/2)
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)
72
Hình 9-5. (b) Counter 1 với đầu vào ngoài
(Chế độ 1)
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
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
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)
83
Các Timer trong C
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)
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.285s, 500 Hz
else { TL0=0x9A; TH0=0xFD };
// FFFFH-FD9AH+1=614, khoảng 666.19s, 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
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)
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)
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
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