IO引脚复用和映射原理与配置
参考资料:
正点原子STM32开发板:
《STM32开发指南-HAL库版本》-4.4 IO引脚复用和映射
STM32F4xx官方资料:
《STM32F4xx中文参考手册》-第7章通用IO
笔记基于正点原子官方视频
视频连接https://www.bilibili.com/video/BV1Wx411d7wT?p=71&spm_id_from=333.1007.top_right_bar_window_history.content.click
如有侵权,联系删除
一、端口复用基础知识
1.什么是端口复用
- STM32有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。
- 例如串口1 的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。
- 在位置H:\3.开发板学习\阿波罗STM32F429开发板\STM32F429开发板资料-(A盘)\7,硬件资料\2,芯片资料 下文件 STM32F429IGT6 中有串口复用表,如下图:
2.STM32(M4内核以上)的端口复用映射原理
-
STM32系列微控制器IO引脚通过一个复用器连接到内置外设或模块。该复用器一次只允许一个外设的复用功能(AF)连接到对应的IO口。这样可以确保共用同一个IO引脚的外设之间不会发生冲突。
-
每个IO引脚都有一个复用器,该复用器采用16路复用功能输入(AF0到AF15),可通过GPIOx_AFRL(针对引脚0-7)和GPIOx_AFRH(针对引脚8-15)寄存器对这些输入进行配置,每四位控制一路复用。
-
端口复用映射示意图
-
AFRL复用功能低位寄存器
-
AFRH复用功能高位寄存器
可以看到AFRH和AFRL都是32位寄存器,然后16个口需要配置16个功能,即需要四位才能配置全4个功能,
AFRL位低八位,可以配置0-7号IO口的16个功能,AFRH位高八位,可以配置8-15号IO口的16个功能,
例如我们要把PA9配置AF7的功能,则需要找到配置PA9的位置区间,在AFRH的第二个区间,配置AF7功能,则需要向AFRH的第二个区间中4个位填入数据0111
3.复用功能映射配置
1)系统功能
将IO连接到AFO,然后根据所用功能进行配置:
- JTAG/SWD:在各器件复位后,会将这些引脚指定为专用引脚,可供片上调试模块立即使用(不受GPIO控制器控制)。
- RTC_REFIN:此引脚应配置为输入浮空模式。
- MCO1和MCO2:这些引脚必须配置为复用功能模式。
2)GPIO
在 GPIOx_MODER寄存器中将所需IO配置为输出或输入。
3)外设复用功能
对于ADC和 DAC,在GPIOx_MODER寄存器中将所需IO配置为模拟通道。对于其它外设: - 在GPIOx_MODER寄存器中将所需ⅣO配置为复用功能
- 通过GPIOx_OTYPER、GPIOx_PUPDR和 GPIOx_OSPEEDER寄存器,分别选择类型、上拉/下拉以及输出速度
- 在GPIOx_AFRL或GPIOx_AFRH寄存器中,将I/O连接到所需AFx
二、端口复用配置过程
在工程模板中,位置SYSTEM-usart.c位置下有串口配置程序
以PA9,PA10配置为串口1为例
①GPIO端口时钟使能。
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIO时钟
②复用外设时钟使能。
比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。
__HAL_RCC_USART1_CLK_ENABLE(); //使能串口1时钟
③端口模式配置为复用功能。 HAL_GPIO_Init函数。
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
④配置GPIOx_AFRL或者GPIOx_AFRH寄存器,将IO连接到所需的AFx。HAL_GPIO_Init函数。
GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
PA9,PA10复用为串口1的配置过程
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIOA时钟
__HAL_RCC_USART1_CLK_ENABLE(); //使能USART1时钟
GPIO_Initure.Pin=GPIO_PIN_9; //PA9
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //高速
GPIO_Initure.Alternate=GPIO_AF7_USART1; //复用为USART1
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA9
GPIO_Initure.Pin=GPIO_PIN_10; //PA10
HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化PA10