You are on page 1of 14

Chương 14

Thao tác & ứng dụng máy bấm/đếm


giờ bên trong
Giới thiệu
Có nhiều ứng dụng ở nơi cần áp dụng sự trì hoãn. Từ lâu chúng ta đã sử dụng nhiều phần
mềm vòng lặp để sinh ra sự trì hoãn. Điều đó có thể không chấp nhận được trong một số
ứng dụng bởi vì chương trình liên kết chặt chẽ suốt từ đầu chí cuối và không thể thực
hiện được nhiều nhiệm vụ khác. Sự hạn chế khác là sự không chính xác của phần mềm trì
hoãn. Một số bộ vi xử lý có gắn kèm những thiết bị bấm giờ có thể chương trình hoá.
Mục tiêu của chương này là giải thích cấu trúc bên trong của bộ vi xử lý Intel 8051 và
minh hoạ cách sử dụng nhiều mẫu cách sử dụng timers đối với nhiều ứng dụng rất khác
nhau như Timing Delays, Pulse Width Measurements và sự phát sinh của nhiều xung phối
hợp thời gian.
Timer/Counters
80C51 có hai thanh ghi Timer/Counter 16-bit: Timer 0 và Timer 1. Cả hai có thể được
định cấu hình để hoạt động hoặc là bấm giờ hoặc đếm sự kiện. Trong chức năng “Timer”,
thanh ghi đã làm gia tăng chu kỳ mọi máy. Vì vậy, có thể nghĩ về nó như một máy đếm
chu kỳ. Bởi vì một chu kỳ máy có 12 chu lỳ máy tạo dao động, tốc độ đếm là 1/12 tần số
máy tạo dao động.
Trong chức năng “Counter”, thanh ghi gia tăng sự đáp lại việc chuyển tiếp từ 1-to-0 tại
chân dữ liệu nhập từ bên ngoài tương ứng của nó, T0 hoặc T1. Trong chức năng này, dữ
liệu vào bên ngoài được lấy mẫu trong thời gian S5P2 của mỗi chu kỳ máy. Khi các mẫu
hiện ra cao trong chu kỳ này và thấp trong chu kỳ kia, sự đếm được gia tăng. Giá trị đếm
mới xuất hiện trong thanh khi trong thời gian S3P1 của chu kỳ theo một trong sự chuyển
tiếp nào đã tìm ra. Bởi vì nó chiếm 2 chu kỳ máy (24 chu kỳ máy dao động) chấp nhận sự
chuyển tiếp 1-to-0, tốc độ đếm cực đại là 1/24 của tần số máy dao động. Không có sự hạn
chế về chu kỳ công suất tín hiệu nhập bên ngoài, nhưng để bảo đảm mức cho trước được
lấy mẫu ít nhất một lần trước khi nó thay đổi, nó cần phải chiếm ít nhất một chu kỳ đầy
đủ. Ngoài ra để lựa chọn “Timer” hoặc “Counter”, Timer 0 và Timer 1 có bốn chế độ hoạt
động để lựa chọn.
Thanh ghi đặc biệt 8-bit SFR (Special Function Register-Thanh ghi chức năng đặc biệt)
được gọi là TMOD được sử dụng để lựa chế độ cho từng timer. Định dạng của thanh ghi
này và định nghĩa của mỗi bit riêng biệt được minh hoạ trong Hình 1 bên dưới:
Để hiểu chức năng của từng bit, chúng ta hãy xem xét cấu trúc bên trong của 8051 trình
bầy trong Hình 2.

Nhìn vào Hình 2, chúng ta có thể liên hệ vai trò của Gate bit C/T trên thanh ghi TMOD.
Đây là định nghĩa về các bit đó:
Gate: Khi bit này thiết lập (nghĩa là: ‘1’), timer có thể được điều khiển bên ngoài bởi
INT1 đối với timer 1 và INT0 đối với timer 0. Timer bắt đầu khi chân này cao. Khi bit
Gate là ‘0’, thì counter bắt đầu không lệ thuộc các chân ngoài.
C/T: Bit này định nghĩa có sử dụng đồng hồ bộ dao động bên trong hoặc đồng hồ bên
ngoài từ T1 đối với timer 1 hoặc T0 đối với timer 0 hày không. M1 & M0 định nghĩa chế
độ của timer như sau:
Bảng 1: Bốn chế độ của từng timer

M1 M0 Diến giải
0 0 Mode 0: 13-bit Timer
0 1 Mode 1: 16-bit Timer
1 0 Mode 2: 8-bit Auto-reload
1 1 Mode 3: Split Timer

Mode 0
Đặt hoặc Timer vào trong Mode 0 làm cho nó trông giống 8048 Timer, đó là Counter 8-
bit có mạch đếm gộp trước (prescaler) chia-theo-32. Hình 7 trình bầy hoạt động của
Mode 0 khi nó áp dụng vào Timer 1. Trong chế độ này, thanh ghi Timer được định hình
là thanh ghi 13-bit. Khi sự đếm cuốn qua từ mọi 1s đến mọi 0s, thì nó thiết lập cờ hiệu
ngắt Timer TF1. Đầu vào được đến được Timer cho phép khi TR1 = 1và hoặc GATE = 0
hoặc INT1 = 1. (Cách thiết lập GATE = 1 cho phép Timer điều khiển đầu vào bên ngòi
INT1, để dễ đo chiều rộng xung). TR1 điều khiển bit trong Special Function Register
TCON. GATE là trong TMOD.
Thanh ghi 13-bit có tất cả 8 bit của TH1 và 5 bit thấp hơn của TL1. 3 bit thấp của TL1 là
vô định và nên lờ đi. Cách thiết lập chạy cớ hiệu (TR1) không làm xoá các thanh ghi.
Mode 0 hoạt động giống như Timer 0 như đối với Timer 1. Có hai bit GATE khác nhau,
một cho Timer1 (TMOD.7) và một cho Timer 0 (TMOD.3).
Mode 1
Mode 1 giống như Mode 0, trừ thanh ghi Timer đang chạy với toàn bộ 16 bits.
Mode 2
Mode 2 đinh cấu hình thanh ghi Timer như Counter (TL1) 8-bit có nạp lại tự động. Sự
tràn bộ nhớ khỏi TL1 không chỉ thiết lập TF1, mà còn làm nạp lại TL1 bằng những nội
dung của TH1, cái đó do phần mềm định trước. Sự nạp lại cho phép TH1 không bị thay
đổi. Mode 2 hoạt động giống như Timer/Counter 0.
Mode 3
Timer 1 trong Mode 3 đơn giản là chứa sự đếm của nó. Hiệu lực giống như cách thiết lập
TR1 = 0. Timer 0 trong Mode 3 thiết lập TL0 và TH0 như hai bộ đếm riêng rẽ. TL0 sử
dụng Timer 0 kiểm soát các bit: C/T, GATE, TR0, INT0, và TF0.TH0 ghìm lại vào trong
chức năng timer (đếm chu kỳ máy) và dẫn tới (takes over) sử dụng TR1 và TF1 từ Timer
1. Như vậy, TH0 bây giờ điều khiển “Timer 1” ngắt. Mode 3 được cung cấp cho những
ứng dụng yêu cầu timer phụ 8-bit vào counter. Với Timer 0 trong Mode 3, 80C51 có thể
trông giống như nó có ba Timer/Counters. Khi Timer 0 trong Mode 3, Timer 1 có thể
được bật và tắt bằng chuyển mạch cho nó ra và vào Mode 3 riêng của nó, hoặc có thể vẫn
sử dụng bởi hàng loạt cổng như máy phát tốc độn baud, hoặc thực tế, trong mọi ứng dụng
không yêu cầu ngắt.
Bảng 2
Bit Ký hiệu Diễn giải
Phần mềm có thể lự đối với timer 0
TCON.0 IT0
Nó chỉ rõ cách tụt xuống mức edge/Low đã gây ra sự ngắt bên ngoài
Ngắt cờ hiệu Edge đối với timer 0. Việc này đặt khi ngắt mép ngoài
TCON.1 IE0
được tìm thấy. Nó được xoá khi Interrupt đã tiến hành
Phần mềm có thể lựa đối với timer 1
TCON.2 IT1
Nó chỉ rõ cách tụt xuống mức edge/Low đã gây ra sự ngắt bên ngoài
TCON.3 IE1
Cờ hiệu Interrupt Edge đối với timer 1. Việc này đặt khi ngắt mép ngoài
được tìm thấy. Nó được xoá khi Interrupt đã tiến hành
TCON.4 TR0 Phần mềm có thể lựa. Bắt đầu và dừng timer 0
Cờ hiệu tràn bộ nhớ Timers 0.
TCON.5 TF0 Nó đặt tự động khi timer / counter tràn bộ nhớ. Nó được xoá khi dịch vụ
ngắt đã xảy ra.
TCON.6 TR1 Phần mềm có thể lựa. Bắt đầu và dừng timer 1
Cờ hiệu tràn bộ nhớ Timers 1.
TCON.7 TF1
Nó đặt tự động khi timer / counter tràn bộ nhớ. Nó được xoá khi dịch vụ
ngắt đã xảy ra.

Note:
Chúng ta giả thiết rằng bộ vi xử lý đang chạy với tinh thể (crystal) Fc=12 MHz.
Điều này gợi ý là đồng hồ thời gian đang chạy tại Ft = 1MHz. Kể kể từ đây thời
gian mỗi tích tắc là 1 giây.
Bộ đếm theo thời gian luôn luôn tính tăng. TL0 và TH0 là những thanh ghi đối với
timer0, TL1 và TH1 là những thanh ghi đối với timer 1. Khi timer khởi động, nó
bắt đầu tăng cho đến khi đạt tới cực đại của nó, rồi nó sinh ra cờ hiệu TF0 hoặc
TF1.
Những ví dụ dưới đâu minh hoạ việc sử dụng và những ứng dụng của timers.
Ví dụ [1]: Time Delays
Tiến trình phát sinh chức năng chừng 100 μ s bằng cách dùng timer 0.
Thủ tục để lập trình timer như sau:
Khởi tạo thanh ghi TMOD
Khởi tạo thanh ghi TL0 và TH0
Khởi động timer
Theo rõi TF0 cho đến khi ổn định
Đối với nhiều ứng dụng thời gian trễ, chế độ 0 của các timer là sử dụng thích hợp nhất.
Bước thứ nhất là quyết định nội dung của thanh ghi TMOD. Các thanh ghi này như đã
nói trên, định nghĩa chế độ/timer nào được sử dụng. Định dạng của các thanh ghi này
được nhắc lại ở đây cho thuận tiện:

Hình 5:

Ở đây chúng ta dùng timer 0 trong chế độ 1 (nghĩa là timer 16 bit). Chúng ta sử dụng
đồng hộ nội tại đối với timer (nghĩa là C/T=0), chúng ta muốn khởi động timer bằng phần
mềm mà nó hàm ý Gate=0. Chế độ là 0, kể từ đây là M1 M0 = 01. Nội dung của thanh
ghi bởi vậy là:

Hình 6

Đối với tinh thể 12MHz, timer sẽ được khoá tại 1MHz tương ứng với 1 μ s mỗi cú đếm.
Kể từ đây đối với 100 μ s, counter cần thiết tính 100 xung. Chúng ta biết rằng TL0 và
TH0 có thể có giá trị cực đại chừng FFFF (in Hex) hoặc (65535). Nếu chúng ta đặt số 0-
100=-100 (nghĩa là FFC9), thì khi sự đếm bắt đầu, thì timer tính tăng lên cho đến FFFF
trước khi nó phát sinh TF0=1. Như từ FFC9 tới 0000 có 100 xung, bởi vậy điều này sẽ
nói chung là 100 μ s khi TF0 đặt là 1.

Thường trình con được viết theo ngôn ngữ assembly (ngôn ngư lập trình bậc thấp) vì vậy:

; Thường trình con để sản sinh 100 μ s bằng sử dụng timer 0


Delay: MOV TMOD, #01H ; Initialise TMOD to 01H
MOV TL0, #9CH ; Initialise TL0 to 9CH
MOV TH0, #0FFH ; Initialise TH0 to FFH
SETB TR0 ; Start timer 0
WAIT: JNB TF0, WAIT ; Wait until TF0 is set to 1
RET

Hàm “C” tương đương đã cho tiếp theo:

void Delay(void)
{
TMOD=0X01;
TL0=0X9C;
TH0=0X0FF;
TR0=1;
while(!TF0);
TR0=0;
TF0=0;
}

Ví dụ [2]: Các máy phát xung vuông

Triển khai chương trình để phát sinh sóng vuông từ P 1.0 như sau:

Hình 7: Cách sản sinh sóng vuông 1KHz từ P10

Bằng cách áp dụng timer 0, và giả thiết rằng bộ vi xử lý là đang chạy với tinh thể 12MHz
chúng ta có thể bắt đầu thiết kế bằng cách trước tiên quyết định như thế nào số ban đầu
trong TL0 và TH0 cần cung cấp sự chậm trễ chừng 0.5 ms (nghĩa là 500 μ s). Bằng cách
dùng tinh thể 12 MHz cung cấp tần số cơ sở thuận tiện để phát sinh thời gian trễ như thể
được chia bên trong bởi 12 tới tần số cho trước 1MHz và kể từ đây tần số máy là 1 μ s.
Kể từ đây 500 μ s trễ yêu cầu timer đếm 500 xung. Điều này thành lập nên biểu thức sau:
0 – 500 = -500 = FE0CH
Bit thấp (nghĩa là 0C) là giá trị ban đầu của TL0 và bit cao hơn là giá trị ban đầu của TH0
(nghĩa là FE). Tiếp theo, chúng ta cần định nghĩa các bit tương ứng trong thanh ghi
TMOD như sau:

Hình 8

Chúng ta giả thiết rằng timer 1 không được dùng trong chương trình này. Timer 0 được
dùng trong chế độ 1, sử dụng đồng hồ bên trong.
Cả hai chương trình toàn bộ và ‘C’ được cho dưới đây:

; Chương trình chính đầu tiên


ORG 0
Start: LJMP Main
ORG 30H
Main: SETB P1^0 ; Set P1.0 to 1
ACALL Delay ; Wait for 0.5 ms
CLRB P1^0 ; Reset P1.0 to 0
ACALL Delay ; Wait for 0.5 ms
AJMP Main ; Repeat again
END
; Cách tạo ra sự trễ 0.5 ms
Delay: MOV TMOD, #01H
MOV TH0, #0FEH
MOV TL0, #0CH
SETB TR0
Wait: JNB TF0, Wait
CLR TR0
CLR TF0
RET

Chương trình nói trên có thể được thực hiện đầy đủ trong ‘C’ như sau:

#include <reg51.h>
void Delay(void);
sbit Pulse = P1^0;
void main(void)
{
for(;;)
{
Pulse = 1;
Delay();
Pulse = 0;
Delay();
}
}
void Delay(void)
{
TMOD=0X01;
TL0=0X0C;
TH0=0X0FE;
TR0=1;
while(!TF0);
TR0 =0;
TF0 =0;
}

Ví dụ [3]: Đo chiều rộng xung


Có một số bộ cảm biến cung cấp xung đầu ra mà chiều rộng của chúng tỷ lệ với lượng
chúng đo được. Phương pháp chính xác đê đo chiều rộng xùng là kết nối xung (giả sử là
xung digital) vào hoặc INT0 hoặc INT1 của bộ vi xử lý 8051 như trình bầy trong Hình 9.

Hình 9: Đo chiều rộng xung bằng cách dùng các timer bên trong

Ở đây, chúng ta đặt cả hai TL0 và TH0 thành 0. Khi xung tới mức cao, bộ đếm sẽ bắt đầu
đếm tăng lên từ 0. Khi xung xuống mức thấp, nó dừng đếm. Giá trị đếm trong TH0 và
TL0 miêu tả chiều rộng theo μ s.
Chú ý rằng, trong sơ đồ trên chân INT0 không phục vụ như đầu vào gián đoạn mà đơn
giản là đầu vào bit. Điều này trình bầy trong Hình 10.
Hình 10: INT0 có thể được sử dụng để khởi động và dừng timer
được cung cấp bên ngoài Gate tại 1 và TR1=1

Chức năng dưới đây trả về chiều rộng xung trong thanh ghi R0 (Least Significant Byte)
và R1 (Most Significant Byte).

Width: MOV TMOD, #09H ; Gate=1 and Mode=1 using timer 0


Loop: JB INT0, Loop ; Wait for pulse to go low
MOV TH0, #0 ; Initialise TH0
MOV TL0, #0 ; Initialise TL0
High: JNB INT0, High ; Wait for pulse to go high
SETB TR0 ; Start timer 0
Low: JB INT0, Low ; Wait for pulse to go low
CLR TR0 ; Stop timer 0
CLR TF0 ; Clear timer 0 flag
MOV R0, TL0 ; Return the low Byte in R0
MOV R1, TH0 ; the high Byte in R1
RET

Chức năng đó được viết trong ‘C’ như sau:

#include <reg51.h>
sbit Width = P3^2;
void main(void)
{
unsigned char Width_Low, Width_High;
TMOD=0X09;
while(1)
{
TL0=0X00;
TH0=0X00;
while(Width==1);
while(Width==0);
TR0 =1;
while(Width==1);
TR0=0;
TF0 =0;
Width_Low=TL0;
Width_High=TH0;
}

Giả định rằng trong chương trình trên là như sau:


Khi timer đang chạy tại 1MHz, nó có thể đo chiều rộng lên đến 65,535 μ s. Nếu chiều
rộng lớn hơn giá trị, thì timer sẽ tự động tràn bộ nhớ và khởi động từ TH0=TL=0 lần nữa.
Chương trình trên không kiểm tra hoặc điều này đã xuất hiện hoặc không. Một giải pháp
có thể sẽ theo rõi cờ hiệu timer trong khi chiều rộng xung đang được đo. Chương trình có
thể theo rõi số lượng cờ hiệu timer (nghĩa là TF) trở thành kích hoạt. Chiều rộng thực sự
của xung sẽ được lấy giá trị này vào xem xét với chiều rộng tính toán của xung. Mẫu
chương trình ‘C’ như sau:

#include <reg51.h>
sbit Width = P3^2;
void main(void)
{
unsigned int Width_Low, Width_High;
unsigned int Count=0;
TMOD=0X09;
while(1)
{
TL0=0X00;
TH0=0X00;
while(Width==1);
while(Width==0);
TR0 =1;
while(Width==1)
{
if(TF0==1)
{
Count++;
TF0=0;
}
}
TR0 =0;
TF0 =0;
Width_Low=TL0 + ( Count & 0X00FF);
Width_High=TH0 + ( Count & 0XFF00);
}

Ở đây có một số yêu cầu để bạn tự đánh giá:


Các câu hỏi tự đánh giá
Q1. Suy xét bộ vi xử lý 8051 chạy với tinh thể 11.0592 MHz.
I. Tần số của đồng hồ thời gian là bao nhiêu?
II. Thời gian mỗi đếm tính bằng microseconds là bao nhiêu?
III. Chiều rộng xung lớn nhất và nhỏ nhất có thể đo được là bao nhiêu?
Q2. Triển khai hàm ‘C’ gọi là Delay50( ) mà nó phát sinh sự trễ là 50ms, giả định tinh
thể là:
I. 12 MHz
II. 11.0592 MHz
Q3. Triển khai chương trình (‘C’ hoặc ‘Assembly’) mà nó phát sinh sóng vuông như từ
P1.7.

Tóm tắt về sử dụng Internal Timer


Một trong những sử dụng thường xuyên nhất của hoặc timer 0 hoặc timer 1 là để sản sinh
thời gian trễ. Các bước trong triển khai chương trình/các chức năng là như sau:
Nếu thời gian trễ đẫ biết (nói là Td), thì bằng cách dùng tần số tinh thể (Fc), chúng
ta có thể tính toán một con số 16-bit cần phải nạp vào trong TL0 và TH0 trước khi
khởi động timer.
Cho phép Fc=11.0592 MHz, thì tần số của timer là:

Fc 11.0592
Ftimer = = = 0.9216MHz= 92MHz
12 12

1
Bởi vậy, Thời gian mỗi đếm, Tcount = = 1.285 μ s
0.9216

Td
Con số (Number) được yêu cầu để nạp vào trong TL0 và TH0 Ö N =
Tcount

50x1000
Ví dụ về thời gian trễ của Td=50mS: N = = 486080
1.085

Chú ý rằng counter cần phải đếm số này để sinh ra thời gian trễ 50ms. Nhưng vì bộ đếm
luôn luôn đếm tăng lên đến FFFF (hoặc 65535) trước khi nó phát sinh cờ hiệu tràn bộ
nhớ (nghĩa là TF0 hoặc TF1) chúng ta cần nạp thanh ghi counter (TLx và THx) với:

0 – 46082 = -(46080)Dec = (4C00)Hex

Đây là con số để được nạp vào trong TL0 và TH0 đối với timer 0 và TL1 và TH1 đối với
timer 1.
Bước tiếp theo là xác định 8-bits trong thanh ghi TMOD. Thanh ghi này yêu cầu
xác định chiều rộng timer và chế nào được đòi hỏi. Sự định dạng thanh ghi này
như sau:

Ví dụ sử dụng đồng hồ bên trong (C/T =0 ), để dừng và khởi động timer ở bên
trong (Gate = 0), thì sử dụng timer 0 trong Mode 1 (nghĩa là M1 M0 = 0 1 ), thời
gian cần được khởi tạo như: 00000001 đã cung cấp timer 1 không được sử dụng.

Đôi khi một trong các timer có thể được sử dụng bởi phần khác của chương trình
và bởi vậy sự khởi tạo của thanh ghi TMOD cần phải được thực hiện mà không
tác động đến các bit đó, điều đó có lẽ đã đặt trong hoạt động trước. Trong trường
hợp này, nó là thực tiễn tốt để initialise TMOD như sau:

TMOD = TMOD | 0X01;


(Chú ý: | là thao tác logical OR) hoặc
TMOD |= 0X01;

Thao tác thực hiện hoạt động logical của mã đang có trong TMOD và mã mới.
Điều này bảo đảm rằng chỉ những bit tương ứng với timer 0 là đã ảnh hưởng và sự
tương ứng đó với timer 1 là không bị thay đổi.

Cuối cùng, chúng ta viết mã chức năng như sau:


Delay: MOV TMOD, #01H
MOV TH0, #4CH
MOV TL0, #00H
CLR TF0
SETB TR0
Wait: JNB TF0, Wait
CLR TR0
CLR TF0
RET

Và trong ‘C’:

void Delay50(void)
{
TMOD |=0X01;
TH0=0X4C;
TL0=0X00;
TF0=0;
TR0=1;
while(TF0==0);
TR0=0;
}

Nếu bội số của 50ms được yêu cầu, hàm trên có thể được gọi bằng tham số mà nó xác
định số lần 50ms trễ cần được thi hành. Điều đó được trình bầy như sau:
void Delay50(unsigned char N)
{
unsigned char i;
for(i=0; i<N; i++)
{
TMOD |=0X01;
TH0=0X4C;
TL0=0X00;
TF0=0;
TR0=1;
while(TF0==0);
TR0=0;
}
}

Hàm nói trên có thể được gọi từ chương trình chính như sau:

#include <reg51.h>
void Delay50(unsigned char N);
void main(void)
{
/* To generate 200 mS delay using repeated 50ms
*/
Delay50(4);
}

Các câu hỏi


Q1. Triển khai hàm theo ‘C’ mà nó sử dụng timer 0 để sinh ra thời gian trễ 1-second.
Viết chương trình chính để minh hoạ cách hàm có thể được gọi để léo lên LED trong
P1.0 ở tốc độ 1 giây ‘ON’ (P1.0 = 1) và 2 giây ‘OFF’ (P1.0 = 0).
Q2. Tính giá trị TL0 và TH0 đối với thời gian trễ của:
I. 10 ms
II. 40 ms
III. 100 ms
Được cung cấp tinh thể tần số 11.0592 MHz.
Q3. Lặp lại Q2 đối với tần số tinh thể là 12 MHz.
Q4. Sử dụng sơ đồ khối thích hợp, miêu tả chức năng của bit ‘Gate’ trong thanh ghi
TMOD.
Q5. Giải thích cách dùng sơ đồ thích hợp mà các timer 8051 có thể thường dùng để đo
tần số của xung đồng hồ thay thế. Giải thích chi tiết, tần số đồng hồ lớn nhất và nhỏ nhất
mà phương pháp do bạn tiến cử có thể đo như thế nào. Có thể đo tần số lớn nhất đã cải
tiến như thế nào?
Q6. Giải thích chi tiết giải pháp đã cho đối với từng trường hợp sau:
I. Cách đo lâu ánh sáng đã ‘ON’ như thế nào.
II. Tính số ô tô vào trong bãi đỗ.
III. Đo số xung mỗi giây từ từ đầu ta của cảm biến.
IV. Đường kính của một bánh xe cho là 2 meters. Bộ cảm biến sinh ra xung đơn khi
bánh xe hoàn thành vòng quay của nó. Giải thích cách có thể sử dụng để xác định
tốc độ của bánh xe tính theo meters/seconds. Giải thích cach có thể dùng timers
trong ứng dụng này?

You might also like