目标:控制 PC13(板载 LED)以 500ms 间隔闪烁
VDD
│
┌─────┤
│P-MOS│ P-MOS 导通 = 引脚输出高电平
│ │
输出数据 ←──┐┴── │
│ │
│N-MOS│ N-MOS 导通 = 引脚输出低电平
│ │
└─┬───┤
│ │
└────┘
│
GND
在推挽输出 (Push-Pull) 模式下,P-MOS 和 N-MOS 交替导通:
在开漏输出 (Open-Drain) 模式下,P-MOS 被断开:
板载 LED 通常接 PC13,低电平点亮:
GPIO_PIN_RESET(0) = 亮,GPIO_PIN_SET(1) = 灭
STM32 的 GPIO 有 8 种模式,分为 4 种输入 + 2 种输出 + 2 种复用:
| 模式 | 宏定义 | 用途 |
|---|---|---|
| 模拟输入 | GPIO_MODE_ANALOG |
ADC 输入 |
| 浮空输入 | GPIO_MODE_IN_FLOATING |
外部有上下拉时用 |
| 上拉输入 | GPIO_MODE_IPU |
按键(松开高电平) |
| 下拉输入 | GPIO_MODE_IPD |
按键(松开低电平) |
| 推挽输出 | GPIO_MODE_OUTPUT_PP |
普通 LED、普通 IO |
| 开漏输出 | GPIO_MODE_OUTPUT_OD |
I2C SDA/SCL |
| 复用推挽 | GPIO_MODE_AF_PP |
USART TX、SPI SCK/MOSI |
| 复用开漏 | GPIO_MODE_AF_OD |
I2C 的复用模式 |
| 函数 | 说明 |
|---|---|
HAL_GPIO_WritePin(GPIOx, GPIO_PIN_x, PinState) |
设置引脚为高/低电平 |
HAL_GPIO_TogglePin(GPIOx, GPIO_PIN_x) |
翻转引脚电平 |
HAL_Delay(uint32_t Delay) |
毫秒级阻塞延时(依赖 SysTick 中断) |
PinState:
GPIO_PIN_SET = 高电平 (1)GPIO_PIN_RESET = 低电平 (0)int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 点亮
HAL_Delay(500);
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); // 熄灭
HAL_Delay(500);
}
}
或用 Toggle 简化:
while (1)
{
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
HAL_Delay(500);
}
GPIO 有 3 档输出速度,需要正确匹配应用场景:
| 速度档位 | 上升/下降时间 | 适用场景 | 理由 |
|---|---|---|---|
| Low (2MHz) | ~125ns | LED、按键、普通 GPIO | 最慢 = EMI 最小,省电 |
| Medium (10MHz) | ~25ns | 几 MHz 以下的 SPI/I2C | 中等频率够用 |
| High (50MHz) | ~5ns | 高速 SPI、SDIO、FSMC | 速度优先,EMI 较大 |
输出速度指 IO 驱动电路的响应速度,不是信号频率上限。选过高速度会增加功耗和 EMI 辐射。能用 Low 就选 Low。
HAL_Init() 必须在 HAL_Delay() 之前调用,否则 SysTick 未初始化,延时无效MX_GPIO_Init() 中自动开启 (__HAL_RCC_GPIOC_CLK_ENABLE()),不需要手动加