Skip to content

Công nghệ 9 giây

“Website hướng dẫn, thử nghiệm và giải thích công nghệ theo cách dễ hiểu cho mọi người.”

Menu
  • Home
  • Công nghệ
  • STM32
  • ESP32
  • Altium Desinger
  • Kiến thức điện máy
Menu

BÀI 39 – INPUT CAPTURE TRÊN STM32F103: ĐO THỜI GIAN, ĐO TẦN SỐ VÀ ĐO XUNG BẰNG TIMER

Posted on August 23, 2026August 23, 2026 by congnghe9s

BÀI 39 – INPUT CAPTURE TRÊN STM32F103

Đo thời gian, đo tần số và đo độ rộng xung bằng Timer

Ở Bài 38, chúng ta đã hiểu:

PSC → chia clock
CNT → bộ đếm
ARR → giới hạn chu kỳ
CCR → Capture / Compare

Bây giờ chúng ta dùng CCR theo chế độ Input Capture.

Đây là một trong những bài quan trọng nhất của phần Timer, bởi vì từ nó bạn có thể làm:

  • đo tần số;
  • đo chu kỳ;
  • đo độ rộng xung;
  • đo PWM từ thiết bị bên ngoài;
  • đo Echo của HC-SR04;
  • đo tốc độ động cơ;
  • đọc encoder;
  • đo tín hiệu cảm biến.

1. Input Capture là gì?

Hãy bắt đầu bằng một câu cực kỳ đơn giản:

Input Capture là cơ chế để Timer tự động chụp giá trị CNT tại thời điểm một sự kiện xảy ra trên chân GPIO.

Ví dụ Timer đang đếm:

CNT:

0
1
2
3
4
5
6
7
8
9
10
...

Một tín hiệu bên ngoài xuất hiện cạnh lên:

          ↑
──────────┘
          Rising Edge

Phần cứng Timer lập tức:

CNT = 1250
       ↓
CCR1 = 1250

CPU không cần phải đứng đó đọc CNT liên tục.


2. Đây là điểm khác biệt rất lớn

Trong polling, bạn phải làm:

while (1)
{
    if (GPIOA->IDR & (1 << 0))
    {
        time = TIM2->CNT;
    }
}

CPU phải liên tục kiểm tra GPIO.

Trong Input Capture:

Tín hiệu
   ↓
TIM2_CH1
   ↓
Capture Hardware
   ↓
CCR1 = CNT
   ↓
Interrupt
   ↓
CPU xử lý

Phần cứng Timer làm công việc chính.


3. Hãy hình dung một đồng hồ bấm giờ

Input Capture giống như:

START
  ↓
Timer bắt đầu đếm
  ↓
───────────────
       ↑
     Event
       ↓
Timer chụp CNT

Ví dụ:

Start:
CNT = 100

Event:
CNT = 750

Ta có:

ΔCNT = 750 - 100
     = 650

Nếu mỗi tick là:

1 µs

thì:

Δt = 650 µs

4. Cấu trúc Input Capture

Sơ đồ:

                    STM32F103
                        │
                        │ GPIO
                        ▼
                 TIM2_CH1 Input
                        │
                        ▼
                  Capture Logic
                        │
                        ▼
                     CCR1
                        │
                        ▼
                      CNT
                        │
                        ▼
                    Interrupt

Bạn cần nhớ:

Input Capture không tạo ra thời gian. Nó ghi lại thời điểm xảy ra sự kiện.


5. Timer vẫn phải chạy

Ví dụ:

TIM2 clock
   ↓
PSC
   ↓
CNT tăng

Nếu Timer không chạy:

CNT = 0

thì Input Capture chẳng có gì để chụp.


6. Chọn tốc độ Timer

Đây là bước rất quan trọng.

Giả sử STM32F103 chạy:

72 MHz

Ta muốn:

1 tick = 1 µs

Cần:

[
72MHz / 1MHz = 72
]

Do PSC dùng:

[
PSC+1
]

nên:

TIM2->PSC = 71;

Kết quả:

72 MHz / 72
= 1 MHz

Do đó:

1 tick = 1 µs

Đây là cấu hình rất đẹp để đo thời gian.


7. Ví dụ

Timer:

PSC = 71;

thì:

CNT = 0
CNT = 1       → 1 µs
CNT = 2       → 2 µs
CNT = 3       → 3 µs
...
CNT = 1000    → 1000 µs

Hay:

1000 µs = 1 ms

8. Đo chu kỳ tín hiệu

Giả sử tín hiệu:

       ┌───────┐       ┌───────┐
───────┘       └───────┘       └──────
       ↑               ↑
       A               B

Cạnh lên đầu tiên:

CCR1 = 1000

Cạnh lên tiếp theo:

CCR1 = 3000

Ta có:

3000 - 1000 = 2000

Vì:

1 tick = 1 µs

nên:

T = 2000 µs
  = 2 ms

9. Từ chu kỳ suy ra tần số

Công thức:

[
f = \frac{1}{T}
]

Nếu:

T = 2 ms

thì:

[
f=\frac{1}{0.002}=500Hz
]

Vậy Input Capture cho phép:

đo thời gian
    ↓
đo chu kỳ
    ↓
đo tần số

10. Đo độ rộng xung

Đây là ứng dụng còn thú vị hơn.

Giả sử:

         ┌────────────┐
─────────┘            └─────────
         ↑            ↑
       Rising       Falling

Ta cần biết:

HIGH time

Nếu:

Rising  → CCR1 = 1000
Falling → CCR1 = 2500

thì:

HIGH width = 2500 - 1000
           = 1500 µs

11. Độ rộng xung và Duty Cycle

Nếu chu kỳ:

T = 5000 µs

và thời gian HIGH:

Ton = 1500 µs

thì:

[
Duty=\frac{Ton}{T}\times100%
]

[
Duty=\frac{1500}{5000}\times100=30%
]

Vậy Input Capture có thể đo:

Frequency
+
Duty Cycle

của tín hiệu PWM bên ngoài.


12. Rising Edge và Falling Edge

Có hai loại cạnh cơ bản:

Rising edge

LOW → HIGH

Falling edge

HIGH → LOW

Input Capture có thể được cấu hình để bắt:

Rising

hoặc:

Falling

hoặc tùy cấu hình có thể xử lý cả hai.


13. Thanh ghi quan trọng: CCMR1

Đối với TIM2 Channel 1/2, chúng ta sẽ gặp:

TIM2->CCMR1

Nó cấu hình Capture/Compare Mode.

Đối với Input Capture Channel 1:

CC1S

xác định Channel 1 hoạt động như Input Capture.


14. Thanh ghi CCER

Chúng ta đã nhắc tới nó ở Bài 38:

TIM2->CCER

Nó quyết định:

  • Channel enable;
  • polarity;
  • input/output behavior.

Ví dụ ý tưởng:

CC1E → enable CH1
CC1P → polarity

15. Thanh ghi CCR1

Khi Input Capture xảy ra:

TIM2->CCR1

sẽ chứa giá trị CNT được chụp.

Ví dụ:

CNT = 2456

External edge
      ↓
Capture
      ↓
CCR1 = 2456

Đây chính là “ảnh chụp thời gian”.


16. Thanh ghi SR

Timer báo sự kiện bằng flag:

TIM2->SR

Đối với Channel 1:

TIM_SR_CC1IF

Nếu:

TIM2->SR & TIM_SR_CC1IF

đúng, nghĩa là:

Channel 1 vừa xảy ra Capture/Compare event.


17. Thanh ghi DIER

Muốn Capture tạo interrupt:

TIM2->DIER |= TIM_DIER_CC1IE;

Trong đó:

CC1IE

=

Capture/Compare 1 Interrupt Enable.


18. Đường đi hoàn chỉnh

Khi tín hiệu ngoài xuất hiện:

GPIOA
  ↓
TIM2_CH1
  ↓
Input Capture
  ↓
CNT được chụp
  ↓
CCR1
  ↓
CC1IF = 1
  ↓
NVIC
  ↓
TIM2_IRQHandler()

Bạn nên thuộc sơ đồ này.


19. Ví dụ cấu hình TIM2_CH1

Trên STM32F103, TIM2_CH1 mặc định nằm trên:

PA0

Do đó chúng ta có thể dùng:

PA0 → TIM2_CH1

để nhận tín hiệu.


20. Cấu hình GPIO PA0

PA0 cần được cấu hình làm Input.

Ví dụ input floating:

void GPIO_InputCapture_Init(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    /* PA0 = Input floating */
    GPIOA->CRL &= ~(0xF << 0);
    GPIOA->CRL |=  (0x4 << 0);
}

Trong đó:

CNF = 01
MODE = 00

→ Input floating.


21. Cấu hình Timer 1 µs/tick

void TIM2_InputCapture_Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

    /*
        72 MHz / 72
        = 1 MHz

        1 tick = 1 us
    */

    TIM2->PSC = 71;

    TIM2->ARR = 0xFFFF;

    TIM2->CNT = 0;
}

TIM2 là Timer 32-bit trên STM32F103, nhưng để học Input Capture cơ bản, bạn có thể coi CNT như một bộ đếm đủ lớn và tập trung vào cơ chế Capture.


22. Cấu hình Channel 1 Input Capture

Đây là phần quan trọng.

Ta cần đặt:

CC1S = 01

để:

CH1 → Input Capture

Có thể cấu hình:

TIM2->CCMR1 &= ~(TIM_CCMR1_CC1S);
TIM2->CCMR1 |= TIM_CCMR1_CC1S_0;

23. Chọn Rising Edge

Ta muốn bắt:

LOW → HIGH

Mặc định polarity là rising.

Enable channel:

TIM2->CCER |= TIM_CCER_CC1E;

24. Enable interrupt

TIM2->DIER |= TIM_DIER_CC1IE;

NVIC:

NVIC_SetPriority(TIM2_IRQn, 2);
NVIC_EnableIRQ(TIM2_IRQn);

Cuối cùng:

TIM2->CR1 |= TIM_CR1_CEN;

Timer bắt đầu chạy.


25. ISR cơ bản

volatile uint32_t capture_value = 0;

void TIM2_IRQHandler(void)
{
    if (TIM2->SR & TIM_SR_CC1IF)
    {
        capture_value = TIM2->CCR1;

        TIM2->SR &= ~TIM_SR_CC1IF;
    }
}

Mỗi khi có cạnh lên:

PA0
 ↓
Capture
 ↓
CCR1
 ↓
capture_value

26. Nhưng như vậy mới chỉ đọc được một thời điểm

Ví dụ:

Capture 1 → 1000
Capture 2 → 3000

Chúng ta cần lưu:

uint32_t capture1;
uint32_t capture2;

và tính:

period = capture2 - capture1;

27. Code đo chu kỳ

volatile uint32_t capture1 = 0;
volatile uint32_t capture2 = 0;
volatile uint32_t period = 0;

volatile uint8_t capture_state = 0;

void TIM2_IRQHandler(void)
{
    if (TIM2->SR & TIM_SR_CC1IF)
    {
        uint32_t current;

        current = TIM2->CCR1;

        if (capture_state == 0)
        {
            capture1 = current;

            capture_state = 1;
        }
        else
        {
            capture2 = current;

            period = capture2 - capture1;

            capture_state = 0;
        }

        TIM2->SR &= ~TIM_SR_CC1IF;
    }
}

28. Có một vấn đề quan trọng: Timer overflow

Giả sử:

capture1 = 65000
capture2 = 100

Nếu bạn nghĩ:

100 - 65000

là sai thì không hoàn toàn đúng.

Với kiểu:

uint16_t

phép trừ unsigned có thể tự xử lý vòng quay.

Ví dụ:

uint16_t delta;

delta = capture2 - capture1;

sẽ cho khoảng thời gian đúng nếu khoảng đo nằm trong một vòng Timer.


29. Với uint32_t

Bạn cũng có thể dùng:

uint32_t delta;

delta = capture2 - capture1;

Miễn là biến là unsigned.

Đây chính là kỹ thuật chúng ta đã gặp ở millis():

(uint32_t)(now - last)

30. Đây là một kỹ thuật cực kỳ quan trọng trong Embedded C

Timer chạy:

0 → MAX → 0 → MAX → ...

Không phải:

0 → MAX → chết

Do đó chương trình phải được thiết kế để chịu được overflow.


31. Đo tần số

Nếu Timer tick:

1 µs

và:

period = 2000

thì:

T = 2000 µs

Đổi sang giây:

0.002 s

Tần số:

f = 1 / 0.002
  = 500 Hz

32. Có thể tính trực tiếp

Nếu:

Timer frequency = 1 MHz

thì:

[
f_{signal}=\frac{1,000,000}{period}
]

Ví dụ:

period = 2000

thì:

f = 1,000,000 / 2000
  = 500 Hz

33. Đo độ rộng xung bằng cách đổi polarity

Ta có:

Rising
 ↓
CCR1 = start

Sau đó chuyển sang:

Falling
 ↓
CCR1 = end

Rồi:

width = end - start;

34. Đây chính là cách đo Echo HC-SR04

Hãy nhớ hình này:

TRIG

____┌──┐________________
    │  │
    └──┘


ECHO

________┌────────────────┐________
        ↑                ↑
      Rising           Falling

Timer:

Rising
  ↓
start = CCR

Falling
  ↓
end = CCR

Sau đó:

echo_time = end - start

35. Từ Echo Time đến khoảng cách

Công thức:

[
Distance = \frac{Time \times 0.0343}{2}
]

Nếu Time tính bằng µs:

Distance(cm)
≈ Time(µs) / 58

Ví dụ:

Echo = 1740 µs

thì:

Distance ≈ 1740 / 58
         ≈ 30 cm

Đây chính là con số 30 cm mà bạn từng dùng trong robot tránh vật cản.


36. Vì vậy Input Capture rất phù hợp cho robot

Thay vì:

while (ECHO == LOW);

start = micros();

while (ECHO == HIGH);

end = micros();

CPU phải chờ.

Input Capture:

ECHO Rising
    ↓
Hardware Capture

ECHO Falling
    ↓
Hardware Capture

CPU
 ↓
tính khoảng cách

CPU không phải đứng chờ toàn bộ thời gian Echo.


37. So sánh hai cách

Cách polling

CPU
 ↓
chờ ECHO
 ↓
chờ ECHO
 ↓
chờ ECHO
 ↓
đọc thời gian

Input Capture

Timer Hardware
 ↓
chờ cạnh
 ↓
capture tự động
 ↓
CPU xử lý khi cần

Đây là tư duy embedded rất quan trọng:

Đẩy công việc thời gian chính xác sang phần cứng.


38. Nhưng có một điều bạn cần đặc biệt chú ý

Trên Blue Pill:

STM32F103C8T6

Timer Clock không phải lúc nào cũng đơn giản là:

72 MHz

Trong cấu hình chuẩn thường gặp:

SYSCLK = 72 MHz
APB1 = 36 MHz

Nhưng Timer trên APB1 có cơ chế:

Nếu APB1 prescaler khác 1, clock Timer có thể được nhân 2.

Vì vậy:

PCLK1 = 36 MHz
TIM2CLK = 72 MHz

Đây là lý do chúng ta thường sử dụng:

TIM2 = 72 MHz

trong cấu hình Blue Pill 72 MHz.


39. Đây là chỗ người mới rất dễ sai

Bạn nhìn:

APB1 = 36 MHz

rồi tính:

TIM2 = 36 MHz

→ có thể sai.

Phải xem clock tree.


40. Bài tập tính toán

Giả sử:

SYSCLK = 72 MHz
APB1 = 36 MHz
APB1 Prescaler = 2

thì:

TIM2CLK = 72 MHz

Muốn:

1 µs/tick

ta dùng:

PSC = 71;

vì:

[
72MHz/(71+1)=1MHz
]


41. Một vấn đề khác: tín hiệu quá chậm

Nếu bạn dùng:

1 µs/tick

thì Timer có thể đo được khoảng:

0 → 65535 µs

nếu sử dụng bộ đếm 16-bit.

Tức:

≈ 65.5 ms

Nếu tín hiệu chậm hơn:

100 ms

có thể xảy ra overflow.

Khi đó bạn có thể:

  • giảm tốc độ Timer;
  • dùng Timer 32-bit;
  • đếm số lần overflow;
  • dùng interrupt Update;
  • hoặc kết hợp nhiều Timer.

42. Ví dụ

Nếu:

tick = 10 µs

thì:

65535 × 10 µs
≈ 655 ms

Phạm vi đo rộng hơn.

Nhưng độ phân giải giảm.


43. Đây là bài toán Resolution vs Range

Timer:

1 µs/tick

Ưu điểm:

độ phân giải cao

Nhược điểm:

dễ overflow với tín hiệu dài

Timer:

10 µs/tick

Ưu điểm:

đo được khoảng thời gian dài hơn

Nhược điểm:

độ phân giải thấp hơn

Kỹ sư phải chọn phù hợp ứng dụng.


44. Một ví dụ thực tế

HC-SR04

Khoảng cách:

2 cm → 400 cm

Echo tối đa khoảng:

23 ms

Dùng:

1 µs/tick

hoàn toàn hợp lý.


45. Đo tốc độ động cơ

Giả sử động cơ có:

1 xung / vòng

Input Capture đo:

T = 20 ms

thì:

f = 50 Hz

Nếu:

1 xung = 1 vòng

thì:

RPM = 50 × 60
    = 3000 RPM

Nếu encoder có:

20 xung/vòng

thì:

RPM = 50 × 60 / 20
    = 150 RPM

46. Vì vậy Input Capture xuất hiện ở rất nhiều hệ thống

Encoder
   ↓
Input Capture
   ↓
Frequency
   ↓
RPM

hoặc:

PWM từ thiết bị
   ↓
Input Capture
   ↓
Period + Ton
   ↓
Frequency + Duty

47. Một khái niệm rất hay: Hardware Timestamp

CCR1 thực chất có thể được hiểu là:

Hardware timestamp

Ví dụ:

Event A → timestamp = 10000
Event B → timestamp = 12500

Khoảng cách thời gian:

2500 ticks

Đây là tư duy cực kỳ hữu ích khi lập trình embedded.


48. Input Capture không cần CPU đọc liên tục

Đây là một trong những điều quan trọng nhất của Bài 39:

❌ Không cần:

while(1)
{
    đọc GPIO;
    đọc CNT;
}

Thay vào đó:

✅ Hardware:

GPIO edge
   ↓
Capture
   ↓
CCR
   ↓
Interrupt
   ↓
CPU xử lý

49. Code khung hoàn chỉnh để học

Dưới đây là một firmware tối giản để bạn nghiên cứu cấu trúc:

#include "stm32f10x.h"

volatile uint32_t capture1 = 0;
volatile uint32_t capture2 = 0;

volatile uint32_t period = 0;

volatile uint8_t capture_state = 0;


/* =====================================================
   GPIO PA0 = TIM2_CH1
   ===================================================== */

void GPIO_Init(void)
{
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    /*
        PA0 = Input Floating
    */

    GPIOA->CRL &= ~(0xF << 0);
    GPIOA->CRL |=  (0x4 << 0);
}


/* =====================================================
   TIM2 INPUT CAPTURE
   ===================================================== */

void TIM2_InputCapture_Init(void)
{
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;

    /*
        TIM2 clock = 72 MHz

        72 MHz / 72
        = 1 MHz

        1 tick = 1 us
    */

    TIM2->PSC = 71;

    /*
        TIM2 is 32-bit on STM32F103,
        but this example uses a large period.
    */

    TIM2->ARR = 0xFFFFFFFF;

    TIM2->CNT = 0;

    /*
        CC1S = 01
        CH1 configured as Input Capture
    */

    TIM2->CCMR1 &= ~TIM_CCMR1_CC1S;
    TIM2->CCMR1 |= TIM_CCMR1_CC1S_0;

    /*
        Rising edge
    */

    TIM2->CCER &= ~TIM_CCER_CC1P;

    /*
        Enable Channel 1
    */

    TIM2->CCER |= TIM_CCER_CC1E;

    /*
        Enable CC1 interrupt
    */

    TIM2->DIER |= TIM_DIER_CC1IE;

    /*
        NVIC
    */

    NVIC_SetPriority(TIM2_IRQn, 2);
    NVIC_EnableIRQ(TIM2_IRQn);

    /*
        Start Timer
    */

    TIM2->CR1 |= TIM_CR1_CEN;
}


/* =====================================================
   TIM2 INTERRUPT
   ===================================================== */

void TIM2_IRQHandler(void)
{
    if (TIM2->SR & TIM_SR_CC1IF)
    {
        uint32_t current;

        current = TIM2->CCR1;

        if (capture_state == 0)
        {
            capture1 = current;

            capture_state = 1;
        }
        else
        {
            capture2 = current;

            period = capture2 - capture1;

            capture_state = 0;
        }

        /*
            Clear Capture flag
        */

        TIM2->SR &= ~TIM_SR_CC1IF;
    }
}


/* =====================================================
   MAIN
   ===================================================== */

int main(void)
{
    GPIO_Init();

    TIM2_InputCapture_Init();

    while (1)
    {
        /*
            period contains signal period in us.

            frequency:
                f = 1000000 / period
        */
    }
}

50. Một lưu ý về code trên

Đây là code học nguyên lý, chưa phải driver Input Capture hoàn chỉnh cho sản phẩm.

Khi làm hệ thống thực tế, chúng ta còn phải xử lý:

Overflow
Noise
Glitch
Invalid signal
Timeout
Multiple captures
Interrupt race
Signal polarity
Filter

Đặc biệt là:

IC Filter

mà chúng ta sẽ gặp khi đi sâu hơn.


51. Bài tập thực hành rất đáng làm

Nếu chưa có signal generator, bạn có thể dùng một Timer khác để tạo PWM/tín hiệu rồi đưa sang PA0.

Ví dụ:

Timer tạo xung
       │
       ▼
      PA?
       │
       │ dây nối
       ▼
      PA0
       │
       ▼
TIM2_CH1 Input Capture

Sau đó kiểm tra:

period
frequency

52. Một bài thực hành cực kỳ phù hợp với bạn

Vì bạn đang có:

STM32 Blue Pill
+
HC-SR04

hãy hướng tới cấu trúc:

             STM32F103
                 │
        ┌────────┴────────┐
        │                 │
       TRIG              ECHO
        │                 │
        ▼                 ▼
     GPIO OUT          TIM2_CH1
                          │
                          ▼
                    Input Capture
                          │
                          ▼
                       CCR1
                          │
                          ▼
                      Echo time
                          │
                          ▼
                     Distance
                          │
                          ▼
                        cm

Đây sẽ là bài thực hành tuyệt vời để chuyển kiến thức Timer từ lý thuyết sang phần cứng thật.


53. Tổng kết Bài 39

Bạn cần nhớ 7 ý sau:

① Timer vẫn chạy bằng:

PSC → CNT

② Input Capture xảy ra khi:

External Edge
      ↓
Capture

③ Khi Capture:

CCR1 = CNT

④ Hai lần Capture:

CCR2 - CCR1

cho ta khoảng thời gian.

⑤ Từ khoảng thời gian:

Period → Frequency

⑥ Rising + Falling:

Rising → start
Falling → end

cho ta:

Pulse Width

⑦ Ứng dụng:

HC-SR04
Encoder
RPM
PWM measurement
Frequency meter
Pulse measurement

54. Chuỗi kiến thức Timer của chúng ta lúc này

Bài 36
TIM Interrupt
     ↓
Bài 37
millis + Software Scheduler
     ↓
Bài 38
PSC + CNT + ARR + CCR
     ↓
Bài 39
INPUT CAPTURE
     ↓
Bài 40
OUTPUT COMPARE
     ↓
Bài 41
PWM
     ↓
Bài 42
SERVO bằng PWM
     ↓
Bài 43
HC-SR04 bằng Input Capture

Tuy nhiên, Bài 40 có thể học trước hoặc sau PWM. Với mục tiêu học STM32 thật chắc, tôi khuyên đi theo hướng:

Bài 40 – OUTPUT COMPARE chuyên sâu → Bài 41 – PWM từ TIM → Bài 42 – Servo → Bài 43 – HC-SR04 bằng Input Capture.

Như vậy bạn sẽ hiểu được toàn bộ chuỗi:

              STM32 TIMER
                   │
        ┌──────────┼──────────┐
        │          │          │
       CNT         │         CCR
        │          │          │
       ARR         │     ┌────┴────┐
        │          │     │         │
     Time Base     │  Compare   Capture
                   │     │         │
                   │     ▼         ▼
                   │   Output    Input
                   │     │         │
                   │     ▼         ▼
                   │    PWM     đo thời gian
                   │             │
                   │             ▼
                   │           HC-SR04
                   │
                   ▼
                 Timer
              Interrupt

Đây chính là lúc Timer STM32 bắt đầu trở thành một “thiết bị phần cứng thông minh” chứ không còn đơn thuần là bộ tạo delay nữa.

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Recent Posts

  • Bạn có thể hướng dẫn tôi quy trình sửa chữa một mainboard laptop cũng như mainboard của máy tính để bàn không?
  • Có những mức nguồn DC nào trên một bo mạch mainboard laptop?Kỹ thuật đốt dòng để kiểm tra nguồn laptop được thực hiện như thế nào?
  • bài tiếp theo hợp lý là: BÀI 63 – SENSOR FUSION THỰC CHIẾN: ENCODER + IMU MPU6050 + EKF + ODOMETRY X,Y,θ TRÊN STM32F103
  • BÀI 62 – EKF (EXTENDED KALMAN FILTER) CHO ROBOT 2 BÁNH: FUSION ENCODER + IMU + ƯỚC LƯỢNG X, Y, θ, V, ω
  • BÀI 61 – KALMAN FILTER CHO ENCODER + IMU: ƯỚC LƯỢNG TỐC ĐỘ, GÓC θ VÀ SENSOR FUSION

Recent Comments

No comments to show.

Archives

  • September 2026
  • August 2026
  • July 2026
  • June 2026
  • May 2026
  • February 2026

Categories

  • Altium Desinger
  • Công nghệ
  • ESP32
  • Khác
  • Kiến thức điện máy
  • STM32
Live 3D Globes Visitor
©2026 Công nghệ 9 giây | Design: Newspaperly WordPress Theme