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 22 – GPIO STM32F103: ĐỌC NÚT NHẤN, INPUT, PULL-UP/PULL-DOWN VÀ DEBOUNCE

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

BÀI 22 – GPIO STM32F103: ĐỌC INPUT, PULL-UP/PULL-DOWN VÀ NÚT NHẤN

Ở Bài 21, chúng ta đã đi vào GPIO và hiểu rằng một chân GPIO có thể được cấu hình để xuất tín hiệu (Output) hoặc đọc tín hiệu (Input).

Bài 22 sẽ chuyển sang phần cực kỳ quan trọng:

STM32 làm thế nào để biết một chân đang ở mức HIGH hay LOW?

Đây chính là nền tảng để đọc nút nhấn, công tắc, cảm biến, tín hiệu từ module bên ngoài…


1. GPIO Input là gì?

Ví dụ:

Nút nhấn
   │
   └────── PA0
           │
        STM32F103

Khi PA0 được cấu hình Input, STM32 không điều khiển điện áp trên PA0.

Thay vào đó, STM32 chỉ quan sát:

PA0 = 0V       → LOW
PA0 ≈ 3.3V     → HIGH

Ta có thể hình dung:

              STM32
          ┌─────────────┐
          │             │
3.3V ─────┤ PA0         │
          │   INPUT     │
          │             │
          └─────────────┘
                ↑
             đọc mức điện áp

2. Input khác Output như thế nào?

Đây là điểm bạn cần phân biệt thật chắc.

Output

STM32 đẩy điện áp ra ngoài:

STM32 PA0 ───────► LED

Ví dụ:

PA0 = 1;

→ PA0 xuất khoảng 3.3V.


Input

STM32 đọc điện áp từ bên ngoài:

Nút nhấn ───────► PA0 STM32

Ví dụ:

if (PA0 == 1)
{
    // có tín hiệu HIGH
}

3. Vấn đề cực kỳ quan trọng: Floating Input

Giả sử:

       không nối gì
            │
            │
            ▼
          PA0

PA0 được cấu hình Input nhưng không nối với nguồn nào.

Khi đó PA0 có thể đọc:

0
1
0
1
1
0
...

một cách không ổn định.

Đây gọi là:

Floating Input – ngõ vào bị thả nổi.


4. Tại sao Floating lại nguy hiểm?

Một chân Input có trở kháng rất cao.

Nó có thể bị ảnh hưởng bởi:

  • nhiễu điện từ
  • điện dung ký sinh
  • dây dẫn dài
  • tín hiệu từ các chân khác
  • môi trường xung quanh

Vì vậy:

PA0 không nối gì
      ↓
điện áp không xác định
      ↓
GPIO đọc lúc 0 lúc 1

Đây là lý do khi làm mạch thực tế, chúng ta thường sử dụng:

Pull-up hoặc Pull-down resistor.


5. Pull-up là gì?

Pull-up nghĩa là kéo chân Input lên VCC thông qua một điện trở.

       3.3V
        │
       [R]
        │
        ├──── PA0
        │
      Button
        │
       GND

Khi nút không nhấn:

3.3V
 │
[R]
 │
PA0

→ PA0 = HIGH.

Khi nút nhấn:

3.3V
 │
[R]
 │
PA0
 │
Button
 │
GND

→ PA0 = LOW.

Vậy:

Trạng thái PA0
Không nhấn 1
Nhấn 0

Đây là kiểu mạch rất phổ biến.


6. Pull-down là gì?

Ngược lại:

       3.3V
        │
      Button
        │
        ├──── PA0
        │
       [R]
        │
       GND

Khi không nhấn:

PA0 → LOW

Khi nhấn:

PA0 → HIGH

Bảng trạng thái:

Trạng thái PA0
Không nhấn 0
Nhấn 1

7. STM32 có điện trở Pull-up/Pull-down bên trong

Đây là một điểm rất hay của STM32.

Bạn không nhất thiết lúc nào cũng phải mắc điện trở ngoài.

GPIO STM32F103 có thể cấu hình:

Input Floating
Input Pull-up
Input Pull-down

Ví dụ:

PA0
 │
 ├── Pull-up nội
 │
 └── Input circuit

STM32 sẽ tạo một đường kéo lên bên trong chip.


8. Hãy nhìn GPIO theo kiểu “đường tín hiệu”

Từ những bài trước, bạn đã học:

CPU
 │
 ▼
Peripheral
 │
 ▼
GPIO Register
 │
 ▼
PA0

Khi đọc GPIO, CPU thực chất đang đọc bit tương ứng trong thanh ghi Input Data Register.

Thanh ghi quan trọng là:

IDR – Input Data Register


9. GPIOx_IDR

Ví dụ GPIOA:

GPIOA_IDR

Đây là thanh ghi chứa trạng thái logic hiện tại của các chân GPIOA.

Ví dụ:

GPIOA_IDR

bit 15 ─ PA15
bit 14 ─ PA14
...
bit 1  ─ PA1
bit 0  ─ PA0

Nếu:

PA0 = HIGH

thì:

GPIOA_IDR bit 0 = 1

Nếu:

PA0 = LOW

thì:

GPIOA_IDR bit 0 = 0

10. Đây chính là kiến thức từ Bài 16

Bạn đã học toán tử:

&
|
^
~
<<
>>

Bây giờ chúng ta sử dụng chúng trong thực tế.

Muốn kiểm tra PA0:

if (GPIOA->IDR & (1 << 0))
{
    // PA0 = HIGH
}

Giải thích:

1 << 0

cho:

00000001

Sau đó:

GPIOA->IDR & 00000001

chỉ kiểm tra:

bit 0

11. Kiểm tra PA5

Nếu muốn đọc PA5:

if (GPIOA->IDR & (1 << 5))
{
    // PA5 HIGH
}

Vì:

1 << 5

= 0010 0000

Nó tạo ra mask cho bit 5.


12. Cách viết dễ hiểu hơn

Bạn có thể định nghĩa:

#define PA0_PIN 0

sau đó:

if (GPIOA->IDR & (1 << PA0_PIN))
{
    // HIGH
}

Hoặc:

#define BUTTON_PIN 0

if (GPIOA->IDR & (1 << BUTTON_PIN))
{
    // Button input HIGH
}

13. Ví dụ thực tế: nút nhấn + LED PC13

Ta có:

Button
   │
   └──── PA0
          STM32
            │
            └──── PC13 ─── LED

Giả sử PA0 sử dụng Pull-up:

Không nhấn → PA0 = 1
Nhấn       → PA0 = 0

Chương trình:

if ((GPIOA->IDR & (1 << 0)) == 0)
{
    // Button đang nhấn
    GPIOC->BSRR = (1 << 13);
}
else
{
    // Button không nhấn
    GPIOC->BSRR = (1 << (13 + 16));
}

Bạn có thể thấy một điều rất thú vị:

Input dùng IDR để đọc.

Output dùng BSRR để điều khiển.


14. IDR và ODR

Hai thanh ghi này rất quan trọng:

IDR = Input Data Register
ODR = Output Data Register

Có thể nhớ:

Input  → IDR → đọc
Output → ODR → dữ liệu xuất

Ví dụ:

GPIOA->IDR

→ đọc trạng thái chân.

Trong khi:

GPIOA->ODR

→ chứa dữ liệu output.


15. Nhưng đừng vội nhầm IDR với ODR

Ví dụ PA0 đang là Output:

PA0 ─── LED

Bạn ghi:

GPIOA->ODR |= (1 << 0);

→ yêu cầu PA0 xuất HIGH.

Nhưng nếu PA0 là Input:

GPIOA->IDR & (1 << 0)

→ đọc mức điện áp thực tế tại chân PA0.


16. Một điều cực kỳ quan trọng: Debounce

Nút nhấn cơ học không chuyển trạng thái sạch như:

HIGH ───────────── LOW

Thực tế thường giống:

HIGH ────┐
         │ ┌─┐
         └─┘ └─┐
               └──── LOW

Hiện tượng này gọi là:

Button bouncing – nảy phím.

Một lần nhấn có thể khiến STM32 tưởng rằng người dùng nhấn nhiều lần.

Ví dụ:

Nhấn 1 lần
   ↓
STM32 đọc:
1 0 1 0 1 0 0 0

Nếu chương trình không xử lý debounce, nó có thể nhận nhiều lần nhấn.


17. Debounce đơn giản bằng delay

Ví dụ:

if ((GPIOA->IDR & (1 << 0)) == 0)
{
    delay_ms(20);

    if ((GPIOA->IDR & (1 << 0)) == 0)
    {
        // Xác nhận nút thực sự được nhấn
    }
}

Ý tưởng:

Phát hiện LOW
     ↓
đợi 20 ms
     ↓
đọc lại
     ↓
vẫn LOW?
     ↓
đúng là nhấn

Sau này chúng ta sẽ học debounce bằng timer, tốt hơn rất nhiều so với delay.


18. STM32F103 và mức logic

Blue Pill của bạn sử dụng STM32F103.

GPIO hoạt động với mức logic dựa trên nguồn I/O của MCU, thông thường:

VDD ≈ 3.3V

Do đó khi làm việc với Blue Pill, hãy hình dung:

LOW  ≈ 0V
HIGH ≈ 3.3V

Không nên mặc định rằng GPIO của STM32 là 5V tolerant ở mọi chân và mọi chế độ.

Một số chân STM32F103 có khả năng chịu 5V trong điều kiện nhất định, nhưng phải xem đúng datasheet của chân đó.


19. Bài thực hành cho Blue Pill của bạn

Bạn có thể dùng chính Blue Pill đang có.

Phần cứng

STM32 Blue Pill

PA0 ───── Button ───── GND

Cấu hình PA0:

Input Pull-up

LED onboard:

PC13

Logic

          PA0
           │
       ┌───┴───┐
       │ Button│
       └───┬───┘
           │
          GND

Không nhấn:

PA0 = HIGH
PC13 = trạng thái bình thường

Nhấn:

PA0 = LOW
PC13 = đổi trạng thái

20. Bài tập quan trọng nhất

Đừng chỉ học thuộc:

GPIOA->IDR

Hãy hiểu chuỗi tư duy:

Nút nhấn
   ↓
điện áp tại PA0
   ↓
GPIO input circuit
   ↓
GPIOA_IDR
   ↓
bit 0
   ↓
CPU đọc
   ↓
if()
   ↓
quyết định
   ↓
PC13

Đây chính là cách một chương trình C trên STM32 tương tác với phần cứng thật.


21. Kiến thức cần nhớ sau Bài 22

Bạn nên thuộc ý nghĩa, không nhất thiết học vẹt mã lệnh:

GPIO Input
GPIO Output

Floating
Pull-up
Pull-down

IDR
ODR
BSRR

HIGH
LOW

1 << bit
GPIOx->IDR & mask

Button debounce

Đặc biệt nhớ:

                 GPIO

        ┌────────────────────┐
        │                    │
        │ INPUT              │
        │   ↓                │
Pin ───►│ IDR                │
        │                    │
        │ OUTPUT             │
        │   ↑                │
        │ ODR / BSRR         │
        └────────────────────┘

Và đây là mốc rất quan trọng:

Bài 17: Memory Map
↓
Bài 18–21: GPIO / Register / Output
↓
Bài 22: GPIO Input + IDR + Pull-up/Pull-down
↓
Bài tiếp theo: chúng ta có thể đi sâu vào GPIO Register của STM32F103: CRL, CRH, IDR, ODR, BSRR, BRR và tự cấu hình PA0/PC13 không dùng HAL, không dùng Arduino, chỉ bằng thanh ghi.

Đó sẽ là lúc bạn bắt đầu thực sự thấy STM32 hoạt động ở cấp độ phần cứng.

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