02-GPIO输出.md 3.9 KB

02 GPIO 输出 —— 点灯(HAL)

目标:控制 PC13(板载 LED)以 500ms 间隔闪烁

IO 端口内部结构

                      VDD
                       │
                 ┌─────┤
                 │P-MOS│    P-MOS 导通 = 引脚输出高电平
                 │     │
    输出数据 ←──┐┴──  │
                 │     │
                 │N-MOS│    N-MOS 导通 = 引脚输出低电平
                 │     │
                 └─┬───┤
                   │    │
                   └────┘
                      │
                    GND

在推挽输出 (Push-Pull) 模式下,P-MOS 和 N-MOS 交替导通:

  • 写 1 → P-MOS 导通 → 引脚接 VDD (3.3V)
  • 写 0 → N-MOS 导通 → 引脚接 GND (0V)

在开漏输出 (Open-Drain) 模式下,P-MOS 被断开:

  • 写 1 → 高阻态(引脚既不高也不低,需要外部上拉电阻拉到 VDD)
  • 写 0 → N-MOS 导通 → 引脚接 GND

板载 LED 通常接 PC13,低电平点亮:GPIO_PIN_RESET(0) = 亮, GPIO_PIN_SET(1) = 灭

GPIO 8 种工作模式速查

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 的复用模式

CubeMX 配置

  • Pinout → 选中 PC13 → 设为 GPIO_Output
  • 参数设置:
    • GPIO output level:Low(初始状态熄灭,改为 High 就是初始点亮)
    • GPIO mode:Output Push-Pull
    • Pull-up/Pull-down:No pull(或 Pull-up)
    • Maximum output speed:Low(LED 用低速即可)

关键 HAL API

函数 说明
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 输出速度的选择

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。

常见坑点

  • ⚠️ 先查原理图确认 LED 极性:低电平点亮(RESET=亮)还是高电平点亮(SET=亮)?
  • ⚠️ HAL_Init() 必须在 HAL_Delay() 之前调用,否则 SysTick 未初始化,延时无效
  • ⚠️ GPIO 时钟在 MX_GPIO_Init() 中自动开启 (__HAL_RCC_GPIOC_CLK_ENABLE()),不需要手动加
  • ⚠️ 复用功能(如 USART 的 TX 引脚)必须选 AF_PPAF_OD,不能是普通 Output