與大家分享我對一下GPIO函數的理解
- 目錄
標號 | 函數名 |
---|---|
1 | void GPIO_DeInit(GPIO_TypeDef* GPIOx); |
2 | void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct); |
3 | void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct); |
4 | void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
5 | uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
6 | uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx); |
7 | uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
8 | uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx); |
9 | void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
10 | void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
11 | void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal); |
12 | void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal); |
13 | void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin); |
14 | void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF); |
1:void GPIO_DeInit(GPIO_TypeDef* GPIOx);
------------------復位IO口
-
Function used to set the GPIO configuration to the default reset state
用於將GPIO選擇的IO口組設置爲默認狀態;
函數參數GPIOx就是用於選擇具體哪一組IO口 -
程序實現過程
//例如設置GPIOA
if (GPIOx == GPIOA)
{
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, ENABLE);//復位端口
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_GPIOA, DISABLE);//不復位端口
}
通過if判斷找到復位的IO口組,通過調用RCC_AHB1PeriphResetCmd復位端口
使端口寄存器恢復默認值
2:void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
-------------------------IO初始化
- 首個參數GPIOx
選擇具體哪一個GPIOx口
例如:GPIOA 即選擇PA組IO口 - 參數GPIO_InitStruct
參數爲一個結構體,結構體內容爲
typedef struct
{
uint32_t GPIO_Pin; //指定要配置的GPIO引腳
GPIOMode_TypeDef GPIO_Mode; //指定設置IO口的模式
GPIOSpeed_TypeDef GPIO_Speed; //指定所選引腳的速度
GPIOOType_TypeDef GPIO_OType; //指定所選引腳的操作輸出類型
GPIOPuPd_TypeDef GPIO_PuPd; //指定所選引腳的操作上拉/下拉
}GPIO_InitTypeDef;
- GPIO_Pin: 即指定具體哪個IO口
- GPIO_Speed: 輸出驅動電路的帶寬, 即一個驅動電路可以不失真地通過信號的最大頻率
- GPIO_PuPd: 即設置引腳的上拉/下拉/懸空
目前的單片機往往可以內部掛載一個電阻,通常io口呈現出高阻態
上拉:就是IO串聯一個電阻到Vcc,這樣就會讓IO口電平呈現Vcc
下拉:就是IO串聯一個電阻到Gnd,這樣就會讓IO口電平呈現Gnd
懸空:即不上下拉,這樣IO口會呈現出高阻狀態,並且IO口的初始電平是不確定的
具體分析一下GPIO_Mode和GPIO_OType
設置GPIO_Mode時,是設定一個枚舉類型的值
typedef enum
{
GPIO_Mode_IN = 0x00, //輸入
GPIO_Mode_OUT = 0x01, //輸出
GPIO_Mode_AF = 0x02, //複用
GPIO_Mode_AN = 0x03 //模擬輸入
}GPIOMode_TypeDef;
- 1:輸入:檢測輸入的電平
- 2:輸出:輸出高電平或低電平
- 3:複用:調用外設時設置
STM32F4 有很多的內置外設,這些外設的外部引腳都是與 GPIO 共用的。也就是說,一個引腳可以有很多作用,但是默認爲IO口,如果想使用一個 GPIO內置外設的功能引腳,就需要GPIO的複用,那麼當這個 GPIO 作爲內置外設使用的時候,就叫做複用。 比如說串口 就是GPIO複用爲串口
- 4:模擬輸入:應用ADC模擬輸入,或者低功耗下省電
當GPIO引腳用於ADC採集電壓的輸入通道時,用作"模擬輸入"功能,此時信號不經過施密特觸發器,直接直接進入ADC模塊,並且輸入數據寄存器爲空 ,CPU不能在輸入數據寄存器上讀到引腳狀態,當GPIO用於模擬功能時,引腳的上、下拉電阻是不起作用的,這個時候即使配置了上拉或下拉模式,也不會影響到模擬信號的輸入輸出
設置GPIO_OType也是設置一個枚舉類型的值
typedef enum
{
GPIO_OType_PP = 0x00, //推輓輸出
GPIO_OType_OD = 0x01 //開漏輸出
}GPIOOType_TypeDef;
區別~!!!!
推輓輸出電路: 其中IN端輸出高電平時下面的PNP三極管截止,而上面NPN三極管導通,輸出電平VS+;當IN端輸出低電平時則恰恰相反,PNP三極管導通,輸出和地相連,爲低電平
開漏輸出電路:IN端輸出低電平時,三極管導通,使輸出接地,IN端輸出高電平時,三極管截止,所以引腳既不輸出高電平,也不輸出低電平,爲高阻態。爲正常使用時必須接上拉電阻,
總結:推輓輸出(PP)可以輸出強高低電平,連接數字器件
開漏輸出(OD)可以輸出強低電平,高電平得靠外部電阻拉高。輸出端相當於三極管的集電極. 需要外接上拉電阻,才能實現輸出高電平 合於做電流型的驅動,其吸收電流的能力相對強(一般20ma以內);在使用任何一種開漏模式時,都需要接上拉電阻,否則只能輸出低電平
推輓和開漏一般是對應輸出,上下拉一般對應着輸入
3:void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
---------------使用默認值填充所有IO口
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
{
/* Reset GPIO init structure parameters values */
GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct->GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct->GPIO_PuPd = GPIO_PuPd_NOPULL;
}
默認設置爲低速推輓無上下拉輸入模式
4:void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
--------------------鎖定GPIO管腳配置寄存器
- 當執行正確的寫序列設置了位16(LCKK)時,該寄存器用來鎖定端口位的配置。位[15:0]用於鎖定GPIO 端口的配置。在規定的寫入操作期間,不能改變LCKP[15:0]。當對相應的端口位執行了LOCK序列後,在下次系統復位之前將不能再更改端口位的配置
5:uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
------------------------讀取指定的輸入端口引腳狀態
- 參數選擇具體哪組IO口,哪個IO口
- 返回值:0或者1,
6:uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
------------------------讀取指定的GPIO組數據端口
- 參數是選擇哪一組IO口
7:uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
--------------------------讀取指定的輸出端引腳狀態
- 同讀取輸入
8:uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
---------------------------讀取指定的GPIO組端口
- 同檢測輸入
9:void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
-----------------------------設置IO口的輸出高電平
- 第一個參數設置GPIO的IO組
- 第二個參數設置具體IO口
作用:設置IO口輸出高電平
10:void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
------------------------------設置IO口的輸出低電平
- 第一個參數設置GPIO的IO組
- 第二個參數設置具體IO口
作用:設置IO口輸出低電平
11:void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
-----------------------------設置IO口的電平
- 第一個參數設置哪組GPIO
- 第二個參數設置取締哪個IO
- 第三個參數設置高電平還是低電平
作用:設置IO口的電平
WriteBit和SetBit、ResetBit的區別!!!!
WriteBit一次只能設置一個IO口,但是SetBit支持或運算可以同時設置幾個IO的電平
12:void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
----------------------------設置一組IO口的電平
- 第一個參數選擇GPIO組
- 第二個參數設置電平
作用:設置GPIO組的電平
13:void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
-------------------------------切換IO口
- 第一個參數爲哪組GPIO
- 第二個參數是哪個IO口
我也不太清楚,有會的大佬可以評論一下
14:void GPIO_PinAFConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_PinSource, uint8_t GPIO_AF);
-------------------------------設置IO口的複用功能
- 第一個參數選擇GPIO組
- 第二個參數選擇IO口
- 第三個參數選擇複用的外設功能
設置IO口的映射,通過使用此函數映射到外設
使用複用功能時,先要將GPIO初始化的複用模式打開,才能開始映射
總結就這些了,覺得還行的可以互相交流交流
謝謝!