STM32 复用功能(AF)配置的常见误区
问题
USART 配好了、SPI 也配好了,代码调了HAL_UART_Transmit但引脚没波形,示波器量是 0V 或 3.3V 不动。
大概率:GPIO 没有配置成对应的复用功能(AF)。
什么是复用功能
STM32 的每个 GPIO 引脚可以干很多事:
PA9 可以是: - 普通 GPIO 输出 - 普通 GPIO 输入 - USART1_TX(复用 AF7) - TIM1_CH2(复用 AF1) - SPI2_SCK(复用 AF5)
想让引脚做 USART 的 TX,需要在 GPIO 寄存器中选择对应的复用号。
典型错误
错误一:配成了普通输出
// ❌ CubeMX 里 PA9 选 GPIO_Output // 然后代码里 HAL_UART_Transmit... // 引脚只能手动高低,UART 外设控制不了它
错误二:复用号选错了
CubeMX 自动配对的,不会错。但如果你手写寄存器:
// ❌ 想配 USART1_TX(AF7),却写成了 AF1(TIM) GPIOA->AFR[1] |= (0x01 << 4); // AFRH 的 bit 4~7 = 0001 → AF1 // 实际上应该写 0111(AF7) // ✅ 正确做法——先清零再赋值: GPIOA->AFR[1] &= ~(0x0F << 4); // 先清零目标字段 GPIOA->AFR[1] |= (0x07 << 4); // 再写入 AF7
CubeMX 里的操作
选中 PA9 → 选USART1_TX(不是 GPIO_Output)→ CubeMX 自动配好 AF。
验证:在 Pinout 视图里,PA9 旁边会显示USART1_TX字样,引脚颜色也会变成复用功能的绿色。
常用复用功能速查
| 外设 | 引脚 | AF 号 | AF 名称 |
|---|---|---|---|
| USART1_TX | PA9 | AF7 | AF7_USART1 |
| USART1_RX | PA10 | AF7 | AF7_USART1 |
| SPI1_SCK | PA5 | AF5 | AF5_SPI1 |
| SPI1_MOSI | PA7 | AF5 | AF5_SPI1 |
| I2C1_SCL | PB6 | AF4 | AF4_I2C1 |
| I2C1_SDA | PB7 | AF4 | AF4_I2C1 |
| TIM2_CH1 | PA0 | AF1 | AF1_TIM2 |
| TIM3_CH3 | PB0 | AF2 | AF2_TIM3 |
每个引脚的可用 AF 怎么看:
方法一:CubeMX 点中引脚,弹出的菜单只显示可用的功能。
方法二:查 STM32F407 的 datasheet(不是参考手册)→ Pinouts 章节 → 那几张巨大的引脚功能表。
代码层面验证
初始化后检查寄存器:
// 检查 PA9 的 MODER uint32_t moder = (GPIOA->MODER >> (9 * 2)) & 0x03; printf("PA9 MODER = %lu (2=Alternate)\r\n", moder); // 检查 PA9 的 AFRH uint32_t afr = (GPIOA->AFR[1] >> ((9 - 8) * 4)) & 0x0F; printf("PA9 AF = %lu (7=USART1)\r\n", afr);如果 MODER 不是 2(Alternate Function)或者 AF 不是 7,引脚就起不到 USART1_TX 的作用。
总结
| 一句话 |
|---|
| GPIO 要做外设功能,必须配成Alternate Function + 正确的 AF 编号 |
| CubeMX 会自动配好,不要手动改成 GPIO_Output/Input |
| 如果怀疑引脚功能不对,读 MODER 和 AFR 寄存器确认 |
