文章目錄
- 1 GPIO和Pin
- 1.1 GPIO和Pin基礎概念
- 1.2 GPIO輸入模式
- 1.3 GPIO輸出模式
- 1.4 GPIO的HAL庫
- 1.4.1 一些HAL庫表示
- 1.4.2 HAL庫常用GPIO函數
- 1.4.3 GPIO點亮led燈程序例子
1 GPIO和Pin
1.1 GPIO和Pin基礎概念
? 單片機有很多的引腳,為了操控每一個引腳,我們對引腳進行分組,例如GPIOA,GPIOB,…,GPIOG等等(Group),這一個組就稱為一個GPIO端口,一般一個端口包含十六個PIN引腳[0~15]。(一個引腳占2bits,而stm32是32位的,所以一組是16個)。GPIO引腳具有可復用和重映射的特點。
- GPIO復用功能:即一個管腳可以有不同的功能,但是同一時間的同一管腳只能占有一個功能。
- GPIO重映射功能:將復用引腳功能重定義到其他引腳,例如USART可能默認使用GPIOA2引腳,但是你可以重映射到GPIOD5使用。
GPIO硬件示意圖:
1.2 GPIO輸入模式
輸入模式有四種,分別是浮空輸入,上拉輸入,下拉輸入,模擬輸入:
-
浮空輸入:不接入上拉電阻或者下拉電阻,直接由觸發器輸入,該模式內部電路呈現高阻態,該模式必須有明確的電平輸入。該模式利用施密特觸發器的滯回特性,可以用于進行波形整形,用于抗干擾。如果該引腳懸空,讀出的值不確定。同時也可以用來輸入微弱的信號。
-
上拉輸入:即用上拉電阻將輸入拉到高電平。
-
下拉輸入:即用下拉電阻將輸入拉到低電平。
-
模擬輸入:把電壓信號直接傳送到片上外設模塊,如ADC,他和浮空輸入的區別是它不經過TTL施密特觸發器,是直接將模擬信號傳輸到外設模塊上。
1.3 GPIO輸出模式
- 推挽輸出:即兩個電平,0和1。推挽電路工作時,兩只對稱功率管輪流導通。所以導通損耗小,效率高。輸出既可向負載灌電流,也可向負載抽取電流,提高了電路的負載能力和開關速度。
- 開漏輸出:開漏輸出沒有高電平,他的兩個電平分別是0電平和(1)高阻態(輸出1高電平時,即是高阻態)。常常用于電平匹配或者形成“線與”邏輯關系。(電平匹配:例如單片機最高只能輸出5v電壓,但是輸出的外設需要15v電壓,這時候就需要使用開漏輸出來提高輸出電平)。
- 復用推挽輸出:I/O端口被用做復用功能,即第二功能時的I/O引腳配置,設置為推挽模式。USART,PWM就是典型的復用推挽輸出模式。
- 復用開漏輸出:I/O端口被用做復用功能,即第二功能時的I/O引腳配置,設置為開漏模式。I2C可以使用復用開漏輸出模式。
1.4 GPIO的HAL庫
1.4.1 一些HAL庫表示
//在HAL庫之中,端口的類型,和pin的類型分別是
GPIO_TypeDef *group; //用GPIO_TypeDef的指針定義端口
uint16_t pin; //引腳用無符號整形uint16_t定義//未使用宏定義的時候,例如表示GPIOA Pin12引腳。使用:
GPIOA 和 GPIO_PIN_12 //表示//若在CubeMX中起了名字,即有宏定義,例如重命名為GreenLED,那么表示為:
GreenLED_GPIO_Port 和 GreenLED_Pin //表示//電平狀態用GPIO_PinState定義
GPIO_PinState 有兩個,分別是GPIO_PIN_RESET和GPIO_PIN_SET
1.4.2 HAL庫常用GPIO函數
//根據GPIO_InitTypeDef結構體的參數初始化GPIO端口
void HAL_GPIO_Init (GPIO_TypeDef * GPIOx, GPIO_InitTypeDef * GPIO_Init);
//將GPIO端口的功能恢復到初始狀態
void HAL_GPIO_DeInit (GPIO_TypeDef * GPIOx, uint32_t GPIO_Pin);//讀出GPIOx中輸入寄存器的值
GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);
//將數據寫入GPIOx中輸出寄存器
void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState);
//翻轉某個引腳的電平狀態
void HAL_GPIO_TogglePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);//鎖定GPIOx寄存器,鎖定后將無法修改直到復位
HAL_StatusTypeDef HAL_GPIO_LockPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin);
1.4.3 GPIO點亮led燈程序例子
在CubeMX中使能相應的LED燈的引腳。
之后我們開始寫程序
//led.h文件
#ifndef __LED_H__
#define __LED_H__#include "gpio.h"#define ON 1
#define OFF 0enum{red_led,blue_led,green_led,max_led,
};extern int turn_led(int which, int status);
extern int blink_led(int which, int interval, int num);
#endif
//led.c文件
#include "led.h"typedef struct gpio_s{GPIO_TypeDef *group;uint16_t pin;
}gpio_t;gpio_t leds[max_led]={{ RedLED_GPIO_Port, RedLED_Pin },{ BlueLED_GPIO_Port, BlueLED_Pin},{ GreenLED_GPIO_Port, GreenLED_Pin},
};int turn_led(int which, int status)
{if (which >= max_led){return -1;}GPIO_PinState level;level = (status==OFF) ? GPIO_PIN_SET : GPIO_PIN_RESET;HAL_GPIO_WritePin(leds[which].group, leds[which].pin, level);return 0;
}int blink_led(int which, int interval, int num)
{while(num--){turn_led (which, ON);HAL_Delay(interval);turn_led (which, OFF);HAL_Delay(interval);}return 0;
}
之后在main函數中引入led.h頭文件,之后調用led的函數就可以實現跑馬燈,改變燈的狀態等功能了。