STM32:吃透引脚、引脚复用与引脚重映射
一:前言
由于STM32很多引脚支持“复用”和“重映射”功能,能将外设的功能从默认引脚“搬到”其他空闲引脚,完美解决引脚冲突问题。
二:引脚 引脚复用 引脚重映射 三者概念及其关系
1.物理GPIO引脚(基础)
这是芯片最基础的硬件引脚,比如PB6、PB7、PA9等,默认情况下,它们都是“普通GPIO引脚”,可以用来控制LED、读取按键、驱动继电器等基础IO操作。
2. 引脚复用
有部分物理引脚,都不止有“普通IO”这一个功能,还能被“复用”为其他外设的专用引脚,这就是引脚复用。
例如:USART1的默认复用引脚是PA9(TX)、PA10(RX)。当我不需要PA9/PA10作为普通IO,而是需要用USART1通信时,就可以将PA9/PA10配置为“复用模式”,此时这两个引脚就不再是普通IO,而是USART1的收发引脚,实现串口通信功能。
核心理解:复用是STM32引脚的“固有能力”,一个引脚对应一个默认的外设复用功能,无需额外配置“映射”,只要将GPIO模式设为复用模式,就能启用该功能。
3. 引脚重映射(Remap)
本质上是“复用功能的搬家”,将一个外设的默认复用引脚,转移到其他空闲的物理引脚,不改变外设本身的功能,只改变其对应的硬件引脚。
还是以USART1为例:它的默认复用引脚是PA9/PA10,若此时我开启“重映射”,就可以将USART1的复用功能,从PA9/PA10转移到PB6/PB7引脚。
重映射后,PB6就相当于原来的PA9(USART1_TX),PB7就相当于原来的PA10(USART1_RX),代码中USART1的驱动逻辑完全不用改,只需要修改GPIO配置和重映射相关代码,就能实现串口通信。
三者关系
物理引脚 → 引脚复用(启用外设功能) → 引脚重映射(外设功能换引脚);
复用是“启用外设功能”,重映射是“给外设功能换个引脚”,重映射依赖于复用,没有复用就没有重映射。
三:代码
使用的芯片是STM32F103,标准库开发,需要实现USART1重映射到PB6(TX)、PB7(RX),用于和ESP8266通信,波特率9600,开启接收中断。
重点:重映射需要用到AFIO模块(复用功能IO模块),所以必须开启AFIO时钟,因为只有先开启复用才可以将复用功能重映射到其它引脚。
void Usart1_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);
}
代码分析:
(1)时钟配置:首先开启USART1、GPIOB、AFIO三个外设的时钟,符合重映射的核心要求——重映射由AFIO模块负责,必须开启其时钟,否则重映射功能无法生效;同时开启USART1和对应GPIO组(GPIOB)的时钟,为后续外设和引脚配置奠定基础,时钟开启顺序不影响功能。
(2)重映射配置:调用GPIO_PinRemapConfig函数,参数为GPIO_Remap_USART1且使能,符合STM32F103 USART1全重映射的配置要求(USART1仅支持全重映射,无部分重映射),能正确将USART1的收发功能从默认PA9/PA10转移到PB6/PB7。
(3)GPIO配置:PB6配置为GPIO_Mode_AF_PP(复用推挽输出),对应USART1_TX(发送端),输出模式匹配发送功能;PB7配置为GPIO_Mode_IPU(上拉输入),对应USART1_RX(接收端),上拉输入可有效抑制干扰,避免接收数据异常,引脚模式、引脚编号与重映射要求完全匹配。
补充学习
NVIC分组是全局配置,整个工程只能调用一次,必须放在main函数最开头,所有外设初始化之前。
四:主要重点
重映射是由AFIO模块负责的,重映射必须开启AFIO时钟,否则AFIO模块无法工作,重映射配置无效。
USART1的全重映射参数是GPIO_Remap_USART1,部分重映射只适用于USART2等其他外设,查手册确认参数后再配置。
五:写在后面
本文所有代码均在STM32F103C8T6上实测通过,可直接复制到 工程中使用,无需修改任何参数。
本博客仅记录自己的学习进程,无任何商业用途,基于论坛上已经存在的内容结合自己实操过程完成了此博客,自己也做了一些细节验证,在此记录下来作为学习沉淀。如有侵权,联系速删。
更多推荐



所有评论(0)