| 层级 |
方式 |
示例 |
难度 |
适合人群 |
| 高级 |
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 步骤
![image]()
| 项目 |
当前设置值 |
含义 & 作用 |
| 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(); //使能 GPIOA 时钟
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; //推挽输出模式
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //初始化 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);
![image]()
时钟选项
| 选项 |
含义 |
用于哪些功能 |
是否必须 |
| HSE (High Speed Clock) |
高速外部时钟,通常为外接 8MHz 晶振 |
主系统时钟(SYSCLK)、串口、USB、定时器等较精准时钟 |
✅ 推荐开启(大部分板子通常带 8MHz 晶振) |
| LSE (Low Speed Clock) |
低速外部时钟,常为 32.768KHz 晶体 |
用于 RTC 实时时钟、低功耗定时、日历功能等 |
❌ 通常不需要(除非你用到 RTC) |
光敏电阻模块引脚
| 引脚名 |
功能 |
| 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(输出) |
光敏电阻模块接线(数字输出 DO)
| 光敏模块引脚 |
说明 |
接 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);