STM32-IO引腳復用-原理和使用


1.什么是端口復用?

STM32有很多的內置外設(把一些功能ADC\看門狗…集中到芯片里面),這些外設的外部引腳都是與GPIO復用的。也就是說,一個GPIO如果可以復用為內置外設的功能引腳,那么當這個GPIO作為內置外設使用的時候,就叫做復用。

例如串口1 的發送接收引腳是PA9,PA10,當我們把PA9,PA10不用作GPIO,而用做復用功能串口1的發送接收引腳的時候,叫端口復用。

2.STM32引腳可以復用為哪些功能?

可在芯片STM32767IGT6資料中的pin and ball definitions中找到:

在這里插入圖片描述

STM32(M4內核以上)的端口復用映射原理

STM32系列微控制器IO引腳通過一個復用器連接到內置外設或模塊。該復用器一次只允許一個外設的復用功能(AF)連接到對應的IO口。這樣可以確保共用同一個IO引腳的外設之間不會發生沖突。

每個IO引腳都有一個復用器,該復用器采用16路復用功能輸入(AF0到AF15),可通過GPIOx_AFRL(針對引腳0-7)和GPIOx_AFRH(針對引腳8-15)寄存器對這些輸入進行配置,每四位控制一路復用。

在這里插入圖片描述

對於每一組GPIO都有GPIO 復用功能低位寄存器 (GPIOx_AFRL) (x = A…K):比如GPIOA有16個IO口,GPIOx_AFRL是32位,可以配置引腳0-7。

GPIOx_AFRL寄存器:

在這里插入圖片描述

GPIO 復用功能高位寄存器 (GPIOx_AFRH) (x = A…J):

在這里插入圖片描述

在這里插入圖片描述

比如配置PA9連接到AF7,那么就是配置GPIOA_AFRH的AFR9,配置成0111 。

3.復用功能配置:

1.系統功能:將I/O連接到AF0,然后根據所用功能進行配置:

  • JTAG/SWD:在各器件復位之后,會將這些引腳指定為專用引腳,可供片上調試模塊立即使用 (不受GPIO控制器控制)
  • RTC_REFIN:此引腳應配置為輸入浮空模式。
  • MCO1和MCO2:這些引腳必須配置為復用功能模式。

2.GPIO:在GPIOx_MODER寄存器中將所需I/O配置為輸出或輸入。

3.外設復用功能:

對於ADC和DAC,在GPIOx_MODER寄存器中將所需I/O配置為模擬通道。對於其它外設:

  • 在GPIOx_MODER寄存器中將所需I/O配置為復用功能
  • 通過GPIOx_OTYPER、GPIOx_PUPDR和GPIOx_OSPEEDER寄存器,分別選擇類型、上拉/下拉以及輸出速度。
  • 在GPIOx_AFRL或GPIOx_AFRH寄存器中,將I/O連接到所需AFx

4.端口復用功能配置過程

以PA9、PA10配置為串口1為例:

1.GPIO端口時鍾使能。
__HAL_RCC_GPIOA_CLK_ENABLE(); //使能GPIO時鍾

2.復用外設時鍾使能。
比如你要將端口PA9,PA10復用為串口,所以要使能串口時鍾。
__HAL_RCC_USART1_CLK_ENABLE(); //使能串口1時鍾

3.端口模式配置為復用功能。 HAL_GPIO_Init函數。
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //復用推挽輸出

4.配置GPIOx_AFRL或者GPIOx_AFRH寄存器,將IO連接到所需的AFx。HAL_GPIO_Init函數。

GPIO_Initure.Alternate=GPIO_AF7_USART1;//復用為USART1

在文件system-usart.c中可以找到:HAL_UART_MspInit

void HAL_UART_MspInit(UART_HandleTypeDef *huart) { //GPIO端口設置 GPIO_InitTypeDef GPIO_Initure; if(huart->Instance==USART1)//如果是串口1,進行串口1 MSP初始化 { __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 #if EN_USART1_RX HAL_NVIC_EnableIRQ(USART1_IRQn); //使能USART1中斷通道 HAL_NVIC_SetPriority(USART1_IRQn,3,3); //搶占優先級3,子優先級3 #endif } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM