Lập trình STM32 GPIO là một bài nhập môn cơ bản mà ai cũng phải học khi làm quen với STM32. Nó giống như các chương trình Hello World khi học ngôn ngữ mới vậy.
Trong bài này chúng ta sẽ tìm hiểu GPIO là gì, cách hoạt động và lập trình cho GPIO trên STM32
Bài 1 trong Serie Học lập trình STM32 từ A tới Z
GPIO là gì?
GPIO (General Purpose Input/Output) chính là các chân Đầu ra hoặc đầu vào dùng chung.
Tại sao lại là dùng chung?
Bởi vì mỗi chân GPIO ngoài các chức năng Input/Ouput chúng còn có thêm các chức năng khác ứng với các ngoại vi khác. Ví dụ: I2C, SPI, UART, ADC… Tất cả các chân này đều có thể sử dụng như 1 cổng I/O để đọc hoặc xuất dữ liệu theo Bit.
STM32 GPIO bao gồm nhiều Port, mỗi Port có tối đa 16 chân.
STM32 GPIO hoạt động như thế nào
STM32 GPIO được cấu tạo như sau:
STM32 GPIO bao gồm 2 khối cơ bản:
- Input Driver: Bao gồm thanh ghi Input Data (IDR), và 1 trigger. Tín hiệu Input ngoài việc được ghi vào IDR còn theo các đường Analog để vào bộ ADC, hoặc theo đường Alternate function input vào các ngoại vi khác
- Output Drive: Bao gồm thanh ghi Output Data (ODR), một khối output control để chọn tín hiệu ra là từ ODR hay từ các ngoại vi khác. Tiếp đến điều khiển 2 mosfet cho điện áp ra ở I/O pin
Chức năng của STM32 GPIO bao gồm:
Input:
- Input pull up: Đầu vào có trở kéo lên (điện áp mặc định trên chân là Vcc)
- Input pull down: Đầu vào có trở kéo xuống (điện áp mặc định trên chân là 0V)
- Input floating: Đầu vào thả nổi, điện áp không cố định dao động từ 0V tới Vcc
- Analog: Đầu vào tương tự, dùng để đo ADC
Output:
- Ouput Push Pull: Đầu ra dạng đẩy kéo, tín hiệu sẽ chỉ có Vcc hoặc 0V tương ứng với Bit 1 và 0 ghi vào chân đó
- Ouput Opendrain: Đầu ra dạng cực máng hở. Chỉ có thể kéo về 0V bằng cách ghi bit 0, khi ghi bit 1, chân IO sẽ có điện áp tương ứng với nguồn nối vào IO đó
- Alternate function Push Pull: Đầu ra kểu đẩy kéo sử dụng trong các ngoại vi
- Alternate function Open Drain: Đầu ra dạng cực máng hở, sử dụng trong các ngoại vi (thường gặp trong I2C)
Cấu hình STM32 GPIO
Sau khi đã chuẩn bị đầy đủ chúng ta bắt đầu với bài học đầu tiên khi làm quen với bất kì con chip nào đó là nháy led
Đầu tiên chúng ta mở phần mềm cubemx lên, Click vào Access to MCU selector , các bạn cũng có thể chọn Access to Board Selector nếu sử dụng các KIT của hãng.
Sau đó gõ STM32F103C8 vào ô tìm kiếm, chọn chip và nhấn Start project
Trong mục SYS các bạn chọn Serial debug, để chọn 2 chân PA13 và PA14 là chân nạp, nếu ko chọn mỗi khi cần nạp bạn phải giữ nút reset và nạp mới được.
Còn lại để mặc định
Trong RCC chọn HSE nếu chạy bằng thạch anh ngoài, ko chọn gì sẽ chạy bằng thạch anh nội
Chọn PC13 là output, mở tab GPIO sửa User Label là LED
Chọn PA0 là GPIO_Input, trong GPIO chọn Pullup, sửa label là Button
Phần Clock config, để mặc định đó là thạch anh nội 8Mhz, phần Project Manager Gõ tên project, nơi lưu trữ, chọn tool chain là MDK-ARM V5, sau đó nhấn Generate Code
Lập trình GPIO STM32 chớp tắt led
Bài đầu chúng ta bắt đầu code cho Led nhấp nháy với chu kì là 500ms
Trong phần while(1) ta viết hàm
Hàm Toggle có nhiệm vụ đảo trạng thái của Pin LED, Hal_Delay(500) sẽ cho CPU chờ mỗi 500ms và lien tục lặp đi lặp lại trong while
Lưu ý: các bạn phải viết code trong khoảng USER CODE BEGIN và USER CODE END nhé. Vì nếu bạn thay đổi trong file Cube và Gen code lại, các code ngoài khoảng này đều bị xóa hết.
Sau đó các bạn click vào Flash -> Configure flash tools-> Debug. Trong Tab Debug chọn Setting -> Flash Download Tick và Reset and Run
Bước này sẽ giúp MCU tự động Reset và chạy chương trình sau khi nạp nhé.
Để nạp chương trình các bạn cắm mạch nạp vào đúng các dây 3.3V GND SWDIO SWCLK, sau đó cắm vào máy tính nhấn nút Load hoặc F8 là oke.
Lưu ý: các bạn phải nhấn F7 hoặc biểu tượng Build để IDE Complier file nếu ko có lỗi mới nạp dc nhé
Hiện như thế này là oke
Lập trình STM32 GPIO đọc giá trị nút nhấn và ghi lên Led
Tạo một biến u8_Status lưu giá trị nút nhấn
Trong While chúng ta đọc giá trị nút nhấn bằng lênh Read và ghi lên Led bằng Lệnh Write
Build và nạp lên kit, kết nối PA0 với nút nhấn và nhấn thử
Xem video lập trình STM32 GPIO tại đây:
Kết
Vậy là xong bài đầu tiên về STM32 GPIO ở các bài tiếp theo mình sẽ hướng dẫn nhanh hơn còn các thao tác cơ bản sẽ bỏ qua, các bạn nhớ đọc kĩ bài này để các bài sau ko làm sai bước nào nhé.
mình mới học lập trình STM cho mình hỏi tại sao cần khởi tạo u8_Status để lưu giá trị nút ấn vậy
Vì bản chất hàm HAL_GPIO_ReadPin sẽ trả về 1 trong hai giá trị là GPIO_PIN_SET(nếu nút được nhấn) hoặc GPIO_PIN_RESET(nếu nút không được nhấn). u8_Status lưu giá trị này sau đó truyền xuống hàm HAL_GPIO_WritePin để bật Led tương ứng khi nhấn nút
bạn ko cần tạo biến mà ghi trực tiếp cũng đc, nó là 1 cái biến chuyển tiếp dữ liệu cho code nhìn đẹp hơn thôi.
Nếu ghi trực tiếp có thể dùng: hal_gpio_write(gpio_port_a, gpio_pin_1, hal_gpio_read(gpio_port_a, gpio_pin_2));
Bn ơi cho mình hỏi nếu muốn khi mình nhấn nút nhấn mà một hàm mình đã viết ở trên được chạy thì sẽ dùng lệnh gì nhỉ ??
Bạn gọi hàm đó trong sau phần kiểm tra nút nhấn if(button == 0)
{
function ();
}
AD giúp mình bài tập này với:
+ Viết chương trình cho 8 led được nối với port A từ A0 -> A7. Dùng 8 button ở port B từ B0, B1, B2, B7, B8, B9, B10, B11. Mỗi button điều khiển bật tắt 1 led .
+ Đếm số lần bấm : Nếu số lần bấm là chẵn thì 8 led sáng theo hiệu ứng cánh bướm. Nếu số lần bấm lẻ thì sáng dần các led từ 1 tới 8. (lưu ý delay(50ms)).
Nếu tổng số lần bấm vượt quá 15 sẽ được reset biến đếm lại 0
anh ơi em ấn go to define mà nó ghi là ‘….’ is undefined thì phải làm sao ạ
Anh ơi các hàm mình viết á, có tài liệu không anh. VD như hàm này: HAL_GPIO_ReadPin() làm sao mình biết có hàm đó để sử dụng, em có tìm mà k có, mong anh giúp cho. Thanks anh!
Em nhấn chuột phải, chọn find to define để tìm nơi lưu hàm đó nhé
anh cho em hỏi có hàm nào trong thư viện HAL mình điều khiển 1 port ko ạ
stm32 này buộc phải gọi tất cả chân ra trước rồi mới lập trình đc hay sao vậy ạ!
Tại khi gọi thêm chân ở cubemx thì code sẽ reset hết lại từ đầu.