【stm32f407】IO引腳複用和對映
一.什麼叫管腳複用
STM32F4有很多的內建外設,這些外設的外部引腳都是與GPIO複用的。也就是說,一個GPIO如果可以複用為內建外設的功能引腳,那麼當這個GPIO作為內建外設使用的時候,就叫做複用。
STM32F4系列微控制器IO引腳通過一個複用器連線到內建外設或模組。該複用器一次只允許一個外設的複用功能(AF)連線到對應的IO口。這樣可以確保共用同一個IO引腳的外設之間不會發生衝突。每個IO引腳都有一個複用器,該複用器採用16路複用功能輸入(AF0到AF15),可通過GPIOx_AFRL(針對引腳0-7)和GPIOx_AFRH(針對引腳8-15)暫存器對這些輸入進行配置,每四位控制一路複用:
1)完成復位後,所有IO都會連線到系統的複用功能0(AF0)。
2)外設的複用功能對映到AF1到AF13。
3)Cortex-M4EVENTOUT對映到AF15。
如圖:
上圖是針對引腳0-7,對 於引腳8-15,控制暫存器為GPIOx_AFRH。從圖中可以看出。當需要使用複用功能的時候,我們配置相應的暫存器GPIOx_AFRL或者GPIOx_AFRH,讓對應引腳通過複用器連線到對應的複用功能外設。這裡我們列出GPIOx_AFRL暫存器的描述,
GPIOx_AFRH的作用跟GPIOx_AFRL類似,只不過GPIOx_AFRH控制的是一組IO口的高八位,GPIOx_AFRL控制的是一組
暫存器分別如下:
二.USART例項講解
以usart2的TX,RX為例
USART2的TX,RX對應的PIN腳分別為:PD5,PD6
1) 首先,我們要使用IO複用功能外設,必須先開啟對應的IO時鐘和複用功能外設時鐘。
/*使能GPIOD時鐘*/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE);
USART2在APB1總線上
/*使能USART2時鐘*/
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
這裡需要說明一下,官方庫提供了五個開啟GPIO和外設時鐘的函式分別為:
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph,FunctionalState NewState);
void RCC_AHB2PeriphClockCmd(uint32_tRCC_AHB2Periph, FunctionalState NewState);
void RCC_AHB3PeriphClockCmd(uint32_tRCC_AHB3Periph, FunctionalState NewState);
void RCC_APB1PeriphClockCmd(uint32_tRCC_APB1Periph, FunctionalState NewState);
void RCC_APB2PeriphClockCmd(uint32_tRCC_APB2Periph, FunctionalState NewState);
這五個函式分別用來開啟相應的匯流排下GPIO和外設時鐘。比如我們的串列埠2是掛載在APB1匯流排之下,所以我們呼叫對應的APB1匯流排下外設時鐘使能函式RCC_APB1PeriphClockCmd來使能串列埠2時鐘。對於其他外設我們呼叫相應的函式即可。
2) 其次,我們在GIPOx_MODER暫存器中將所需IO(對於串列埠2是PD5,PD6)配置為複用功能(ADC和DAC設定為模擬通道)。
3)再次,我們還需要對IO口的其他引數,例如型別,上拉/下拉以及輸出速度。
上面兩步,在我們庫函式中是通過GPIO_Init函式來實現的,參考程式碼如下:
/*GPIOD5與GPIOD6初始化*/
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_5 | GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode= GPIO_Mode_AF;//複用功能
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;//速度50MHz
GPIO_InitStructure.GPIO_OType= GPIO_OType_PP; //推輓複用輸出
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOD,&GPIO_InitStructure);//初始化PD5,PD6
4)最後,我們配置GPIOx_AFRL或者GPIOx_AFRH暫存器,將IO連線到所需的AFx。這些步驟對於我們使用庫函式來操作的話,是呼叫的
GPIO_PinAFConfig函式來實現的。具體操作程式碼如下:
/*PD5連線AF7,複用為USART2_TX */
GPIO_PinAFConfig(GPIOD,GPIO_PinSource5,GPIO_AF_USART2);
/* PD6連線AF7,複用為USART2_RX*/
GPIO_PinAFConfig(GPIOD,GPIO_PinSource6,GPIO_AF_USART2);
對於函式GPIO_PinAFConfig函式,入口第一個第二個引數很好理解,可以確定是哪個IO,
對於第三個引數,實際上我們確定了這個IO到底是複用為哪種功能之後,這個引數也很好選擇,因為可選的引數在stm32f4xx_gpio.h列出來非常詳細,如下