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 29 – GPIO STM32F103: BRR – THANH GHI RESET VÀ MỐI QUAN HỆ VỚI BSRR

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

BÀI 29 – GPIO STM32F103: BRR – THANH GHI RESET VÀ MỐI QUAN HỆ VỚI BSRR

Ở Bài 28, chúng ta đã học:

GPIOx->BSRR

và biết rằng:

BSRR bit 0..15  → SET GPIO
BSRR bit 16..31 → RESET GPIO

Hôm nay chúng ta học thêm:

GPIOx->BRR

Đây là thanh ghi chuyên dùng để RESET GPIO về LOW.


1. BRR là gì?

BRR viết tắt của:

Bit Reset Register

Trong STM32F103, mỗi GPIO có thanh ghi:

GPIOA->BRR
GPIOB->BRR
GPIOC->BRR
...

Nó dùng để đưa các chân GPIO Output xuống:

LOW

2. Cách hoạt động của BRR

BRR có 16 bit điều khiển tương ứng với 16 chân GPIO:

BRR

bit 15 ................. bit 0
 |                         |
 PC15 ...                  PA0

Nếu:

GPIOA->BRR = (1 << 5);

thì:

PA5 = LOW

Nếu:

GPIOA->BRR = (1 << 0);

thì:

PA0 = LOW

3. So sánh BSRR và BRR

Đây là phần quan trọng nhất của bài.

Thanh ghi Tác dụng
ODR Đọc/ghi trạng thái Output
BSRR SET hoặc RESET GPIO
BRR RESET GPIO

Ví dụ với PA5:

SET PA5

GPIOA->BSRR = (1 << 5);

→ PA5 HIGH.

RESET PA5 bằng BSRR

GPIOA->BSRR = (1 << 21);

→ PA5 LOW.

RESET PA5 bằng BRR

GPIOA->BRR = (1 << 5);

→ PA5 LOW.

Ba thao tác trên cho kết quả tương ứng:

BSRR bit 5
     ↓
PA5 HIGH


BSRR bit 21
     ↓
PA5 LOW


BRR bit 5
     ↓
PA5 LOW

4. Vậy tại sao cần BRR nếu BSRR đã RESET được?

Câu hỏi rất hay.

Bạn có thể hỏi:

“Nếu BSRR đã có phần RESET ở bit 16–31, tại sao STM32F103 còn cần BRR?”

Về chức năng:

BSRR RESET

và:

BRR

đều có thể đưa GPIO xuống LOW.

Ví dụ:

GPIOA->BSRR = (1 << (5 + 16));

và:

GPIOA->BRR = (1 << 5);

đều làm:

PA5 = LOW

Nhưng cách biểu diễn khác nhau.


5. BRR dễ hiểu hơn khi chỉ RESET

Nếu muốn RESET PA5:

Với BSRR:

GPIOA->BSRR = (1 << (5 + 16));

Bạn phải nhớ:

RESET = pin + 16

Với BRR:

GPIOA->BRR = (1 << 5);

Rất trực tiếp:

bit 5
 ↓
RESET PA5

Vì vậy BRR rất dễ đọc khi bạn chỉ cần RESET GPIO.


6. Ví dụ với PC13 trên Blue Pill

Giả sử PC13 đang được cấu hình Output.

Muốn:

PC13 = LOW

ta có thể dùng:

Cách 1

GPIOC->BRR = (1 << 13);

Cách 2

GPIOC->BSRR = (1 << (13 + 16));

Hai cách đều:

PC13 = LOW

7. Nhưng nhớ LED Blue Pill là Active LOW

Đây là phần chúng ta đã nói ở bài trước.

Thông thường:

PC13 LOW  → LED sáng
PC13 HIGH → LED tắt

Vì vậy:

GPIOC->BRR = (1 << 13);

không có nghĩa là:

LED OFF

mà trong trường hợp LED onboard Blue Pill thường là:

PC13 LOW
     ↓
LED ON

Đây là ví dụ rất tốt để phân biệt:

GPIO state

với:

Device state

8. BRR cũng có thể RESET nhiều chân

Ví dụ:

PA0
PA1
PA2

đều muốn LOW.

Ta viết:

GPIOA->BRR =
    (1 << 0) |
    (1 << 1) |
    (1 << 2);

Hoặc:

GPIOA->BRR = 0x0007;

Kết quả:

PA0 = LOW
PA1 = LOW
PA2 = LOW

9. So sánh với BSRR

Với BSRR:

GPIOA->BSRR =
    (1 << 16) |
    (1 << 17) |
    (1 << 18);

Với BRR:

GPIOA->BRR =
    (1 << 0) |
    (1 << 1) |
    (1 << 2);

Cả hai đều:

PA0 = LOW
PA1 = LOW
PA2 = LOW

Nhưng BRR ngắn gọn hơn.


10. Một điểm rất quan trọng: BRR chỉ RESET

BRR không dùng để SET GPIO.

Ví dụ:

GPIOA->BRR = (1 << 5);

→ PA5 LOW.

Không có:

GPIOA->BRR = ...

nào để đưa PA5 HIGH.

Muốn HIGH, dùng:

GPIOA->BSRR = (1 << 5);

Vì vậy:

             GPIO
              │
       ┌──────┴──────┐
       ↓             ↓
     SET           RESET
       │             │
     BSRR           BSRR
   bit 0..15     bit 16..31
                     │
                     hoặc
                     ↓
                    BRR

11. Viết hàm GPIO bằng BRR

Ở Bài 28, chúng ta đã viết:

void GPIO_Set(GPIO_TypeDef *GPIOx, uint8_t pin)
{
    GPIOx->BSRR = (1 << pin);
}

Và:

void GPIO_Reset(GPIO_TypeDef *GPIOx, uint8_t pin)
{
    GPIOx->BSRR = (1 << (pin + 16));
}

Bây giờ có thể viết GPIO_Reset() bằng BRR:

void GPIO_Reset(GPIO_TypeDef *GPIOx, uint8_t pin)
{
    GPIOx->BRR = (1 << pin);
}

Dễ đọc hơn rất nhiều.


12. Vậy nên dùng BRR hay BSRR?

Đây là câu hỏi thực tế.

Nếu chỉ RESET:

GPIOx->BRR = (1 << pin);

rất rõ ràng.

Nếu muốn sử dụng một thanh ghi duy nhất để điều khiển cả:

SET
RESET

thì:

GPIOx->BSRR

rất tiện.

Ví dụ:

GPIOx->BSRR = (1 << pin);          // SET
GPIOx->BSRR = (1 << (pin + 16));   // RESET

13. Tại sao BSRR rất được ưa chuộng?

Hãy tưởng tượng bạn muốn:

PA0 HIGH
PA1 LOW

Với BSRR:

GPIOA->BSRR =
    (1 << 0) |
    (1 << (1 + 16));

Có thể thực hiện cả hai thao tác thông qua một lần ghi BSRR.

Đây là một đặc điểm rất hữu ích khi điều khiển nhiều GPIO.


14. ODR thì sao?

Ta có thể làm:

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

để SET PA0.

Và:

GPIOA->ODR &= ~(1 << 1);

để RESET PA1.

Nhưng đây là dạng:

READ
 ↓
MODIFY
 ↓
WRITE

Trong khi BSRR:

GPIOA->BSRR = ...

là ghi trực tiếp lệnh SET/RESET.

Đây chính là lý do BSRR rất quan trọng trong lập trình firmware.


15. Một ví dụ cực kỳ thực tế

Giả sử:

PA0 → LED đỏ
PA1 → LED xanh

Muốn:

PA0 HIGH
PA1 LOW

ta có thể viết:

GPIOA->BSRR =
    (1 << 0) |
    (1 << (1 + 16));

Nhưng nếu dùng BRR:

GPIOA->BSRR = (1 << 0);
GPIOA->BRR  = (1 << 1);

Hai cách đều có thể tạo ra trạng thái cuối:

PA0 = HIGH
PA1 = LOW

Tuy nhiên cách BSRR đầu tiên có ưu điểm là hai thay đổi được yêu cầu trong cùng một lần ghi thanh ghi.


16. Một khái niệm mới: Atomic GPIO

Đến đây bạn nên hiểu rõ hơn từ atomic mà chúng ta bắt đầu nói ở Bài 28.

Giả sử:

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

CPU phải:

Đọc ODR
   ↓
Thay đổi bit
   ↓
Ghi ODR

Trong khi:

GPIOA->BSRR = (1 << 0);

chỉ cần:

Ghi BSRR
   ↓
Phần cứng SET PA0

Điều này làm thao tác GPIO phù hợp hơn với các chương trình có:

Interrupt
Timer
DMA
RTOS

17. Một lưu ý về STM32F103

Khi học STM32, bạn sẽ gặp nhiều dòng STM32 khác nhau.

Không nên mặc định:

“Tất cả STM32 đều có thanh ghi giống hệt nhau.”

Ví dụ STM32F1 có cách tổ chức GPIO đặc trưng:

CRL
CRH
IDR
ODR
BSRR
BRR
LCKR

Trong các dòng STM32 mới hơn, cấu trúc GPIO có thể khác.

Đây là lý do khi lập trình thanh ghi, bạn phải luôn đọc Reference Manual của đúng MCU.

Với Blue Pill STM32F103C8T6, chúng ta đang học đúng cấu trúc GPIO của STM32F1.


18. Bây giờ hãy nhìn toàn bộ GPIO

Sau Bài 29, bạn đã biết:

GPIOA
 │
 ├── CRL  → cấu hình PA0...PA7
 │
 ├── CRH  → cấu hình PA8...PA15
 │
 ├── IDR  → đọc trạng thái chân
 │
 ├── ODR  → trạng thái Output
 │
 ├── BSRR → SET + RESET
 │
 ├── BRR  → RESET
 │
 └── LCKR → khóa cấu hình GPIO

Đây chính là bộ khung quan trọng của GPIO STM32F103.


19. Bài tập Bài 29

Bài tập 1

Viết:

void GPIO_Reset(GPIO_TypeDef *GPIOx, uint8_t pin)

bằng BRR.


Bài tập 2

Cho:

#define LED_PIN 13

Viết lệnh làm:

PC13 LOW

bằng:

BRR

Bài tập 3

Viết lệnh làm:

PA0 = HIGH
PA1 = LOW
PA2 = HIGH

bằng một lần ghi BSRR.

Gợi ý:

SET PA0
SET PA2
RESET PA1

Bạn sẽ cần:

GPIOA->BSRR = ?

20. Kiến thức cần thuộc sau Bài 29

Bạn nên thuộc bảng này:

Mục đích Lệnh
SET PA5 GPIOA->BSRR = (1 << 5);
RESET PA5 bằng BSRR GPIOA->BSRR = (1 << 21);
RESET PA5 bằng BRR GPIOA->BRR = (1 << 5);
Đọc PA5 GPIOA->IDR & (1 << 5)
Đọc trạng thái Output GPIOA->ODR & (1 << 5)

Đặc biệt nhớ:

BSRR:
0..15  = SET
16..31 = RESET

BRR:
0..15  = RESET

🎯 Bước tiếp theo – Bài 30

Đến Bài 30, chúng ta nên ghép tất cả những gì đã học:

BÀI 30 – TỰ VIẾT GPIO DRIVER CHO STM32F103: GPIO_Init(), GPIO_Set(), GPIO_Reset(), GPIO_Toggle() BẰNG THANH GHI, KHÔNG DÙNG HAL

Đây sẽ là bài rất quan trọng, vì từ đây bạn bắt đầu chuyển từ “học từng thanh ghi” sang “tự xây dựng thư viện GPIO của riêng mình”.

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