STM32學習筆記——GPIO

菠菜面筋發表於2024-09-06

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
    }
}

相關文章