GPIO為最基礎應用也最廣泛之功能,本篇主要紀錄GPIO中所學習到的知識。
以STM32G431為例,使用CubeMX設定GPIO之條件所帶來的相關功能,也將依依解釋與紀錄。
STM32G431所使用系列,共有45pin,使用STM32cubeIDE建立檔案,進入到CubeMX後,可看見完整MCU接腳圖,點選任意腳出現各種功能與名稱,每個腳位有不同使用功能,也有重複的部分。有時候需要查功能配置腳位圖需要查詢spec,但後來大部分直接使用MX確認所需的接腳,進行機種配置,方便又快速。
本文主要說明GPIO,系統與時脈設定就不多加說明
以P2腳位PC13為例,設定為GPIO輸出腳位。在MCU接腳圖點選GPIO_Output
可在左邊System Core選項中開啟GPIO視窗,可顯現所設定腳位詳細資料
可在User Label可自行定義名稱。
若沒有特殊要求,甚至User Label亦可選擇默認,即完成CubeMX中 GPIO的配置
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列舉值之一:
. GPIO_PIN_RESET:清除埠Pin,低電平
. 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, 1);//單獨設定為高電平
HAL_Delay(1000);//1s
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
小記
CubeMX中的GPIO設定真的很簡易,雖然有其餘功能,但幾乎點一下即開啟使用,但相對在main.c指令與函數中的使用,若不曉得有HAL指令的,還真的不曉得如何應用,我剛初學甚至連HAL指令在哪都不曉得。
GPIO intput使用可以分成兩種方式達成,分別是輪詢與中斷方式
首先以輪詢方式說明步驟:
設定為GPIO輸入腳位。在MCU接腳圖點選GPIO_input
可在左邊System Core選項中開啟GPIO視窗,可顯現所設定腳位詳細資料
1.使GPIO讀取腳位高電平或低電平
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);//兩個設定為低電平
}
以中斷方式說明步驟:
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請求中斷,比如DMA、AD轉換等
中斷回撥函式
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);//單獨輸出電平取反
}
}
STM32的HAL庫中GPIO有8種工作模式,4種輸入狀態、4種輸出狀態(2種復用輸出+2種普通輸出),分別對應如下:
1、浮空輸入模式
當GPIO採用浮空輸入模式時,STM32的引腳狀態是不確定的,此時STM32得到的電平狀態完全取決於GPIO外部的電平狀態,所以說在GPIO外部的引腳懸空時,讀取該埠的電平狀態是個不確定的值。
#define GPIO_MODE_INPUT 0x00000000U /*!< Input Floating Mode */
2、模擬輸入模式
這個很好理解,最常用的場合是ADC模擬輸入,不像其他輸入模式只有0和1,模擬輸入模式可以讀取到很細微變化的值。
#define GPIO_MODE_ANALOG 0x00000003U /*!<
3、帶上拉、下拉輸入模式
STM32的數據手冊中關於上下拉的電阻的介紹是電阻阻值都在30-50K之間。
為什麼要用帶上拉或者下拉輸入的模式呢?因為浮空模式時,在GPIO外部連接的電路未工作時,STM32讀取的GPIO狀態是不確定的,所以可以採用帶上拉或者下拉輸入的模式先給MCU一個確定的狀態,當外部電路電平狀態發生變化時,易於MCU的判斷。這樣可以增強MCU的抗干擾能力Analog Mode */
#define GPIO_MODE_IT_RISING 0x10110000U /*!< External Interrupt Mode with Rising edge trigger detection */
#define GPIO_MODE_IT_FALLING 0x10210000U /*!< External Interrupt Mode with Falling edge trigger detection */
#define GPIO_MODE_IT_RISING_FALLING 0x10310000U /*!< External Interrupt Mode with Rising/Falling edge trigger detection */
4、推輓輸出模式
推挽結構一般是指兩個三極體分別受兩個互補信號的控制,總是在一個三極體導通的時候另一個截止。這種結構既可以輸出高電平,也可以輸出低電平,可以用於連接數字器件。
以推挽方式存在於電路中,各負責正負半周的波形放大任務,電路工作時,兩隻對稱的功率開關管每次只有一個導通,所以導通損耗小、效率高。輸出既可以向負載灌電流,也可以從負載抽取電流。推拉式輸出級既提高電路的負載能力,又提高開關速度。
#define GPIO_MODE_OUTPUT_PP 0x00000001U /*!< Output Push Pull Mode */
5、開漏輸出模式
我們重點講開漏輸出,一般開漏輸出模式時,如果外部不接上拉電阻時,只能輸出低電平,所以要想輸出高電平必須要外接上拉電阻。這樣做的有一個好處,可以用來匹配不同的電平信號,也就是用於不同電壓的系統之間的通信;另外,因為要輸出高電平需要有外部的上拉電阻,所以在進行通信時,通信的速度也受到上拉電阻阻值的影響,阻值小時,通信速度可以很快,阻值大時,通信速度變慢,但也不能為了通信速度把上拉電阻用的很小,也要注意在電阻很小時,功耗會變大,所以要平衡好這個度。
#define GPIO_MODE_OUTPUT_OD 0x00000011U /*!< Output Open Drain Mode */
6、復用推挽、開漏輸出模式
這兩種模式,可以理解為把GPIO配置為第二功能使用的時候的配置,並非單純的用作IO輸入或輸出。
比如使用外設IIC時,我們需要把GPIO配置為復用推輓輸出,用於數據通信功能。
再比如串口通信的TX、以及SPI外設的GPIO使用就要把引腳設置為復用開漏輸出。
#define GPIO_MODE_AF_PP 0x00000002U /*!< Alternate Function Push Pull Mode /
#define GPIO_MODE_AF_OD 0x00000012U /!< Alternate Function Open Drain Mode */
小記
CubeMX中的GPIO設定真的很簡易,雖然有其餘功能,但幾乎點一下即開啟使用,但相對在main.c指令與函數中的使用,若不曉得有HAL指令的,還真的不曉得如何應用,我剛初學甚至連HAL指令在哪都不曉得。
若此文章對您有幫助或學習,歡迎加入likecoin讚賞公民,下方連結點擊like支持~
本文參考