โญ Quick Start Guide to STM32 GPIO
Includes: Best Practices | Common Functions | Debug Output | Example Code (Compilable)
๐งฉ 1. What is GPIO – The Fundamental “Control Interface”
| Chinese | English | Brief Description |
| ้็จ่พๅ ฅ่พๅบ็ซฏๅฃ | General Purpose Input/Output (GPIO) | The most basic module for the MCU to “read from the outside” and “control the outside”. |
Each pin of the STM32 can be configured for different functions, with GPIO being the most fundamental:
- โข Light up an LED (Output)
- โข Read a button (Input)
- โข Drive a buzzer (Output)
- โข Detect sensor signals (Input)
- โข Serve as multiplexed pins for SPI/UART/IยฒC (Multiplexed Mode)
Almost all projects rely on GPIO.
๐งฑ 2. Why are ports divided into A/B/C/D… with 16 pins each?
The core reason:๐ Facilitates hardware design + Unified register structure + Increases efficiency
- โข STM32 registers are 32 bits
- โข Each pin requires 2 bits to represent its mode (MODER)
- 16 pins = 16 ร 2 bits = 32 bits, exactly one register can control one port
Therefore, each port is fixed at 16 pins:
| Port | Pins |
| GPIOA | PA0 ~ PA15 |
| GPIOB | PB0 ~ PB15 |
| GPIOC | PC0 ~ PC15 |
| โฆ | (Specific models determine availability) |
๐งฑ 3. Four Basic Attributes of GPIO That Must Be Understood
A pin in STM32 is determined by at least the following configurations:
| Attribute | English | Function |
| ๆจกๅผ | Mode | Input/Output/Multiplex/Analog |
| ่พๅบ็ฑปๅ | Output Type | Push-Pull or Open-Drain |
| ไธไธๆ | Pull-up/Pull-down | Prevents floating inputs |
| ่พๅบ้ๅบฆ | Output Speed | Speed of level switching |
Understanding these 4 switches = Fully mastering GPIO.
โ๏ธ 4. Common GPIO Code + Debug Output (Essential for Beginners)
The following code can be directly placed in <span>main.c</span> for verification.
1๏ธโฃ Output Mode: Control LED
Assuming there is an LED on <span>PC13</span> (common on minimal system boards)
CubeMX Configuration
- โข PC13 โ GPIO_Output
- โข Output Type = Push-Pull
- โข Pull = No Pull
- โข Speed = Low
Example Code
// Light up LED
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
// Note: On some boards, PC13 is lit when low
// Turn off LED
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
// Toggle LED
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
Add Debug Output (Recommended)
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
printf("LED toggled. Current state: %d\r\n",
HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13));
Output Example
LED toggled. Current state: 0
LED toggled. Current state: 1
๐ Strongly recommended:Print every action for easier debugging of peripheral issues.
2๏ธโฃ Input Mode: Read Button
Assuming the button is connected to PB12, pressed to ground, requiring internal pull-up.
CubeMX Configuration
- โข PB12 โ GPIO_Input
- โข Pull = Pull-up
Example Code
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET)
{
printf("Button Pressed!\r\n");
}
Output Example
Button Pressed!
3๏ธโฃ Open-Drain Output – Common in IยฒC Bus
Open-drain can only output:
- โข Low level (0)
- โข High-Z (floating)
External resistors are responsible for pulling the level high.
CubeMX Configuration (I2C SDA/SCL)
- โข GPIO Output Type: Open-drain
- โข Pull-up: External Pull-up (commonly 4.7k)
Manual Open-Drain Output Example
// Output low level
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_RESET);
// Release the bus (allow external pull-up resistor to pull high)
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
4๏ธโฃ Multiplexed Function AF: UART / SPI / TIM / PWM
For example USART1:
| Pin | AF Function |
| PA9 | AF7 (USART1_TX) |
| PA10 | AF7 (USART1_RX) |
CubeMX will generate this automatically.
๐ 5. Best Practices for GPIO (Engineer-Level Summary)
๐ฆ 1. Always add pull-up/down for inputs (to prevent floating noise)
Do not use Floating Input! Otherwise:
- โข Signal jitter
- โข CPU interrupts triggered incorrectly
- โข Program anomalies
Experience Summary:
| Scenario | Recommendation |
| Button | Pull-up |
| Sensor Output | Follow sensor manual recommendations |
| Signal Source with Open Circuit Possibility | Pull-up or Pull-down |
๐ฆ 2. Prefer Push-Pull for Outputs
Unless you are very sure you need open-drain.
Push-Pull is suitable for:
- โข LED lights
- โข Driving small loads
- โข Digital signals
- โข PWM outputs
Open-Drain is used for:
- โข I2C
- โข Multi-device shared lines
- โข Scenarios requiring external pull-up
๐ฆ 3. Use BSRR instead of ODR (Faster and Safer)
Not recommended:
GPIOC->ODR ^= (1 << 13);
Recommended:
GPIOC->BSRR = (1 << 13); // Set
GPIOC->BSRR = (1 << (13 + 16)); // Reset
Advantages of BSRR:
- โข Atomic operation, will not be interrupted and cause errors
- โข Faster speed
HAL’s <span>WritePin()</span> uses BSRR.
๐ฆ 4. Adding Debug Output (printf) is the Fastest Way for Beginners to Improve
Recommendation:
printf("Pin PB12 = %d\r\n", HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12));
Don’t be afraid of too many prints! If you can see it, you can understand it; if you can understand it, you can control it.
๐ฆ 5. Don’t set GPIO speed (OSPEEDR) too high
Low speed is sufficient (unless for high-speed PWM/SPI) Otherwise:
- โข Increased EMI
- โข Increased power consumption
- โข Sharp signal edges can cause interference in the circuit
๐ง 6. Comprehensive Demo – Button Controls LED (with Print)
#include "main.h"
#include <stdio.h>
void SystemClock_Config(void);
void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
printf("GPIO Demo Start!\r\n");
while (1)
{
if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_12) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
printf("Button Pressed โ LED ON\r\n");
}
else
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
printf("Button Released โ LED OFF\r\n");
}
HAL_Delay(100);
}
}
Output Example
GPIO Demo Start!
Button Released โ LED OFF
Button Released โ LED OFF
Button Pressed โ LED ON
Button Pressed โ LED ON
Button Released โ LED OFF
๐งญ 7. Diagram of GPIO Working Model (Very Important)
โโโโโโโโโโโโโโโโ MCU ๅ
้จ โโโโโโโโโโโโโโโ
โ GPIO PORT โ
โ โโโโโโโโโโโโฌโโโโโโโโโโโฌโโโโโโโโโโโโโ โ
โ โ MODER โ OTYPER โ PUPDR โ โ ็กฌไปถ้
็ฝฎๅฏๅญๅจ
โ โโโโโโโโโโโโดโโโโโโโโโโโดโโโโโโโโโโโโโ โ
โ โ โ
โ โผ โ
โ ๅผ่ๆงๅถ้ป่พ โ
โโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโ
โผ
๏ผๅค้จๅผ่ PAx/PBx๏ผ
๐ Summary: The Core of GPIO in One Sentence
Input looks at IDR, output writes BSRR, configuration relies on MODER/OTYPER/PUPDR/OSPEEDR. Prefer push-pull, use pull resistors to prevent floating, print more, observe more.