STM32 GPIO輸入輸出(基於HAL庫)

1、基礎認識

GPIO全名爲General Purpose Input Output,即通用輸入輸出。有時候簡稱爲「IO口」。通用,說明它是常見的。輸入輸出,就是說既能當輸入口使用,又能當輸出口使用。端口,就是元器件上的一個引腳。編程

輸入模式和輸出模式是GPIO的基本特性,固然GPIO還有其它模式可選。函數

(一) IO耐壓問題

STM32是一款3.3V電壓的芯片,IO輸出是3.3V,但IO大部分都是能夠容忍5V電壓輸入。通常在芯片手冊的「引腳定義」章節能夠查看到有FT標識表示該IO能夠容忍5V電壓輸入。測試

2、在標準庫中GPIO的模式

(一)模式彙總

輸入模式:ui

l  浮空輸入(GPIO_Mode_IN_FLOATING):引腳電平是真實的外部鏈接器件電壓,電平有不肯定性spa

l  上拉輸入 (GPIO_Mode_IPU):默認經過電阻上拉到VCC,不接外部器件時能夠讀出高電平.net

l  下拉輸入 (GPIO_Mode_IPD):默認經過電阻下拉到GND,不接外部器件時能夠讀出低電平3d

l  模擬輸入 (GPIO_Mode_AIN):將外部信號直接傳輸到數模轉換通道上code

輸出模式:orm

l  開漏輸出(GPIO_Mode_Out_OD):只能輸出低電平,高電平由電阻上拉決定blog

l  開漏複用功能(GPIO_Mode_AF_OD):用於外設功能使用

l  推輓式輸出(GPIO_Mode_Out_PP):能夠輸出強高和強低,一般使用該功能控制LED

l  推輓式複用功能(GPIO_Mode_AF_PP):用於外設功能使用

GPIO的基本結構:

TTL肖特基觸發器其實能夠理解爲用肖特基管構成的施密特觸發器,做用簡單說就是將相對緩慢變化的模擬信號變成矩形(方波)信號,便於後面讀取。這裏有一個閾值電壓的概念,好比從低到高達到多少纔會導通,從高到底多少纔會關閉。

(二)   浮空輸入(GPIO_Mode_IN_FLOATING)

浮空就是邏輯器件與引腳即不接高電平,也不接低電平。因爲邏輯器件的內部結構和外部引腳所接的器件決定電平狀態。通常實際運用時,引腳不建議懸空,易受干擾。通俗講就是浮空就是浮在空中,就至關於此端口在默認狀況下什麼都不接,呈高阻態,這種設置在數據傳輸時用的比較多。浮空最大的特色就是電壓的不肯定性,它多是0V,頁多是VCC,還多是介於二者之間的某個值(最有可能) 浮空通常用來作ADC輸入用,這樣能夠減小上下拉電阻對結果的影響。

(三)  上拉輸入 (GPIO_Mode_IPU)

上拉就是把點位拉高,好比拉到Vcc。上拉就是將不肯定的信號經過一個電阻嵌位在高電平。電阻同時起到限流的做用。弱強只是上拉電阻的阻值不一樣,沒有什麼嚴格區分。

電阻一般爲30-50KΩ

(四) 下拉輸入 (GPIO_Mode_IPD)

下拉就是把點位拉低,好比拉到GND。下拉就是將不肯定的信號經過一個電阻嵌位在低電平。電阻同時起到限流的做用。弱強只是下拉電阻的阻值不一樣,沒有什麼嚴格區分

(五) 模擬輸入 (GPIO_Mode_AIN)

模擬輸入是指傳統方式的輸入,數字輸入是輸入PCM數字信號,即0,1的二進制數字信號,經過數模轉換,轉換成模擬信號,經前級放大進入功率放大器,功率放大器仍是模擬的

(六)  開漏輸出(GPIO_Mode_Out_OD)

IO輸出0接GND,IO輸出1,懸空,須要外接上拉電阻,才能實現輸出高電平。當輸出爲1時,IO口的狀態由上拉電阻拉高電平,但因爲是開漏輸出模式,這樣IO口也就能夠由外部電路改變爲低電平或不變。能夠讀IO輸入電平變化,實現C51的IO雙向功能。

只能輸出強低電平。

(七)開漏複用功能(GPIO_Mode_AF_OD)

用於外設使用

(八)推輓式輸出(GPIO_Mode_Out_PP)

IO輸出0-接GND, IO輸出1 -接VCC。這是使用最多的了。控制LED基本都是使用這種模式。

能夠輸出強高低電平,鏈接外部數字器件

(九)推輓式複用功能(GPIO_Mode_AF_PP)

用於外設使用

3、配置輸入輸出IO

(一)輸入

(1).   GPIO Pull-up/Pull-down:

IO上下拉配置

l  No pull-up and no pull-down,浮空輸入,配置爲不上拉和下拉

l  Pull-up,上拉輸入

l  Pull-down,下拉輸入

(二)輸出

(1).   GPIO output level

l  Low:IO初始化默認輸出低電平

l  High:IO初始化默認輸出高電平

(2).   GPIO mode

l  Output Open Drain,開漏輸出,能夠輸出低電平

l  Output Push Pull,推輓輸出,能夠輸出低電平和高電平 

(3).   GPIO Pull-up/Pull-down:

IO上下拉配置

l  No pull-up and no pull-down,浮空輸入,配置爲不上拉和下拉

l  Pull-up,上拉輸入

l  Pull-down,下拉輸入

(4).   Maximum output speed

l  Low,GPIO速度爲低速,一般爲2MHZ

l  Medium,GPIO速度爲中速,一般爲10MHZ

l  High,GPIO速度爲高速,一般爲50MHZ

4、 輸出編程

測試有GPIOA1和GPIOA2設置爲輸出測試

(一)CubeMx設置

 

 

 

(二) 初始化函數

宏定義

#define DONG_OUT_1_Pin GPIO_PIN_1
#define DONG_OUT_1_GPIO_Port GPIOA
#define DONG_OUT_2_Pin GPIO_PIN_2
#define DONG_OUT_2_GPIO_Port GPIOA

初始化函數是自動生成的

void MX_GPIO_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};

  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIOA時鐘

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//設置上電電平爲低

  /*Configure GPIO pins : PAPin PAPin */
  GPIO_InitStruct.Pin = DONG_OUT_1_Pin|DONG_OUT_2_Pin;//兩個GPIO_PIN
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;//推輓輸出模式
  GPIO_InitStruct.Pull = GPIO_NOPULL;//浮空,不上拉也不下拉
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;//低速
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

}

(三)輸出相關函數

設置或清除選定的數據端口位

void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)

參數:

GPIOx :其中x能夠(A..G取決於所使用的設備)來選擇GPIO外設

GPIO_Pin :指定要寫入的端口位。此參數能夠是GPIO_PIN_x之一,其中x能夠是( 0..15 )

PinState :指定要寫入選定位的值。此參數能夠是GPIO_PinState枚舉值之一:

l  GPIO_PIN_RESET:清除端口Pin,低電平

l  GPIO_PIN_SET:設置端口Pin,高電平

例子:

HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//兩個設置爲低電平
HAL_Delay(1000);//1s
HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin, GPIO_PIN_SET);//單獨設置爲高電平
HAL_GPIO_WritePin(GPIOA,DONG_OUT_2_Pin, GPIO_PIN_SET);//單獨設置爲高電平
HAL_Delay(1000);//1s

切換指定的GPIO pin

void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

參數:

GPIOx :其中x能夠(A..G取決於所使用的設備)來選擇GPIO外設

GPIO_Pin :指定要寫入的端口位。此參數能夠是GPIO_PIN_x之一,其中x能夠是(0..15 )

例子:

HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin);//兩個輸出電平取反
HAL_Delay(1000);//1s
HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//單獨輸出電平取反
HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//單獨輸出電平取反
HAL_Delay(1000);//1s

5、輸入編程(輪詢檢測)

(一)CubeMX設置

 (二)初始化函數

宏定義

#define DONG_IN_1_Pin GPIO_PIN_3
#define DONG_IN_1_GPIO_Port GPIOA

初始化部分

GPIO_InitTypeDef GPIO_InitStruct = {0};//初始化結構體
__HAL_RCC_GPIOA_CLK_ENABLE();//GPIO時鐘開啓
GPIO_InitStruct.Pin = DONG_IN_1_Pin;//引腳
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;//輸入模式
GPIO_InitStruct.Pull = GPIO_PULLUP;//上拉
HAL_GPIO_Init(DONG_IN_1_GPIO_Port, &GPIO_InitStruct);

(三)輸入相關函數

讀取指定的輸入端口引腳

GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)

參數:

GPIOx :其中x能夠(A..G取決於所使用的設備)來選擇GPIO外設

GPIO_Pin :指定要寫入的端口位。此參數能夠是GPIO_PIN_x之一,其中x能夠是(0..15 )

返回:

typedef enum
{
  GPIO_PIN_RESET = 0u,//低電平
  GPIO_PIN_SET//高電平
} GPIO_PinState;

例子:

GPIO_PinState res=HAL_GPIO_ReadPin(DONG_IN_1_GPIO_Port,DONG_IN_1_Pin);//讀取電平
if(res==GPIO_PIN_RESET){
     HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_SET);//兩個設置爲高電平
}else{
     HAL_GPIO_WritePin(GPIOA, DONG_OUT_1_Pin|DONG_OUT_2_Pin, GPIO_PIN_RESET);//兩個設置爲低電平
}

6、輸入編程(中斷檢測)

(一)CubeMX設置

 

GPIO mode:

l  上升沿觸發檢測的外部中斷模式(External Interrupt Mode with Rising edge trigger detection)

l  降低沿觸發檢測的外部中斷模式(External Interrupt Mode with Falling edge trigger detectiort)

l  上升/降低沿觸發檢測的外部中斷模式(External Interrupt Mode with Risinq/Falling edge trigger detection)

l  上升沿觸發檢測的外部事件模式(External Event Mode with Rising edge trigger detection)

l  降低沿觸發檢測的外部事件模式(External Event Mode with Falling edge trigger detection)

l  上升/降低沿觸發檢測的外部事件模式(External Event Mode with Rising/Falling edge trigger detectiont)

中斷和事件的區別:

l  中斷是當IO達到中斷條件後會向CPU產生中斷請求

l  事件是事先設置好的任務,當單片機達到要求將經過硬件的方式處理事先設置好的任務,而不向CPU請求中斷,好比DMAAD轉換等

(二)初始化函數

宏定義

#define KEY1_Pin GPIO_PIN_3
#define KEY1_GPIO_Port GPIOA
#define KEY1_EXTI_IRQn EXTI3_IRQn

初始化部分

__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/*Configure GPIO pin : PtPin */
GPIO_InitStruct.Pin = KEY1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(KEY1_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);

(三)中斷輸入相關函數

中斷回調函數

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin);

參數:

GPIO_Pin :指定鏈接EXTI線的引腳

例子:

//GPIO中斷回調函數
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
//判斷進入中斷的GPIOs
if(KEY1_Pin==GPIO_Pin){
            HAL_GPIO_TogglePin(GPIOA, DONG_OUT_1_Pin);//單獨輸出電平取反
            HAL_GPIO_TogglePin(GPIOA,DONG_OUT_2_Pin);//單獨輸出電平取反
     }
}

其它

關於按鍵防抖的問題:

l  軟件防抖能夠檢測到電平延時一段時間再確認電平,延時時間通常爲10-20ms

l  硬件防抖能夠在按鍵上並聯一個電容,通常爲0.1uf


 參考:

https://blog.csdn.net/baidu_37366055/article/details/80060962

相關文章
相關標籤/搜索