| 层级 | 方式 | 示例 | 难度 | 适合人群 |
|---|---|---|---|---|
| 高级 | HAL 库(CubeMX 默认) | HAL_GPIO_WritePin() | ⭐ | 新手入门 |
| 中级 | LL 库(Low Layer) | LL_GPIO_SetOutputPin() | ⭐⭐ | 进阶者 |
| 底层 | 直接寄存器 | `GPIOA->ODR | = (1 << 5);` | ⭐⭐⭐ |
| 名称 | 含义 |
|---|---|
GPIOA | 代表 GPIOA 端口 |
ODR | Output Data Register,输出数据寄存器 |
1 << 5 | 把第 5 位(PA5)置 1 |
| ` | =` |
HAL_Init();
SystemClock_Config(); // 已由 CubeMX 自动生成 72MHz 配置
MX_GPIO_Init();
while (1)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 设置高电平
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 设置低电平
HAL_Delay(500);
}
GPIO 初始化MX_GPIO_Init()
系统时钟SystemClock_Config()
CubeMX 中配置外部时钟 + GPIO 步骤

| 项目 | 当前设置值 | 含义 & 作用 |
|---|---|---|
| GPIO output level | High | 初始化时的默认输出电平,上电时默认输出高电平(VDD) |
| GPIO mode | Output Push Pull | 输出推挽模式(标准输出)✅ |
| GPIO Pull-up/Pull-down | Pull-up | 内部上拉电阻使引脚在悬空时为高电平(对输出口其实不起作用) |
| Maximum output speed | Medium | GPIO 切换速度为中等(10 MHz 左右) |
| User Label | LED | 给这个引脚设置标签(可读性提升) |
官方定义说明(STM32 HAL 中):
#define GPIO_PIN_0 ((uint16_t)0x0001) // 1 << 0
#define GPIO_PIN_1 ((uint16_t)0x0002) // 1 << 1
...
#define GPIO_PIN_15 ((uint16_t)0x8000) // 1 << 15
注意这些宏是 uint16_t 类型,所以最多只能表达 16 位(即 PIN_0~15)。
GPIOA->ODR |= (1 << pin) 置高,或 GPIOA->ODR &= ~(1 << pin) 置低
| 31 … 16 | 15 … 0 |
| 复位位 Reset Bits | 设置位 Set Bits |
低 16 位(0~15 bit):将对应引脚 置高电平(写 1 有效)
高 16 位(16~31 bit):将对应引脚 置低电平(写 1 有效)
| 操作 | 写入值 | 说明 |
|---|---|---|
| 设置 PA5 为高电平 | GPIOA->BSRR = (1<<5) | 低 16 位 Bit5 写 1 |
| 设置 PA5 为低电平 | GPIOA->BSRR = (1<<21) | 高 16 位 Bit5 写 1(5+16) |
GPIOx->BSRR = GPIO_PIN_0; // 置 GPIOx 的第 0 引脚为高电平
GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
ODR 修改需要 读 → 改 → 写,中断过程中可能打断写入操作。
BSRR 写入是 一次完成、原子操作,不会影响其他引脚,适合高实时场景(如中断、RTOS)
while (1)
{
GPIOA->BSRR = (1 << 5); // PA5 = 高
HAL_Delay(500); // 延时 500ms
GPIOA->BSRR = (1 << (5 + 16)); // PA5 = 低
HAL_Delay(500); // 延时 500ms
}
for i in range(16):
led_high = 1 << i
led_low = 1 << (i + 16)
print(f"GPIO_PIN_{i:>2}: SET=0x{led_high:08X} RESET=0x{led_low:08X}")
Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
| 宏定义名 | 说明 |
| ----------------------------- | ----------------- |
| `GPIO_MODE_INPUT` | 输入模式(默认悬浮) |
| `GPIO_MODE_OUTPUT_PP` | 推挽输出(能主动拉高+拉低) |
| `GPIO_MODE_OUTPUT_OD` | 开漏输出(只能拉低) |
| `GPIO_MODE_AF_PP` | 推挽复用功能(如 UART TX) |
| `GPIO_MODE_AF_OD` | 开漏复用功能(如 I2C) |
| `GPIO_MODE_ANALOG` | 模拟模式(ADC) |
| `GPIO_MODE_IT_RISING` | 上升沿中断输入 |
| `GPIO_MODE_IT_FALLING` | 下降沿中断输入 |
| `GPIO_MODE_IT_RISING_FALLING` | 双边沿中断输入 |
MX_GPIO_Init() 函数
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOA_CLK_ENABLE(); // 1️⃣ 使能 GPIOA 时钟
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; // 2️⃣ 推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 3️⃣ 初始化 PA5
开漏模式:LED 长脚(正极)连 GPIO 短脚(负极)连电阻 → GND
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出模式
GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉电阻启用
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


| 选项 | 含义 | 用于哪些功能 | 是否必须 |
|---|---|---|---|
| HSE (High Speed Clock) | 高速外部时钟,通常为外接 8MHz 晶振 | 主系统时钟(SYSCLK)、串口、USB、定时器等依赖准确时钟 | ✅ 推荐开启(你的板子通常带 8MHz 晶振) |
| LSE (Low Speed Clock) | 低速外部时钟,常为 32.768KHz 晶体 | 用于 RTC 实时时钟、低功耗定时、日历功能等 | ❌ 通常不需要(除非你用到 RTC) |
进阶:stm32 + 光敏电阻模块 + 有源蜂鸣器模块
光敏电阻模块Pin
| 引脚名 | 功能 |
|---|---|
| A0 | 模拟输出(可选) |
| GND | 地线 |
| D0 | 数字输出(高/低电平) |
| VCC | 电源(一般 3.3V 或 5V) |
有源蜂鸣器模块
| 蜂鸣器引脚 | 说明 | 连接到 STM32 小板 |
|---|---|---|
| VCC | 电源(3.3V或5V) | 3.3V 或 5V(建议先用 5V) |
| GND | 地 | GND |
| I/O | 控制引脚(低电平触发) | 比如 PA0(GPIO输出) |
有源蜂鸣器模块接线(低电平触发型)
| 蜂鸣器模块引脚 | 说明 | 接 STM32 小板 |
|---|---|---|
| VCC | 电源 | 5V(或 3.3V) |
| GND | 地 | GND |
| I/O | 控制输入 | PA0(输出) |
光敏电阻模块接线(数字输出 D0)
| 光敏模块引脚 | 说明 | 接 STM32 小板 |
|---|---|---|
| VCC | 电源(建议 5V) | 5V |
| GND | 地 | GND |
| D0 | 数字信号输出(高/低) | PA1(输入) |
| A0 | 模拟输出(可忽略) | 不接或接 ADC |
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
// 如果检测到低电平,说明环境变暗
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1) == GPIO_PIN_RESET)
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // 蜂鸣器响
}
else
{
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // 蜂鸣器关闭
}
HAL_Delay(100); // 稍作延时
}
}
继电器吸合:
#define RELAY_ON() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET) // 低电平吸合
#define RELAY_OFF() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET) // 高电平断开
RELAY_ON(); // 吸合
HAL_Delay(1000);
RELAY_OFF(); // 断开
HAL_Delay(1000);

Comments | NOTHING