GPIO——General Purpose Input Output——通用輸入輸出出口
特點:通用性、快速翻轉、中斷支援、支援多種工作模式。
8種輸入輸出模式
模式 | 性質 | 特徵 | 應用 | 標識 |
浮空輸入 |
數字輸入 |
可讀取引腳電平,若引腳懸空,則電平不確定 |
適用於需要讀取外部訊號的場景,但外部訊號狀態不確定。 |
GPIO_Mode_IN_FLOATING |
上拉輸入 |
數字輸入 |
可讀取引腳電平,內部連線上拉電阻,懸空時預設高電平 |
用於外部訊號預設為高電平的情況,如按鈕按下時會拉低訊號。 |
GPIO_Mode_IPU |
下拉輸入 |
數字輸入 |
可讀取引腳電平,內部連線下拉電阻,懸空時預設低電平 |
適用於外部訊號預設為低電平的情況,如按鈕按下時會拉高訊號。 |
GPIO_Mode_IPD |
模擬輸入 |
模擬輸入 |
GPIO無效,引腳直接接入內部ADC |
適用於需要進行模擬訊號處理的場景。 |
GPIO_Mode_AIN |
開漏輸出 | 數字輸出 |
可輸出引腳電平,高電平為高阻態,低電平接VSS |
適用於需要多個輸出埠共享同一訊號線的場景,例如I2C的SDA、SCL線。 |
GPIO_Mode_Out_OD |
推輓輸出 | 數字輸出 |
可輸出引腳電平,高電平接VDD,低電平接VSS |
適用於需要輸出到外部裝置,需要較大驅動能力的場景。 |
GPIO_Mode_Out_PP |
複用開漏輸出 | 數字輸出 |
由片上外設控制,高電平為高阻態,低電平接VSS |
適用於需要實現外設功能,同時共享訊號線的場景,例如硬體I2C的SDA、SCL線 |
GPIO_Mode_AF_OD |
複用推輓輸出 | 數字輸出 | 由片上外設控制,高電平接VDD,低電平接VSS | 適用於需要實現外設功能,同時需要提供較大驅動能力的場景,例如SPI的SCK、MISO、MOSI線。 | GPIO_Mode_AF_PP |
引腳電平:0V~3.3V,部分引腳可容忍5V
GPIO的庫函式位置
函式 | 解釋 |
void GPIO_DeInit(GPIO_TypeDef* GPIOx) | gpio的反初始化函式,該函式的作用是把GPIO相關的暫存器配置成上電覆位後的預設狀態,在第一次初始化前或者不在使用某一介面後,可以呼叫該函式。 |
void GPIO_AFIODeInit(void) | 外設對映設定恢復為預設狀態,以重新初始化外設對映配置。 |
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) | GPIO的初始化函式,該函式的作用是對io進行初始化。 |
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct) | GPIO結構體的初始化。對GPIO_InitStruct結構體進行預設配置。 |
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 讀取io輸入管腳的值 |
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx) | 讀取輸入io資料,該函式用於讀取一個io分組的所有資料 |
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 讀取io輸出管腳的值 |
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx) | 讀取輸出io資料,該函式用於讀取一個io分組的所有資料 |
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 對io管腳進行置位(輸出高電平) |
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 對io管腳進行復位(輸出低電平) |
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal) | 對某一位進行寫入操作。 |
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal) | 對GPIO埠進行寫入操作,適用於對統一埠的多個管腳的寫入。 |
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) | 鎖定GPIO暫存器,鎖定的暫存器是GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR, GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH。在下一次復位前,被鎖定的管腳不能被修改。 |
void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) | 配置GPIO引腳作為事件輸出,用於特定的事件通知機制。 |
void GPIO_EventOutputCmd(FunctionalState NewState) |
啟用或禁用GPIO事件輸出功能。 |
void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState) | 重新對映指定引腳,以實現不同的引腳功能。(重對映和IO口的複用一樣,需要開啟AFIO的時鐘。) |
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource) | 配置外部中斷線的GPIO埠和引腳。 |
void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface) | 配置乙太網介質介面。 |
通用外設驅動模型:
初始化→讀函式→寫函式→設定中斷
初始化(常用):
void __GPIO_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); //RCC_APB2Periph_GPIOB-》這裡選擇的是STM上的B0和B10,所以是GPIOB ENABLE-》使能 GPIO_InitTypeDef GPIO_InitStructure; //定義結構體 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //輸入模式 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10;//埠 可同時定義多個 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //選擇速率 GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化 }
STM32按鍵控制開關燈例項:
LED燈的配置
#include "stm32f10x.h" void LED_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIOA口的PA0、PA2、PA5埠,設定推輓輸出 GPIO_SetBits(GPIOA,GPIO_Pin_0 | GPIO_Pin_2 | GPIO_Pin_5); //PA0、PA2、PA5埠輸出高電平 } void LED1_ON(void){ GPIO_ResetBits(GPIOA,GPIO_Pin_0); } void LED1_OFF(void){ GPIO_SetBits(GPIOA,GPIO_Pin_0); } void LED2_ON(void){ GPIO_ResetBits(GPIOA,GPIO_Pin_2); } void LED2_OFF(void){ GPIO_SetBits(GPIOA,GPIO_Pin_2); } void LED3_ON(void){ GPIO_ResetBits(GPIOA,GPIO_Pin_5); } void LED3_OFF(void){ GPIO_SetBits(GPIOA,GPIO_Pin_5); } //3個LED開關燈操作,低電平點亮,高電平熄滅 void LED1_Turn(void){ if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0){ GPIO_SetBits(GPIOA,GPIO_Pin_0); }else{ GPIO_ResetBits(GPIOA,GPIO_Pin_0); } } //讀取PA0埠的LED狀態,進行翻轉操作 void LED2_Turn(void){ if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0){ GPIO_SetBits(GPIOA,GPIO_Pin_2); }else{ GPIO_ResetBits(GPIOA,GPIO_Pin_2); } } //讀取PA2埠的LED狀態,進行翻轉操作 void LED3_Turn(void){ if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_5) == 0){ GPIO_SetBits(GPIOA,GPIO_Pin_5); }else{ GPIO_ResetBits(GPIOA,GPIO_Pin_5); } } //讀取PA5埠的LED狀態,進行翻轉操作
開關的配置
#include "stm32f10x.h" // Device header #include "Delay.h" void Key_Init(void){ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStructure); //初始化PB0和PB10埠,分別連線了兩個開關,使用上拉輸入模式 } uint8_t Key_GetNum(void){ uint8_t KeyNum = 0; if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0){ //讀取PB0埠資料判斷是否為0(低電平) Delay_ms(20); //延時過濾 while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_0)==0); //當為0時跳出迴圈 Delay_ms(20); //延時過濾 KeyNum = 1; //標誌位置1 } if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0){ Delay_ms(20); while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)==0); Delay_ms(20); KeyNum = 2; } return KeyNum; //返回標誌位 }
主函式
#include "stm32f10x.h" #include "Delay.h" #include "LED.h" #include "Key.h" uint8_t KeyNum; int main(void) { LED_Init(); //燈初始化 Key_Init(); //開關初始化 while(1){ KeyNum = Key_GetNum(); //獲取標誌位 if(KeyNum == 1){ LED1_Turn(); } if(KeyNum == 2){ LED2_Turn(); LED3_Turn(); } //標誌位為1時,翻轉LED1,為2時翻轉LED2和LED3 } }