Lập trình STM32F103 thanh ghi cấu hình GPIO Input STM32F103RCT6

Trong bài viết này, chúng ta sẽ tìm hiểu cách lập trình STM32F103 thanh ghi để cấu hình GPIO input STM32F103 và đọc trạng thái nút nhấn thông qua thanh ghi GPIO_IDR. Ví dụ minh họa sử dụng vi điều khiển STM32F103RCT6, cấu hình chân PC1 làm input pull-up để điều khiển bật/tắt LED PA8.
Bài viết tập trung vào lập trình bare-metal, không sử dụng thư viện HAL, giúp bạn hiểu rõ bản chất hoạt động của GPIO trong STM32.

Mục tiêu bài lập trình STM32F103 thanh ghi cấu hình GPIO input

  • Cấu hình PC1 làm GPIO input pull-up
  • Điều khiển LED PA8 (LED0)

Define struct thanh ghi GPIO_IDR cho lập trình STM32F103 thanh ghi

Thanh ghi GPIO_IDR: port input data register GPIOx_IDR trong hướng dẫn lập trình stm32f103 thanh ghi cấu hình GPIO output
Thanh ghi GPIO_IDR: port input data register GPIOx_IDR

Các thanh ghi cấu hình GPIO Input trong lập trình STM32F103 thanh ghi

Thanh ghi GPIO_IDR trong STM32F103

Thanh ghi GPIO_IDR: port input data register GPIOx_IDR trong hướng dẫn lập trình stm32f103 thanh ghi cấu hình GPIO output
Thanh ghi GPIO_IDR: port input data register GPIOx_IDR

GPIO_IDR là một thanh ghi rất quan trọng trong bộ GPIO của vi điều khiển STM32F1 (và nhiều dòng STM32 khác).

Thanh ghi GPIO_IDR – Thanh ghi dữ liệu ngõ vào của một cổng GPIO. GPIOx_IDR dùng để đọc trạng thái logic tại các chân GPIO (ngõ vào). Thanh ghi này chỉ cho phép đọc (read-only) và phản ánh mức điện áp hiện tại trên các chân được cấu hình làm đầu vào.

Mỗi bit trong GPIOx_IDR tương ứng với một chân pin của cổng đó:

  • PA0 ↔ bit 0
  • PA1 ↔ bit 1
  • v.v…

Khi đọc GPIOx_IDR, ta biết được:

  • Mức logic 0 (chân ở mức thấp – GND)
  • Mức logic 1 (chân ở mức cao – 3.3V)

Ví dụ thanh ghi IDR

GPIOA_IDR = 0b0000 0000 0001 0100

Nghĩa là:

  • PA2 = 1 (mức cao)
  • PA4 = 1 (mức cao)
  • Các chân còn lại = 0

Thanh ghi GPIO_ODR – Thanh ghi dữ liệu ngõ ra

Thanh ghi GPIO_ODR: port output data register GPIOx_ODR trong hướng dẫn lập trình STM32f103 cấu hình GPIO Input STM32F103RCT6
Thanh ghi GPIO_ODR: port output data register GPIOx_ODR

GPIOx_ODR dùng để:

  • Ghi giá trị logic ra các chân output
  • Hoặc đọc lại trạng thái đang được xuất ra (nếu cấu hình chân là output)

Khi một chân GPIO được cấu hình là output (push-pull hoặc open-drain), thanh ghi GPIOx_ODR quyết định mức logic xuất ra.

Khi chân được cấu hình là input, bit tương ứng trong ODR không điều khiển đầu ra, nhưng có tác dụng khi cấu hình input pull-up / pull-down.

Ví dụ thanh ghi ODR

GPIOA_ODR = 0b0000 0001 0000 0010

Nghĩa là:

  • PA1 = mức 1 (cao)
  • PA8 = mức 1 (cao)
  • Các chân khác = mức 0 (thấp)

Cấu hình GPIO input STM32f103RCT6

Các bước cấu hình GPIO Input cho STM32F103

  • Bật clock GPIOA
  • Bật clock GPIOC
  • Cấu hình PC1 (KEY0):
    • MODE1 = 0 (input)
    • CNF1 = 2 (pull-up)
    • ODR1 = 1 (pull-up)
      (RM0008 – Section 9.2.1, trang 171)

Code cấu hình GPIO input PC1

Hàm đảo trạng thái LED PA8

Chương trình chính (main.c)

Github link: Download code chương trình cấu hình GPIO Input STM32f103RCT6

Giải thích đọc GPIO input bằng IDR

if (!((GPIOC->IDR.reg >> 1) & 1U))

Giải thích:

  • GPIOC->IDR.reg là thanh ghi Input Data Register của port C
  • Dịch phải >> 1 để lấy bit 1 (PC1)
  • & 1U để lọc lấy 1 bit
  • Dấu ! đảo ngược logic (do input pull-up)

IDR đọc trạng thái input (RM0008 – Section 9.2.3, trang 172)

Chống dội nút nhấn (Debounce) bằng Delay

Delay_Approx(30);

Hàm tạo trễ khoảng 30ms (0.03 giây).

Mục đích:

  • Chống dội nút nhấn (debounce)
  • Tránh LED đổi trạng thái nhiều lần do nhiễu khi nhấn nút

Trong thời gian delay 30ms, dù nút còn dội hay không, chương trình không phản ứng.

Vấn đề của cách chống dội đơn giản

Chương trình chống dội trên có thể hoạt động không chính xác:

  • Nút nhấn cơ học không thay đổi tín hiệu ngay lập tức
  • Khi nhấn hoặc nhả, tín hiệu dao động trong vài ms đến vài chục ms

Nhấn nút thật:

Tín hiệu thực tế:

Hạn chế:

  • Trong 30ms delay, nếu nút vẫn bị dội → LED có thể toggle thêm
  • Nhấn nhanh hơn 30ms → bị bỏ qua
  • Không kiểm tra cạnh → giữ nút vẫn bị toggle liên tục

Bạn hãy thử tìm cách cải thiện code, để tránh trường hợp giả nhấn khi thả nút nha ?

Chương trình chống dội cải thiện (Dò cạnh + debounce)


Cải thiện

  • Dùng biến lastKeyState để phát hiện cạnh
  • Chỉ toggle khi từ 1 → 0
  • Chỉ toggle 1 lần cho mỗi lần nhấn
  • Không toggle khi giữ nút
  • Lọc nhiễu tốt cả khi nhấn và nhả

Kết luận

Qua bài viết này, bạn đã nắm được cách lập trình STM32F103 thanh ghi để cấu hình GPIO input STM32F103RCT6, đọc nút nhấn bằng GPIO_IDR và điều khiển LED thông qua GPIO_ODR/BSRR. Việc kết hợp dò cạnhchống dội giúp chương trình hoạt động ổn định, đúng thực tế hơn so với cách delay đơn giản.
Đây là nền tảng rất quan trọng khi học cấu hình GPIO input STM32F103RCT6 theo hướng bare-metal.

Bài viết tiếp theo tôi sẽ giới thiệu các phương pháp chống dội nút nhấn bằng phần mềm khác.

📘 Tham chiếu: RM0008 – Section 9.2 (trang 171–175)

Viết một bình luận

This site uses Akismet to reduce spam. Learn how your comment data is processed.