1、GPIO簡介
STM32F103ZET6有多個GPIO組,如GPIOA、GPIOB、GPIOC...等等。每個GPIO組具有16個IO口。
GPIO組的寄存器都是類似的,每個GPIO組都有2個32位的配置寄存器、2個32位的數據寄存器、1個32位的置位/復位寄存器、1個16位復位寄存器和1個32位鎖定寄存器。
STM32的很多IO口都是5V兼容的,具體哪些IO口是5V兼容的,可以從芯片的數據手冊管腳描述中查到,在手冊的IO Level中標FT的就是5V電平兼容的。
2、GPIO配置
STM32F103ZET6可以通過配置寄存器CRH和CRL將IO配置成不同的功能。IO具有以下幾種不同的模式:
-
- 輸入浮空
- 輸入下拉
- 輸入上拉
- 模擬輸入
- 開漏輸出
- 推免式輸出
- 推免式復用功能
- 開漏復用功能
CRH和CRL寄存器的每4個BIT用來配置一個IO的功能,CRL用來配置低8位IO的功能,CRH用來配置高8位IO的功能。
CNF1、CNF0、MODE1、MODE0這4個位組成了1個IO的配置位,如GPIOF0的配置位CNF1、CNF0、MODE1、MODE0這些位位於CRL寄存器中的BIT3~BIT0;GPIOF1的配置位CNF1、CNF0、MODE1、MODE0這些位位於CRL寄存器中的BIT7~BIT4;而GPIOF8的配置位CNF1、CNF0、MODE1、MODE0這些位位於CRH寄存器中的BIT3~BIT0;以此類推。CRH和CRL這兩個寄存器總共有64個BIT,總共組成了16個IO的配置位。
IO口的配置表如下:

MODE1和MODE0是用來配置IO的輸入、輸出狀態;CNF1和CNF0則是根據IO口的輸入和輸出狀態的不同配置不同的IO功能。
在配置IO的時候,首先通過MODE1和MODE0配置IO是輸入還是輸出,再通過CNF1和CNF0配置IO是什么功能的輸入或輸出。
通過CNF1、CNF0、MODE1、MODE0這些位可以將IO設置成上拉/下拉輸入,但是具體是設置成上拉輸入還是下拉輸入,並不是根據這4個位來決定的。IO口是通過ODR數據寄存器來區分到底是設置成上拉輸入還是下拉輸入。如果IO口的ODR被置為1,則IO口被設置為上拉輸入;如果IO口的ODR被清為0,則IO口被設置為下拉輸入。
CNF1、CNF0、MODE1、MODE0配置位功能如下:
MODE1和MODE0控制IO的輸入和輸出:
-
-
- [MODE1、MODE0] = 00 設置為輸入。
- [MODE1、MODE0] = 01 設置為輸出,速率為10MHZ。
- [MODE1、MODE0] = 10 設置為輸出,速率為20MHZ。
- [MODE1、MODE0] = 11 設置為輸出,速率為50MHZ。
-
CNF1、CNF0則需要根據IO是輸入還是輸出來區分:
IO設置為輸入時:
-
-
-
- [CNF1、CNF0] = 00 設置為模擬輸入。
- [CNF1、CNF0] = 01 設置為浮空輸入。
- [CNF1、CNF0] = 10 設置為上拉/下拉輸入。
- [CNF1、CNF0] = 11保留。
-
-
IO設置為輸出時:
-
-
-
- [CNF1、CNF0] = 00 設置為通用推免輸出。
- [CNF1、CNF0] = 01 設置為通用開漏輸出。
- [CNF1、CNF0] = 10 設置為復用功能推免輸出。
- [CNF1、CNF0] = 11 設置為復用功能開漏輸出。
-
-
3、GPIO的復位狀態
芯片在上電復位后,大部分IO口的模式默認為浮空輸入模式。但是有些IO比較特殊,比如PA15、PA14、PA13、PB4、PB3等IO,這些IO是JTAG和SWIO調試下載口,芯片復位后,這些IO就被默認成了JTAG和SWIO等功能,也就是說芯片復位后,PA15、PA14、PA13、PB4、PB3等IO並不能通過常規的配置設置成相應的功能。如果需要使用這些口的IO口功能,則必須將這些IO功能重新映射為GPIO口。
需要注意的是如果將PA15、PA14、PA13、PB4、PB3等口重映射為GPIO口后,則不能用調試器調試程序,而且也不能下載程序,只有通過復位芯片,使這些IO口的功能處於復位默認功能,才能下載程序。
復位后,PA15、PA14、PA13、PB4、PB3這些引腳被配置成如下模式:
-
- PA15:JTDI被置為上拉輸入模式。
- PA14:JTCK/SWCLK被置為下拉輸入模式。
- PA13:JTMS/SWDIO被置為上拉輸入模式。
- PB4:JNTRST被置為上拉輸入模式。
- PB3:JTDO
4、GPIO鎖定機制
GPIO的鎖定機制允許凍結IO口的配置。當在一個端口位上通過LCKR寄存器執行了鎖定(LOCK)程序,在下一次復位之前,將不能再更改端口位的配置。
5、外設的GPIO配置
可以在中文參考手冊的GPIO介紹章節查到外設的GPIO設置,比如說如果要使用USART_TX功能,需要將USART_TX腳位配置成什么狀態,可以在參考手冊中查到。
6、GPIO寄存器
CRH和CRL是GPIO的配置寄存器,用來配置IO的功能。
IDR是GPIO的輸入數據寄存器。通過IDR寄存器可以讀出IO的狀態。需要注意的是IDR寄存器只能以字(16位)的形式讀出。
ODR是GPIO的輸出數據寄存器。通過ODR寄存器可以輸出高低電平。
BSRR是GPIO的端口位設置/清除寄存器。BSRR寄存器的高16位是清除IO位,低16位是置位IO位。需要注意的是BSRR只有在寫入1的時候,相應的功能才有作用,寫入0是無效的。
BRR是GPIO的端口位清除寄存器。BRR基礎只有在寫入1的時候,相應的功能才有作用,寫入0無效。
LCKR是GPIO的端口配置鎖定寄存器。LCKR寄存器用來鎖定IO口的配置,設置后,除了復位后不能再配置IO的狀態。
7、HAL庫操作GPIO
以下面的程序為例說明:
void GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; __HAL_RCC_GPIOF_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOF, &GPIO_InitStruct); HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET); }
首先定義一個GPIO_InitTypeDef結構體。
在操作GPIO口之前,需要先使能GPIO的時鍾。在HAL庫中,是通過宏定義的方式使能或失能相應外設時鍾的。一般在stm32f1xx_hal_rcc_ex.h文件當中。如果不知道某個外設的時鍾是在哪個寄存器使能的,可以通過stm32f1xx_hal_rcc_ex.h查看對應的時鍾使能程序。
HAL_GPIO_Init函數是GPIO初始化函數,通過傳入的參數來配置IO的功能。
GPIO_InitStruct.Pin選擇要設置的IO腳。
GPIO_InitStruct.Mode選擇要設置的功能。
GPIO_InitStruct.Pull選擇設置上拉或下拉或無上下拉。
GPIO_InitStruct.Speed選擇設置IO口的速度。
在HAL庫中GPIO的函數被封裝在stm32f1xx_hal_gpio.c文件中,可以在該文件中查看每個函數是如何實現和使用的。
GPIO重映射使能和失能
在HAL庫中,GPIO重映射的使能和失能被封裝成了宏,可以在stm32f10xx_hal_gpio_ex.h文件當中查看。
比如調試接口重映射成GPIO口:
PA15、PA14、PA13、PB4、PB3這幾個口是調試接口腳,芯片復位的時候,將它們的功能默認為調試接口的功能,如果不重映射,它們將不能用來作為IO口功能被操作。
通過配置AFIO_MAPR寄存器的SWJ_CFG[2:0]位,可以設置PA15、PA14、PA13、PB4、PB3是調試接口還是GPIO口。
__HAL_AFIO_REMAP_SWJ_ENABLE();//將PA15、PA14、PA13、PB4、PB3全部設為調試接口
__HAL_AFIO_REMAP_SWJ_NONJTRST();//將PA15、PA14、PA13、PB3設為調試接口,而PB4為IO口
__HAL_AFIO_REMAP_SWJ_NOJTAG();//將PA15、PA14、PA13設為調試接口,而PB4、PB3為IO口
__HAL_AFIO_REMAP_SWJ_DISABLE();//將PA15、PA14、PA13、PB4、PB3全部設為IO口
8、通過STM32CubeMX配置GPIO
以使用STM32CubeMX配置GPIOF6口為例說明。
打開STM32CubeMX軟件,通過Pinout View選擇PF6腳位為GPIO_Output功能。如下圖:

在System Core下選擇GPIO,會彈出Configuration界面,在Configuration配置IO口的功能,如圖:

點擊Configuration中的PF6,會彈出PF6 Configuration,這里可以配置PF6的屬性。
點擊Project Manger,在里面設置生成的工程路徑和生成的工程類型。如下圖:

配置完之后點擊右上角的GENERATE CODE生成功能代碼。

打開生成的工程。

找到MX_GPIO_Init()函數,該函數就是實現PF6口的配置,如下:

可以通過MX配置生成的工程參考外設的配置流程。
