stm32端口复用和重映射

端口复用和重映射都是和单片机的I/O口有关系,端口复用是将一个I/O赋予多个功能,通过设置I/O的工作模式来切换不同的功能。重映射是将某些I/O口上面的功能映射到其他I/O口上面去。但是注意一点:重映射的I/O都是厂家设置好的,不能自己更改。

端口复用

外设

在说端口复用之前先明白一个概念:什么是外设?什么是内置外设?

外部设备简称“外设”,是指连在计算机主机以外的硬件设备。对数据和信息起着传输、转送和存储的作用,是计算机系统中的重要组成部分。
—百度百科

内置外设就是集成在单片机内部的外设,存在对应的寄存器。可参考:单片机里内部外设和外设分别是什么

端口复用

STM32有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。

例如串口1的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。

端口复用设置步骤

  1. GPIO时钟使能;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
  2. 复用外设时钟使能
    比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
  3. 端口模式配置。 GPIO_Init()函数。

具体说下第3步 端口模式配置,在使用I/O时,首先要进行初始化,

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

第一个参数是哪组I/O口,第二组I/O是一个结构体指针

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

主要看一下 GPIO_Mode 这个参数的取值

typedef enum
{ GPIO_Mode_AIN = 0x0,      //模拟输入
  GPIO_Mode_IN_FLOATING = 0x04,//浮空输入
  GPIO_Mode_IPD = 0x28,//下拉输入 
  GPIO_Mode_IPU = 0x48,//上拉输入
  GPIO_Mode_Out_OD = 0x14,//开漏输出
  GPIO_Mode_Out_PP = 0x10,//推挽输出
  GPIO_Mode_AF_OD = 0x1C,//复用开漏输出
  GPIO_Mode_AF_PP = 0x18//复用推挽输出
}GPIOMode_TypeDef;

这里写图片描述
在数据手册中可以看到 PA9和PA10可以复用为串口(Default),
这里写图片描述
从上两张图中可以看出,复用为串口发送需要将 PA9设置为 推挽复用输出,

代码示例:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//GPIO时钟使能

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//外设时钟(串口)使能

//初始化IO为对应的模式
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9//复用推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;  //PA10 PA.10 浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);  

总结

GPIO复用功能就是同样的几个I/O口可以通过设置I/O模式,使能相应时钟, 从而实现不同的功能。具体的设置可以参考 stm32中文参考手册和相应芯片的 dataSheet。

重映射

每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在STM32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。

重映射技术的需求背景:

  • I/O的复用:GPIO和内置外设共用引出管脚
  • I/O的重映射:复用功能(AFIO)从不同的GPIO管脚引出
  • 方便了PCB的设计,减少了信号交叉干扰
  • 分时复用某些外设,虚拟地增加了端口数目
  • 为了使不同器件封装的外设IO功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。

还是以串口1为例
这里写图片描述
上图中的,Remap对应的I/O就是可以重映射到的I/O,Default就是该I/O默认可复用的功能。
从上图中可以看出 串口1 可以重映射到 PB6和PB7引脚,也就是说如果PA9和PA10引脚不好用的时候,或者已经被占用了;那么可以用PB6和PB7来实现串口1的功能。

AFIO重映射的操作步骤:

  1. 使能倍重新映射到的I/O端口时钟
  2. 使能被重新映射的外设时钟
  3. 使能AFIO功能的时钟(勿忘)
  4. 进行重映射

注意第三步,使能AFIO功能时钟,为什么需要使能这个时钟 & 什么时候需要使能这个时钟, 可以参见下面这个回答

那么,问题来了!
  AFIO 是什么?AFIO 时钟什么时候需要开启?
  
  我们从《STM32中文参考手册_V10》中找到:对寄存器 AFIO_EVCR、AFIO_MAPR 和 AFIO_EXTICRX 进行读写操作前,应当首先打开 AFIO 的时钟(设置 APB2 外设时钟使能寄存器 RCC_APB2ENR)。
  也就是说:当你需要配置 AFIO 这些寄存器的时候,就需要把 RCC_APB2ENR 寄存器的 AFIO 位置‘1’打开 AFIO 时钟。
  
  跟 AFIO 相关的寄存器有:
  1、 事件控制寄存器(AFIO_EVCR)
  2、 复用重映射和调试I/O 配置寄存器(AFIO_MAPR)
  3、 外部中断配置寄存器1(AFIO_EXTICR1)
  4、 外部中断配置寄存器2(AFIO_EXTICR2)
  5、 外部中断配置寄存器3(AFIO_EXTICR3)
  6、 外部中断配置寄存器4(AFIO_EXTICR4)
  看看这些寄存器的定义,我们就明白,这些寄存器是用于“事件控制”、“重映射”、“调试IO配置”、“外部中断”的。例如 AFIO_EXTICRX 用于选择 EXTIx 外部中断的输入源。
  总结:当我们需要配置这些 AFIO 寄存器的时候,就需要打开 RCC_APB2ENR 寄存器的 AFIO 时钟,而不是用到引脚复用功能的时候打开。
  ——-来自于: STM32的AFIO时钟什么时候需要开启

部分重映射 & 完全重映射

  • 部分重映射:功能外设的部分引脚重新映射,还有一部分引脚是原来的默认引脚。
  • 完全重映射:功能外设的所有引脚都重新映射。
    这里写图片描述
    如何配置部分重映射 & 完全重映射在后面

引脚重映射配置过程(串口3为例):
1. 使能GPIO时钟(重映射后的IO);
2. 使能功能外设时钟(例如串口3);
3. 使能AFIO时钟。重映射必须使能AFIO时钟:
4. 开启重映射。

  GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);
  //根据第一个参数,来确定是部分重映射还是全部重映射

这里写图片描述
查看第一个参数的取值,如下图:
这里写图片描述
以串口3为例,如果想部分映射:GPIO_PinRemapConfig()的第一个参数取值应该是:上图红框框里面的第一个参数,即 GPIO_PartialRemap_USART3,如果是完全映射就是:GPIO_FullRemap_USART3

总结

重映射就是将在某个I/O实现的功能映射到另外的I/O口, 主要是为了布线的方便以及信号的干扰。具体配置步骤与部分重映射 & 完全重映射前面都已说明。

参考资料

正点原子视频
STM32中GPIO的8种工作模式
STM32的AFIO时钟什么时候需要开启
单片机里内部外设和外设分别是什么

猜你喜欢

转载自blog.csdn.net/williamgavin/article/details/79776654
今日推荐