一:前言

由于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上实测通过,可直接复制到 工程中使用,无需修改任何参数。

本博客仅记录自己的学习进程,无任何商业用途,基于论坛上已经存在的内容结合自己实操过程完成了此博客,自己也做了一些细节验证,在此记录下来作为学习沉淀。如有侵权,联系速删。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐