这一章在干嘛?
跑马灯实验:GPIO 八种模式、寄存器配置、HAL_GPIO_Init 用法、LED 灯交替闪烁。本章是后续 30 个实验的「Hello World」,务必亲手跑通。
13.1 STM32F4 GPIO 简介
F407IGT6 有 140 个 IO,分 GPIOA~GPIOI 共 10 组(I 组只有 12 个)。
5V 兼容:带 FT 标志的 IO 兼容 5V,可直连 5V 外设(模拟输入模式除外)。
原书图 13.1.1:STM32 IO 端口属性缩写符号表
GPIO 八种工作模式:
| 模式 | 典型应用 |
|---|---|
| 输入浮空 | 按键检测(外部已上下拉) |
| 输入上拉 | 按键检测(无外部电阻) |
| 输入下拉 | 外接高电平有效信号 |
| 模拟 | ADC 输入 |
| 开漏输出 | I2C 总线 |
| 推挽输出 | LED、蜂鸣器、普通 IO |
| 开漏式复用 | I2C、SPI 等外设 |
| 推挽式复用 | USART、SPI 等外设 |
13.1.1 GPIO 功能模式
每种模式由 MODER(模式)、OTYPER(输出类型)、OSPEEDR(速度)、PUPDR(上下拉)、IDR(输入数据)、ODR(输出数据)、BSRR(位设置/复位)等寄存器组合实现。
13.1.2 GPIO 基本结构分析
GPIO 内部结构从引脚看进去:
- 保护二极管:限制电压在 VSS~VDD;
- 上拉/下拉电阻:30~50K,可软件开关;
- TTL 肖特基触发器:将模拟信号整形为 0/1;
- 输入数据寄存器 IDR:可读当前电平;
- 输出数据寄存器 ODR:可设置输出电平;
- 位设置/复位寄存器 BSRR:原子操作 ODR 位。
原书图 13.1.2.1:GPIO 基本结构图
BSRR 是 GPIO 的灵魂: GPIOA->BSRR = GPIO_PIN_5; 原子地把 PA5 拉高,且不影响其他 IO。
13.2 硬件设计
DMF407 LED 电路:
- LED0 → PF9,低电平点亮(灌电流接法)
- LED1 → PF10,低电平点亮
LED 串联电阻 ~ 510Ω,限流 ~ 5 mA。
13.3 程序设计
13.3.1 编程步骤
- 开启 GPIOF 时钟:
__HAL_RCC_GPIOF_CLK_ENABLE(); - 配置 GPIO:
HAL_GPIO_Init(GPIOF, &gpio_struct); - 在 while 里翻转电平。
原书图 13.3.1.1:LED 硬件原理图
13.3.2 关键代码
LED_Init:
GPIO_InitTypeDef gpio = {0};
__HAL_RCC_GPIOF_CLK_ENABLE();
gpio.Pin = GPIO_PIN_9 | GPIO_PIN_10;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOF, &gpio);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9 | GPIO_PIN_10, GPIO_PIN_SET); // 默认灭
main:
while (1) {
LED0_TOGGLE(); // HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_9);
delay_ms(500);
LED1_TOGGLE();
delay_ms(500);
}
原书图 13.3.2.1:GPIO 初始化流程图
13.4 下载验证
烧录 → 开发板 LED0/LED1 交替闪烁(500ms 周期),看不到闪烁检查:
- 接线 / 烧录是否成功;
- 延时是否生效(Watch g_fac_us);
- LED 正负极方向。
进阶实验: 改成 PWM 呼吸灯(用 TIM1_CH1 输出 PWM 接到 LED),可调亮度。
GPIO 八种模式中,I2C 应该用哪种?
开漏式复用。
原子地设置某一位 GPIO 应使用哪个寄存器?
BSRR(Bit Set Reset Register)。
LED0 接在 PF9,低电平点亮:程序里熄灭 LED0 的语句?
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_SET);。