Hoạt động của thanh ghi TCON được tóm tắt như sau : Ký hiệu Địa chỉ TCON 88h Có Điều khiển bộ định thời / đếm TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 Bit Ký mềm hoặc bởi phần cứng khi các
Trang 1Bài Gỉang
Môn Học
VI ĐIỀU KHIỂN
TRƯỜNG ĐẠI HỌC KỸ THUẬT CÔNG NGHỆ TP HCM
KHOA ĐIỆN – ĐIỆN TỬ
Naêm 2008
Trang 2TMOD 89h Không Điều khiển chọn chế độ định thời / đếm
(Timer/Counter)
7 GATE 1 Bit điều khiển (mở) cổng của Timer-1 Khi bit TR1 = 1 (trong TCON) và GATE =
1, Timer chỉ chạy khi chân INT1 = 1 (điều khiển cứng) Khi GATE=0, Timer chỉ chạy khi TR1 = 1 (điều khiển mềm)
6 C / T 1 Bit chọn chế độ Counter/Timer (đếm sự kiện hay định thời) của Timer-1
C/T = 1 : Đếm sự kiện (dùng xung clock nhận từ ngõ vào T1) C/T = 0 : Định thời (dùng xung clock nội của hệ thống)
5 M1 x Bit-1 chọn chế độ của Timer-1 (Xem bảng dưới)
4 M0 x Bit-0 chọn chế độ của Timer-1 (Xem bảng dưới)
3 GATE 0 Bit điều khiển (mở) cổng của Timer-0 Khi bit TR0 = 1 (trong TCON) và GATE =
1, Timer chỉ chạy khi chân INT0 = 1 (điều khiển cứng) Khi GATE=0, Timer chỉ chạy khi TR0 = 1 (điều khiển mềm)
2 C / T 0 Bit chọn chế độ Counter/Timer (đếm sự kiện hay định thời) của Timer-0
C/T = 1 : Đếm sự kiện (dùng xung clock nhận từ ngõ vào T0) C/T = 0 : Định thời (dùng xung clock nội của hệ thống)
1 M1 x Bit-1 chọn chế độ của Timer-0 (Xem bảng dưới)
0 M0 x Bit-0 chọn chế độ của Timer-0 (Xem bảng dưới)
Timer 0 : TL0 là Timer 8 bit được điều khiển bởi các bit của Timer 0
TH0 tương tự nhưng được điều khiển bởi các bit của chế độ Timer 1.
Timer 1 : Được ngừng lại.
Thanh ghi chế độ định thời TMOD
Trang 3THANH GHI ĐIỀU KHIỂN TCON (Timer/Counter Control Register) :
Thanh ghi TCON chứa các bit trạng thái và các bit điều khiển của Timer-0 và Timer-1 Thanh ghi TCON có định địa chỉ bit
-4 bit cao (TF1, TR1, TF0, TR0) được dùng để điều khiển Timer hoạt động/hay ngưng (TR0, TR1) hoặc để báo tràn (TF0, TF1)
-4 bit thấp (IE1, IT1, IE0, IT0) không dùng để điều khiển mà được sử dụng để phát
hiện và khởi động các ngắt-ngoài.
Hoạt động của thanh ghi TCON được tóm tắt như sau :
Ký hiệu Địa chỉ
TCON 88h Có Điều khiển bộ định thời / đếm
TCON TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0
Bit Ký
mềm hoặc bởi phần cứng khi các vectơ xử lý đến thủ tục phục vụ ngắt ISR
ngưng chạy Timer.
hiện có ngắt ngoài tác động cạnh xuống xuất hiện trên chân INT1; được xóa bỡi phần cứng khi ngắt được xử lý.
thuộc loại tác động cạnh xuống hay tác động mức thấp.
hiện có ngắt ngoài tác động cạnh xuống xuất hiện trên chân INT0; được xóa bỡi phần cứng khi ngắt được xử lý.
thuộc loại tác động cạnh xuống hay tác động mức thấp.
Tóm tắt thanh ghi điều khiển định thời / đếm TCON
Trang 4Xung Clock Cho bộ định thời
TLx (8
Xung Clock Cho bộ định thời
TLx (5
Xung Clock Cho bộ định thời
Xung Clock
i
CÁC CHẾ ĐỘ ĐỊNH THỜI VÀ CỜ TRÀN :
1 Chế độ Timer-13 bit (Mode 0) :
Chế độ 1 là Chế độ Timer 16-bit, tương tư như Cheat độ 0 ngoại trừ Timer này hoạt
động như một Timer đầy đủ 16 bit, xung clock được dùng với sự kết hợp các thanh ghi cao và thấp (TLx,THx) Khi xung clock được nhận vào, bộ đếm Timer tăng lên 0000H, 0001H,0002H, , và một sự tràn sẽ xuất hiện khi có sự chuyển trên bộ đếm Timer từ FFFFH sang 0000H và sẽ set cờ tràn Timer (bit TFx trong thanh ghi TCON), sau đó Timer đếm tiếp.
Bit có trọng số lớn nhất (MSB) của giá trị trong thanh ghi Timer là bit 7 của THx và bit có trọng
Các thanh ghi Timer TLx và Thx có thể được đọc hoặc ghi tại bất kỳ thời điểm nào bởi phần mềm.
3 Chế độ tự động nạp 8- bit (Mode 2)
Cờ tràn Nạp lại
Hình : Chế độ 2
Trang 5Chế độ 2 là chế độ tự động nạp 8-bit, byte thấp TLx của Timer hoạt động như một Timer 8-bit trong khi byte cao THx của Timer giữ giá trị nạp lại (Reload) Khi bộ đếm tràn từ FFH sang 00H, không chỉ cờ tràn
được set mà giá trị trong THx cũng được nạp vào TLx : Bộ đếm được tiếp tục từ giá trị này lên đến sự chuyển trạng thái từ FFH sang 00H kế tiếp và cứ thế tiếp tục Chế độ này khá tiện lợi do bỡi việc tràn bộ định thời xảy ra ở những khoảng thời gian xác định và tuần hoàn một khi các thanh ghi TMOD và THx đã được khởi động
TL1 (8 bit)
TH1 (8 bit)
TL0 (8 bit)
TH0 (8 bit)
TF0
Xung Clock cho bộ định thời Xung Clock cho bộ định thời Xung Clock cho bộ định thời
TF1
Cờ tràn
Cờ tràn
4 Chế độ tách Timer (Mode 3) :
Timer-1 bị dừng lại ở chế độ 3, nhưng có thể được khởi động bởi việc ngắt nó vào một trong các chế độ khác (Do khuyết điểm là cờ tràn TF1 của Timer-1 không bị ảnh hưởng vì cờ này đã được dùng bỡi TH0) Khi Timer-0 ở chế độ-3, thì Timer-1 có thể hoạt động hoặc
ngưng bằng cách chuyển Timer-1 ra khỏi chế độ-3 hoặc vào chế độ-3 Timer-1 có thể được sử dụng bỡi port nối tiếp (lúc này Timer-1 làm
nhiệm vụ của bộ tạo xung clock tốc độ baud) hoặc sử dụng theo một cách nào đó nhưng không yêu cầu ngắt (vì Timer-1 không còn nối đến TF1.
Trang 6Ví dụ 1 : Tạo xung 250 KHz
Viết chương trình tạo dạng xung tuần hoàn trên chân P1.0 có tần số cao có thể có được Tần số và chu kỳ nhiệm vụ của xung là bao nhiêu ?
Giải : Các khoảng thời gian rất ngắn (tức tần số cao) có thể
được lập trình mà không cần sử dụng đến các bộ Timer như sau :
ORG 8100h Loop : SETB P1.0 ; 1 chu kỳ máy = 1µ s
END
v.v…
SETB P1.0
SJMP Loop
CLR P1.0
SETB
P1.0
1 chu kỳ máy =
kỳ nhiệm vụ là ¼ = 25%.
Bắt đầu lệnh SETB
Kết thúc SETB, bắt đầu CLR
Kết thúc CLR, bắt đầu SJMP
Kết thúc SJMP, bắt đầu SETB
Trang 7Ví dụ 2 : Tạo sóng vuông 10 KHz
Viết chương trình tạo dạng sóng vuông 10KHz trên chân P1.0 bằng cách sử dụng bộ định thời 0
Giải :
Do fOSC = 12MHz nên chu kỳ máy = 1 μs.
Sóng vuông f = 10KHz yêu cầu chu kỳ máy T = 1/f = 1/10KHz =
1/10000Hz = 0.1ms =100 µ s với thời gian mức cao là : 50 µ s và thời gian
mức thấp là : 50 µ s Do khoảng thời gian này < 256 µ s nên Chế độ 2
(chế độ tự nạp lại 8-bit) được sử dụng Do Timer-0 đếm lên , nên một
tràn xảy ra sau mỗi 50 µ s yêu cầu một giá trị số đếm nhỏ hơn
00h một lượng +50 phải được nạp và nạp lại cho TL0, nghĩa là
giá trị nạp cho TH0 là : -50 Chương trình theo yêu cầu như sau :
ORG 8100h MOV TMOD, #02h ; Timer-0 : Mode-2 (chế độ tự nạp lại
8-bit)
MOV TH0, #-50 ; TH0 chứa giá trị -50 (Do
định thời, cho phép Timer-0 chạy
Loop : JNB TF0, Loop ; Nếu Timer-0 chưa tràn thì chờ
tràn
CPL P1.0 ; Đảo trạng thái bit P1.0 để tạo xung vuông
SJMP Loop END
0 1 0 0 0 0 0 0 02h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 8Ví du 3ï : Tạo sóng vuông 1KHz
Viết chương trình tạo sóng vuông 1KHz trên chân P1.0 sử dụng bộ định thời 0.
Giải : Sóng vuông f = 1KHz yêu cầu chu kỳ T = 1/f = 1/1KHz =
1/1000Hz = 1000 µ s với thời gian mức cao là : 500 µ s và thời gian
mức thấp là : 500 µ s Do khoảng thời gian này > 256 µ s nên không
thể sử dụng Chế độ-2 (chế độ tự nạp lại 8-bit) được, mà phải sử dụng Chế độ-1 (chế độ định thời 16-bit) Sự khác nhau trong phần
mềm của 2 chế độ này là : ở Chế độ-1, do không có giá trị nạp lại, nên các thanh ghi định thời TL0, TH0 phải được khởi động lại sau mỗi lần tràn :
ORG 8100h MOV TMOD, #01h Batdau : MOV TH0, #0FEh ; Byte cao của -500
MOV TL0, #0Ch ; Byte thấp của -500
; Hoặc dùng cặp lệnh giả HIGH, LOW như sau :
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 9Ví du 4ï : Tạo 2 sóng vuông 1KHz và 10KHz
Viết chương trình tạo : xung vuơng tần số f = 10KHz tại P1.0 dùng timer 0 và
xung vuơng tần số f = 1 KHz tại P1.1 dùng timer 1.
Giải :
Phân tích cho các thanh ghi giống như các phần ví dụ nêu trên, nhưng lưu ý rằng quá trình kiểm tra timer tràn sẽ khác: thực hiện kiểm tra timer 0, nếu chưa tràn thì kiểm tra timer 1 và kiểm tra tương tự cho timer 1
MOV TMOD, #12h ; Timer-1 : Mode-1, Timer-0 : Mode-2MOV TH1, #High(-500) ; P1.1 = Timer-1 = 1000µ s
MOV TL1, #Low(-500) ; Xung vuơng = 500µ s + 500µ sMOV TH0, #(-50) ; P1.0 = Timer-0 = 100µ s
MOV TL0, #(-50) ; Xung vuơng = 50µ s + 50µ sSETB TR0
SETB TR1 KtrT0: JNB TF0, KtrT1
CLR TF0 CPL P1.0 KtrT1: JNB TF1, KtrT0
CLR TF1 CPL P1.1 MOV TH1, #High(-500) MOV TL1, #Low(-500) SJMP KtrT0
END
Lưu ý, xung vuơng tạo bằng cách như trên cĩ thể khơng chính xác khi 2 timer tràn cùng lúc
0 1 0 0 1 0 0 0 12h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 10Ví dụ 5 : Tạo sóng vuông 1Hz
Viết chương trình tạo xung vuơng tần số f = 1Hz tại P1.2 dùng timer 1
Giải :
f = 1 Hz → T = 1/f = 1 s = 1.000.000 μs → một chu kỳ sĩng vuơng chiếm khoảng
thời gian 500.000 chu kỳ máy → thời gian trì hỗn cần thiết là 500.000 chu kỳ máy.
Giá trị đếm là 500.000, vượt quá khả năng của timer (tối đa chỉ đếm được 65.536
chu kỳ) nên phải thực hiện tạo vịng lặp đếm nhiều lần cho đến khi đạt đến giá trị
500.000 (cĩ thể đếm mỗi lần 50.000 và thực hiện vịng lặp 10 lần).
Chương trình thực hiện như sau:
MOV TMOD,#10h ; Mode-1Batdau:
MOV R7,#10 ; Lặp 10 lầnLap:
MOV TH1, #High(-50000) MOV TL1, #Low(-50000) SETB TR1
KtrT1:
JNB TF1,KtrT1 CLR TF1
CLR TR0 DJNZ R7,Lap ; Giảm R7 đi 1 và Nếu R7 ≠ 0 thì lặp lạiCPL P1.2 ; Đảo bit để tạo xung
SJMP Batdau END
0 0 0 0 1 0 0 0 10h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 11Ví dụ 6 : Giao tiếp với mạch còi (Buzzer) và công tắc SW
Một còi được nối với chân P1.7 và một công tắc chống dội SW được nối đến chân P1.6 Viết chương trình đọc mức logic cung cấp bỡi công tắc SW và hụ còi trong thời gian 1sec sau mỗi lần phát hiện sự chuyển trạng thái từ 1 xuống 0 ở chân P1.6.
CALL Delay1s ; kéo dài 1sec
SJMP Loop
;
-Delay1s: MOV R7, #TrămLần
Lap : MOV TH0, #HIGH Count
MOV TL0, #LOW Count SETB TR0
Wait2: JNB TF0, Wait2
CLR TF0 CLR TR0 DJNZ R7, Lap RET
END
1 0 0 0 0 0 0 0 01h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 12MOV R7,#20 ; Lặp 20 lầnLap:
MOV TH0, #High(-50000) ; Mỗi lần trì hoãn 50.000 μsMOV TL0, #Low(-50000)
SETB TR0 Lap1:
JNB TF0, Lap1 CLR TF0
CLR TR0 DJNZ R7, Lap ; Lặp đủ 20 lần thì thoátRET
END
Lưu ý rằng : khi viết chương trình trì hoãn như trên thì chương trình của AT89C51 xem như dừng lại, không làm gì cả (có thể giải quyết bằng cách sử dụng ngắt).
1 0 0 0 0 0 0 0 01h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 13Ví dụ 8 : Xét sơ đồ kết nối Dãy Led đơn như sau : P0.0 →LED0, ….,
P0.7→LED7
Viết chương trình điều khiển Led sáng từ trái sang phải, mỗi lần 1 Led.
Giải : Các Led nối với Port 0 của AT89C51 (P0 khi dùng như các cổng nhập / xuất thì cần phải cĩ điện trở kéo lên nguồn) nên muốn Led sáng (LED tác động ở mức thấp) thì phải gởi dữ liệu ra P0.
Theo sơ đồ mạch, Led sang khi các bit tương ứng tại P0 là 0.
Yêu cầu điều khiển Led sang từ trái sang phải (lần lượt từ P0.0 đến P0.7) nên dữ liệu gởi ra là:
- Lần 1: 1111 1110b (0FEh) – sáng 1 Led trái - Lần 2: 1111 1101b (0FDh) - Lần 3: 1111 1011b (0FBh)
MOV DPTR, # MaLed ; DPTR chứa vị trí bảng mã Led
Main:
MOV R7, #0 ; Phần tử đầu tiên của bảng mã
Loop :
MOV A, R7 MOVC A, @A+DPTR ; Đọc bảng mã
MOV P0, A ; Chuyển vào P0 để sáng Led
CALL Delay ; Chờ để mắt người cĩ thể thấy
CJNE R7,#8, Loop ; Đã hết bảng mã thì lặp lại
SETB TR0 JNB TF0,$
CLR TF0 CLR TR0 RET END
1 0 0 0 0 0 0 0 01h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 14MOV R7,#4 D2: MOV
R6,#250 D1: MOV R5,#250 DJNZ R5,$
DJNZ R6,D1 DJNZ R7,D2 RET
Trang 15Ví dụ 10 : Xét sơ đồ kết nối LED 7-đọan Anode chung Port P0 nối đến các đọan, chân P1.0 →LED1, P1.1→LED0 Các LED tích cực ở mức 1 Viết chương trình hiển thị số 0 ra Led1 và
số 1 ra Led2
Giải :Theo sơ đồ kết nối, chân g của Led nối với P0.6, chân a nối với P0.0 nên bảng mã Led
là bảng 4.2, dữ liệu cho số 0 và 1 lần lượt là 0C0h và 0F9h Phương pháp sử dụng là phương pháp quét nên cần phải cĩ thời gian trì hỗn giữa 2 lần quét, thời gian này được thực hiện thơng qua timer (thời gian trì hỗn khoảng 200 μs) Chương trình thực hiện như sau:
MOV P1,#0 ; Xố P1 để tắt LedMain:
MOV P0, #0C0h ; Mã số “0” gửi ra port0 cho các cathodeSETB P1.0 ; Sáng Led1
CALL Delay200 µ s ; Thời gian trì hỗn để thấy Led1 sángCLR P1.0 ; Tắt Led1
MOV P0, #0F9h ; Mã số “1” gửi ra port0 cho các cathodeSETB P1.1 ; Sáng Led2
CALL Delay200 µ s ; Thời gian trì hỗn để thấy Led2 sángCLR P1.1 ; Tắt Led2
SJMP main
; -Delay200 µ s:
MOV TMOD, #01h MOV TH0, #(-200) MOV TL0, #(-200) SETB TR0
JNB TF0,$
CLR TF0 CLR TR0 RET
END
1 0 0 0 0 0 0 0 01h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 17Ví dụ 10B : Viết lại chương trình hiển thị số “0” ra Led1 và số “1” ra Led2 như trên nhưng
sử dụng ngắt của Timer
Giải : Đối với chương trình trong ví dụ kế trên, khi đang thực hiện quét led thì
chương trình khơng làm gì cả trong khi đĩ, các ứng dụng thực tế thường xử lý các cơng việc khác đồng thời với quá trình quét Vấn đề này cĩ thể giải quyết bằng cách sử dụng ngắt của timer: mỗi khi timer tràn thì thực hiện hiển thị trên 1 Led Chương trình như sau:
Led1 EQU 30h ; Địa chỉ chứa dữ liệu của Led1Led2 EQU 31h ; Địa chỉ chứa dữ liệu của Led2Led_Pos EQU 32h ; Vị trí Led hiện hành
ORG 0000h LJMP main ORG 000Bh ; Địa chỉ ISR của timer 0LJMP Timer0_ISR
Main:
SETB EA ; Cho phép ngắt tại timer 0SETB ET0
MOV Led1,#0C0h ; Số 0MOV Led2,#0F9h ; Số 1MOV Led_Pos,#01h ; Vị trí sáng đầu tiên là Led1MOV R0,#Led1 ; Dữ liệu gởi ra đầu tiên là ở Led1MOV TMOD,#01h
MOV TH0,#(-200) MOV TL0,#(-200) SETB TR0
SJMP $ ; Khơng làm gì cả, trong thực tế
; cĩ thể thêm chương trình vào
1 0 0 0 0 0 0 0 01h
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit
Trang 18Timer0_ISR:
; -MOV A,Led_Pos ; Xác định vị trí Led hiện hànhMOV P1,A ; Sáng Led hiện hành
RL A ; Dịch trái để chuyển qua Led kếMOV Led_Pos,A ; trong qua trình tràn tiếp theoMOV A,@R0 ; Đọc dữ liệu hiện hành
MOV P0,A INC R0 ; Chuyển qua dữ liệu kếCJNE R0,#Led_Pos,exitTimer0 ; Nếu đã quét hết toàn bộMOV Led_Pos,#01h ; Led thì bắt đầu lại từ Led1MOV R0,#Led1
exitTimer0:
RETI END
Trang 19Ví dụ 11 : Viết chương trình hiển thị nội dung trong ơ nhớ 30h ra 2 Led trong đĩ Led1 chứa số hàng chục và Led2 chứa số hàng đơn vị (giả sử giá trị trong ơ nhớ
30h tối đa là 99).
Giải : Để xuất nội dung trong ơ nhớ 30h ra Led 7 đoạn cần thực hiện :
- Chuyển nội dung trong ơ nhớ 30h thành số hàng chục và hàng đơn vị (thực hiện chia cho 10).
- Chuyển giá trị số thành mã Led 7 đoạn (bằng cách tra bảng).
Chương trình thực hiện như sau:
Led1 EQU 30h ; Địa chỉ chứa dữ liệu của Led1Led2 EQU 31h ; Địa chỉ chứa dữ liệu của Led2Led_Pos EQU 32h ; Vị trí Led hiện hành
ORG 0000h LJMP main ORG 000Bh ; Địa chỉ ISR của timer 0LJMP Timer0_ISR
MOV TH0,#(-200) MOV TL0,#(-200) SETB TR0
Trang 20Begin:
MOV A,30h CALL Chuyenma SJMP Begin
Chuyenma:
MOV Led2,A RET
BCDtoLed7:
; -MOV DPTR,#MaLed7 MOVC A,@A+DPTR RET
MaLed7: DB 0C0h,0F9h,0A4h,0B0h,99h,92h,82h,0F8h,80h,90h
Timer0_ISR:
; -PUSH ACC
MOV P0,A
MOV R0,#Led1 exitTimer0:
POP ACC RETI END
Trang 21MOV DPTR,# cot
MOVC A,@A+DPTR ; Xuất cột MOV P1,A
MOV A,R0 MOV DPTR,# hang
MOVC A,@A+DPTR
CALL delay ; Tạo thời gian trì hoãn để thấy
CJNE R0,#5,lap ; Nếu quét đủ 5 cột thì lặp lại SJMP main
; -delay :
MOV TMOD,#01h MOV TL0,#LOW(-500) MOV TH0,#HIGH(-500) SETB TR0
JNB TF0,$
CLR TF0 CLR TR0 RET
; -cot : DB 01h,02h,04h,08h,10h
hang : DB 41h,3Eh,3Eh,3Eh,41h
END
Trang 22Ví dụ 13 : Xét sơ đồ kết nối động cơ.Viết chương trình điều khiển động cơ quay thuận mỗi lần một bước với tốc độ 50 vịng/phút (giả sử động cơ cĩ gĩc quay là 7.20/bước)
P2.0→Cuộn 1-2, P2.1→Cuộn 2-3, P2.2→Cuộn 4-5, P2.3→Cuộn 5-6
Giải : Gĩc quay 7.20/bước → 1 vịng quay cần 3600/7.20 = 50 bước → 50 vịng quay cần
thực hiện 2500 bước Tốc độ 50 vịng / phút → 1 phút (3600s) thực hiện 2500 bước → mỗi bước cần 3600/2500 = 1,44sec = 1.440.000 μs Thứ tự kích xung cho như bảng
main:
MOV R0,#0 MOV DPTR,#thuan1buoc begin: MOV A,R0
MOVC A,@A+DPTR MOV P2,A ; Xuất ra P2 để điều khiển động cơ
CALL Delay144 INC R0
CJNE R0,#4,begin SJMP main
Delay144:
MOV TMOD,#01h MOV R7,#40
SETB TR0 JNB TF0,$
CLR TF0 CLR TR0 DJNZ R7,Delay1 RET
thuan1buoc: DB 08h,04h,02h,01h
END
M 0
M 1
C/
T
GA TE
M 0
M 1
C/
T
GA TE
TM OD
0 1 2 3 4 5 6 7 Bit