BÀI 18 – GPIO STM32F103: TỪ THANH GHI ĐẾN CHÂN GPIO THỰC TẾ
Ở Bài 17, chúng ta đã học Memory Map của STM32F103 và hiểu rằng địa chỉ như:
không phải là một con số ngẫu nhiên. Nó là địa chỉ của một vùng thanh ghi ngoại vi.
Hôm nay chúng ta nối kiến thức đó với thứ rất thực tế:
Làm thế nào CPU STM32F103 điều khiển một chân GPIO bằng cách ghi vào thanh ghi?
Đây là bài cực kỳ quan trọng. Nếu hiểu bài này, sau này bạn sẽ hiểu được cả HAL, LL và lập trình thanh ghi trực tiếp.
1. GPIO thực chất là gì?
Ví dụ bạn có Blue Pill:
- PC13 → LED onboard
- PA0 → nút nhấn
- PA1 → LED
- PB6/PB7 → I²C
- PA9/PA10 → UART
Khi bạn nói:
thì GPIOC không phải là một chân.
Nó là một ngoại vi GPIO chứa rất nhiều thanh ghi điều khiển các chân:
Mỗi GPIO port có nhiều thanh ghi.
Ví dụ GPIOC có:
2. Một chân GPIO có những trạng thái gì?
Một chân STM32 không đơn giản chỉ có:
Nó còn có chế độ hoạt động.
Ví dụ một chân có thể là:
Và nếu là output thì còn có:
Tốc độ output cũng có thể được cấu hình:
Vì vậy khi cấu hình một GPIO, chúng ta thực chất đang thiết lập nhiều bit trong các thanh ghi.
3. Thanh ghi CRL và CRH
Đây là điểm rất quan trọng với STM32F103.
STM32F103 chia 16 chân của một GPIO thành hai nhóm:
Ví dụ:
4. Mỗi chân chiếm 4 bit
Đây là một quy tắc bạn nên nhớ:
Mỗi GPIO pin của STM32F1 sử dụng 4 bit trong CRL/CRH.
Ví dụ CRL:
Mỗi pin:
tổng cộng:
5. Ví dụ PC13
PC13 thuộc nhóm:
nên nó nằm trong:
PC13 là pin số 13.
Trong CRH:
Do đó:
PC13 sử dụng bit 20 → 23 của GPIOC->CRH.
Đây chính là thứ bạn sẽ cần khi điều khiển LED PC13 bằng thanh ghi.
6. MODE là gì?
Hai bit MODE quyết định chế độ output/input.
Đối với output:
Còn:
là:
Ví dụ muốn PC13 là output 2 MHz:
7. CNF là gì?
CNF quyết định kiểu cấu hình.
Ví dụ với output:
→ General purpose output push-pull.
Đây là cấu hình rất phổ biến khi điều khiển LED.
Vì vậy:
ghép thành:
hay:
Do PC13 nằm ở bit 20:
8. Tại sao lại phải SHIFT?
Đây chính là lúc kiến thức Bài 16 – bit và toán tử << phát huy tác dụng.
Ta có:
Nhưng 0x2 đang nằm ở bit 0.
Ta cần đưa nó tới bit 20:
Kết quả nằm ở:
Tương tự CNF nằm ở:
9. Nhưng còn CNF cũ thì sao?
Đây là lỗi rất nhiều người mới học thanh ghi mắc phải.
Không nên đơn giản:
mà không xóa cấu hình cũ.
Ví dụ PC13 hiện đang có:
Ta muốn thay bằng:
Trước tiên phải xóa 4 bit cũ:
Sau đó ghi cấu hình mới:
Hai bước:
Đây chính là kỹ thuật:
Read → Modify → Write
10. Thanh ghi ODR
Sau khi cấu hình GPIO là output, chúng ta cần điều khiển mức logic.
Thanh ghi:
là:
Output Data Register
Có 16 bit:
Vì vậy:
11. Bật PC13
Muốn đưa PC13 lên HIGH:
Ý nghĩa:
dịch sang trái 13 bit:
sau đó OR với ODR.
12. Tắt PC13
Muốn đưa PC13 xuống LOW:
Ta đang:
13. Toggle PC13
Muốn đảo trạng thái:
Nếu:
thì:
Nếu:
thì:
Do đó:
có nghĩa:
Đảo trạng thái PC13.
14. Nhưng còn một vấn đề cực kỳ quan trọng
Bạn có thể viết:
nhưng trước đó GPIOC phải được cấp clock.
Nếu chưa cấp clock:
thì ngoại vi GPIOC chưa hoạt động đúng.
15. RCC xuất hiện
RCC = Reset and Clock Control.
GPIOC nằm trên:
Vì vậy phải bật clock cho GPIOC bằng:
Ví dụ:
Trên STM32F103, bit 4 là:
tức:
I/O Port C Clock Enable.
16. Bây giờ toàn bộ quá trình đã rõ
Muốn điều khiển PC13 bằng thanh ghi:
Đây là chuỗi tư duy bạn cần nhớ.
17. Ví dụ hoàn chỉnh
Nếu dùng CMSIS/register definitions phù hợp với STM32F103, ý tưởng cấu hình PC13 output push-pull 2 MHz là:
Ta hãy đọc từng dòng.
Dòng 1
→ bật clock GPIOC.
Dòng 2
→ xóa cấu hình cũ của PC13.
Dòng 3
→ cấu hình:
→ output push-pull 2 MHz.
Dòng 4
→ PC13 = HIGH.
18. Đây chính là lý do Bài 16 quan trọng
Nhìn đoạn:
bạn đang sử dụng đồng thời:
Còn:
sử dụng:
Và:
sử dụng:
Cho nên:
Bit manipulation không phải kiến thức toán học khô khan. Nó chính là ngôn ngữ để điều khiển thanh ghi của vi điều khiển.
19. Một điều rất quan trọng về PC13 trên Blue Pill
Trên Blue Pill, LED onboard thường được mắc active-low.
Điều này có nghĩa:
và:
Vì vậy nếu bạn thấy:
mà LED tắt, đó không phải lỗi.
Đó là do cách LED được mắc trên board.
20. GPIO không chỉ có ODR
STM32F103 còn có:
Trong đó BSRR cực kỳ đáng chú ý.
Ví dụ:
→ set PC13.
Còn:
→ reset PC13.
Tức là BSRR cho phép thao tác set/reset GPIO mà không cần read-modify-write ODR theo cách thông thường.
Chúng ta sẽ đào sâu phần này sau.
21. Bảng cần nhớ của GPIOF1
| Thành phần | Ý nghĩa |
|---|---|
RCC->APB2ENR |
bật clock GPIO |
GPIOx->CRL |
cấu hình pin 0–7 |
GPIOx->CRH |
cấu hình pin 8–15 |
GPIOx->IDR |
đọc input |
GPIOx->ODR |
xuất output |
GPIOx->BSRR |
set/reset GPIO |
GPIOx->BRR |
reset GPIO |
GPIOx->LCKR |
khóa cấu hình |
22. Công thức tư duy rất quan trọng
Khi gặp bất kỳ GPIO nào, hãy tự hỏi 4 câu:
Câu 1
Clock của GPIO đã bật chưa?
Ví dụ:
Câu 2
Pin này nằm ở CRL hay CRH?
Câu 3
Pin này chiếm 4 bit nào?
Ví dụ PC13:
nên:
→ bit 20–23.
Câu 4
Sau khi cấu hình, dùng thanh ghi nào để điều khiển?
Output:
Input:
23. Bài tập thực hành hôm nay
Với Blue Pill STM32F103C8T6, hãy thử tự viết chương trình:
Bài tập 1
Cấu hình:
Bài tập 2
Cho LED PC13:
lặp lại.
Bài tập 3
Không được dùng:
Mà phải dùng trực tiếp:
24. Và đây là kiến thức quan trọng nhất của Bài 18
Hãy ghi nhớ chuỗi này:
Và với PC13:
Nếu Bài 17 giúp bạn hiểu “địa chỉ thanh ghi nằm ở đâu”, thì Bài 18 giúp bạn hiểu “dùng thanh ghi đó để điều khiển phần cứng như thế nào”.
Ở Bài 19, bước tiếp theo rất tự nhiên sẽ là GPIO Input: đọc nút nhấn bằng IDR, Pull-up/Pull-down, và vì sao một chân GPIO có thể “trôi” (floating). Đây là bài sẽ giúp bạn chuyển từ “điều khiển LED” sang “đọc thế giới bên ngoài”.