0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

STM32速成筆記(2)—GPIO

冬至子 ? 來源:二土電子 ? 作者:二土電子 ? 2023-10-23 16:36 ? 次閱讀

一、什么是GPIO

GPIO(英語:General-purpose input/output),通用型之輸入輸出的簡稱,可以用來輸入高低電平或者輸出高低電平。這里的高電平指的是3.3V,低電平指的是0V。通常稱GPIO為IO口,或者引腳。

STM32F103ZET6有GPIOx_0~GPIOx_15,其中x = A,B,C,D,E,F,G。

二、GPIO的輸入/輸出模式

GPIO有多種輸入輸出模式,輸入模式有

  • ? 輸入浮空 輸入浮空指的是GPIO與外設(shè)之間既不接高電平,也不接低電平,呈高阻態(tài)。除了類似于在數(shù)據(jù)傳輸時將GPIO配置為輸入浮空外,一般不配置為該模式。因為輸入浮空狀態(tài)的GPIO電壓具有不確定性,可能是0V,也可能是VCC,或者是介于0V和VCC之間的某一個值。
  • ? 輸入上拉 輸入上拉是通過一個上拉電阻,將GPIO拉至高電平狀態(tài),不受外接電路的影響。
  • ? 輸入下拉 輸入下拉是通過一個下拉電阻,將GPIO拉至低電平,不受外接電路的影響。
  • ? 模擬輸入 模擬輸入模式通常用在ADC采集,采集模擬信號。

輸出模式有

  • ? 開漏輸出
  • ? 推挽式輸出
  • ? 推挽式復(fù)用功能
  • ? 開漏復(fù)用功能

對于一些輸出模式這里就不再做詳細介紹了,貼一篇大佬的文章深刻理解GPIO。這些模式在接下來的學(xué)習(xí)過程中會慢慢的介紹這些模式需要在什么時候使用,這里只需要知道就夠了。

三、GPIO初始化配置

本專欄介紹的是使用庫函數(shù)進行開發(fā),很多內(nèi)容都是庫函數(shù)提供的,相對來講非常方便。在初始化GPIO時有一個結(jié)構(gòu)體,只需要對這個結(jié)構(gòu)體進行配置即可。結(jié)構(gòu)體中包括想要配置的GPIO引腳,GPIO速度,GPIO工作模式。

初始化GPIO的步驟主要有

  • ? 定義GPIO結(jié)構(gòu)體
  • ? 開啟時鐘 GPIO工作需要提供時鐘信號,在初始化結(jié)構(gòu)體之前需要將時鐘打開
  • ? 配置結(jié)構(gòu)體成員 GPIO_Pin是想要配置的IO,GPIO_Speed,通常寫GPIO_Speed_50MHz,GPIO_Mode是IO的工作模式
  • ? 寫入配置

GPIO的工作模式在程序中有定義

typedef enum
{ GPIO_Mode_AIN = 0x0,   // 模擬輸入
  GPIO_Mode_IN_FLOATING = 0x04,   // 輸入浮空
  GPIO_Mode_IPD = 0x28,   // 輸入下拉
  GPIO_Mode_IPU = 0x48,   // 輸入上拉
  GPIO_Mode_Out_OD = 0x14,   // 開漏輸出
  GPIO_Mode_Out_PP = 0x10,   // 推挽式輸出
  GPIO_Mode_AF_OD = 0x1C,   // 開漏復(fù)用功能
  GPIO_Mode_AF_PP = 0x18   // 推挽式復(fù)用功能
}GPIOMode_TypeDef;

初始化GPIO的例程如下

void Drv_Gpio_Init (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;   // 定義結(jié)構(gòu)體
    // 開啟時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB,ENABLE);

    // 配置結(jié)構(gòu)體
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置結(jié)構(gòu)體
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

這里初始化的是PA0,PA8和PB1,PB2。在開啟時鐘不必要寫兩遍相同的代碼用來初始化GPIOA和GPIOB的時鐘。寫一句,用“ | ”同時開啟兩個GPIO的時鐘。寫Pin時也同理。

四、Boot引腳

這里簡單介紹一下Boot引腳的配置,對于只是利用核心板編寫程序的小伙伴來說Boot引腳的存在感較低,但是當我們需要繪制硬件電路圖時,Boot引腳怎么連接就顯得很重要。中文參考手冊中介紹如下

圖片

中文參考手冊Boot引腳介紹

這里簡單說一下本人經(jīng)歷得來的經(jīng)驗。如果想使用USB轉(zhuǎn)TTL通過串口下載程序,Boot0需要通過KΩ級電阻接VCC,Boot1接地。下載完程序后再將Boot0接地。需要注意的是這個KΩ級別的電阻最好用10KΩ左右電阻,如果電阻太大會導(dǎo)致下載失敗。

由于本人在使用自制板時只使用過串口下載,所以對于用調(diào)試器下載需要怎么配置Boot引腳,未測試。

五、一些特殊的GPIO

在使用GPIO時需要注意一些特殊的GPIO,否則你會疑惑,為什么一些引腳的高低電平無法控制。其實有些GPIO在上電后就有自己的默認設(shè)置,會穩(wěn)定在高電平或者低電平。比如用作JTAG的幾個GPIO——PB3,PB4,PA13,PA14和PA15。這幾個GPIO在上電后就已經(jīng)默認用作JTAG,即使用上面的GPIO初始化程序?qū)⑦@幾個引腳初始化后,依舊無法控制(無法正常用程序拉高拉低)。

這個時候我們需要對這幾個GPIO進行復(fù)用重映射,關(guān)掉其默認的功能,才能作為普通的GPIO使用。針對JTAG/SWD復(fù)用功能重映射,中文參考手冊描述如下

圖片

中文參考手冊關(guān)于JTAG/SWD引腳的描述

圖中說明這幾個GPIO有幾種模式,完全SWJ,表中的五個IO均不可作為普通IO使用。完全SWJ但是沒有JNTRST,PB3和PB4可用,依此解讀。上圖是針對寄存器開發(fā)描述的內(nèi)容,使用庫函數(shù)開發(fā)時有封裝好的函數(shù),但是需要注意的是需要提前開啟AFIO時鐘(對于AFIO是指什么,大家可以自行了解)。使用庫函數(shù)開發(fā)時針對特殊引腳進行重映射的操作步驟為

  • ? 定義GPIO結(jié)構(gòu)體
  • ? 開啟GPIO時鐘和AFIO時鐘
  • ? 重映射引腳(根據(jù)所需情況設(shè)定引腳模式)
  • ? 配置GPIO結(jié)構(gòu)體初始化GPIO

庫函數(shù)中提供了可以選擇的三種引腳模式

GPIO_Remap_SWJ_NoJTRST          // 完全SWJ(恢復(fù)引腳的默認功能)
GPIO_Remap_SWJ_JTAGDisable      // 關(guān)閉JTAG,啟用SW-DP
GPIO_Remap_SWJ_Disable          // 關(guān)閉JTAG-DP,關(guān)閉SW-DP

提供了一個函數(shù),可以進行重映射操作

void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);

當需要使用到上述的五個GPIO時,初始化程序需要修改,舉例如下

void Drv_Gpio_Init (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;   // 定義結(jié)構(gòu)體
    // 開啟時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 
                           RCC_APB2Periph_AFIO,ENABLE);

    // 關(guān)閉JTAG-DP,關(guān)閉SW-DP
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
    
    // 配置結(jié)構(gòu)體
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // 配置結(jié)構(gòu)體
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

STM32F103ZET6芯片GPIO資源較為豐富,平時開發(fā)時盡量不要使用這幾個特殊引腳。

六、點亮LED

學(xué)習(xí)完GPIO后我們就可以利用GPIO進行一些簡單的操作,比如點亮LED,使用蜂鳴器,用IO驅(qū)動小黃電機,檢測按鍵等。

點亮LED比較簡單,但是也有一些需要注意的點

  • ? 根據(jù)硬件電路確定LED是高電平點亮還是低電平點亮
  • ? 初始化GPIO后要先將所有的LED

6.1 硬件電路

下圖所示電路中,LED右側(cè)接3.3V,左側(cè)接IO口。此時如果想點亮LED,需要將對應(yīng)的IO電平拉低。相反如果右側(cè)接的是地,如果想要點亮LED,需要將對應(yīng)IO電平拉高。

圖片

LED電路

6.2 拉高/拉低GPIO

如何將GPIO電平拉高拉低?庫函數(shù)提供了封裝好的函數(shù)

// 設(shè)置為高電平
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

// 設(shè)置為低電平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

6.3 程序設(shè)計

點亮LED很簡單,只需要初始化相應(yīng)的GPIO,輸入模式設(shè)置為推挽式輸出,然后設(shè)定電平即可。

這里給出點亮LED的例程,LED電路為一側(cè)接3.3V,另一側(cè)接GPIO。

這里給出的只是一些必要的函數(shù),如果需要工程模板可私信聯(lián)系。

需要注意的是,初始化GPIO時需要開啟時鐘,開啟時鐘之前需要確認GPIO掛載的總線。

/*
 *==============================================================================
 *函數(shù)名稱:Drv_Led_Init 
 *函數(shù)功能:初始化LED的GPIO
 *輸入參數(shù):無
 *返回值:無
 *==============================================================================
*/
void Drv_Led_Init (void)
{
    GPIO_InitTypeDef GPIO_InitStructure;   // 定義結(jié)構(gòu)體
    // 開啟時鐘
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

    // 配置結(jié)構(gòu)體
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_SetBits(GPIOA,GPIO_Pin_1);   // 熄滅LED
}

/*
 *==============================================================================
 *函數(shù)名稱:Med_Led_On 
 *函數(shù)功能:點亮LED
 *輸入?yún)?shù):無
 *返回值:無
 備注:如果有多個LED可以定義一個結(jié)構(gòu)體或者使用swtich,增加一個輸入變量
      來確定開啟哪個LED
 *==============================================================================
*/
void Med_Led_On (void)
{
    GPIO_ResetBits(GPIOA,GPIO_Pin_1);   // 熄滅LED
}

七、GPIO的位帶操作

對于什么是“位帶”這里就不做解釋了,大家可以自行搜索。這里只介紹如何使用。位帶操作可以使操作GPIO變得更加簡單。在模板程序的sys.h文件中已經(jīng)定義好了各個IO的位帶操作所需內(nèi)容

//IO口操作,只對單一的IO口!
//確保n的值小于16!
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr,n)  //輸出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_Addr,n)  //輸入 

#define PBout(n)   BIT_ADDR(GPIOB_ODR_Addr,n)  //輸出 
#define PBin(n)    BIT_ADDR(GPIOB_IDR_Addr,n)  //輸入 

#define PCout(n)   BIT_ADDR(GPIOC_ODR_Addr,n)  //輸出 
#define PCin(n)    BIT_ADDR(GPIOC_IDR_Addr,n)  //輸入 

#define PDout(n)   BIT_ADDR(GPIOD_ODR_Addr,n)  //輸出 
#define PDin(n)    BIT_ADDR(GPIOD_IDR_Addr,n)  //輸入 

#define PEout(n)   BIT_ADDR(GPIOE_ODR_Addr,n)  //輸出 
#define PEin(n)    BIT_ADDR(GPIOE_IDR_Addr,n)  //輸入

#define PFout(n)   BIT_ADDR(GPIOF_ODR_Addr,n)  //輸出 
#define PFin(n)    BIT_ADDR(GPIOF_IDR_Addr,n)  //輸入

#define PGout(n)   BIT_ADDR(GPIOG_ODR_Addr,n)  //輸出 
#define PGin(n)    BIT_ADDR(GPIOG_IDR_Addr,n)  //輸入

有了位帶操作后,就不需要再使用前面介紹的拉高拉低函數(shù)來操作GPIO。比如需要拉d低PA1

PAout(1) = 0;   // 拉低PA1

有了位帶操作后也可以對GPIO進行宏定義,用自己想要的名字來操作它。還是拿上面的拉低PA1舉例

#define LED   PAout(1)   // 將PA1宏定義為LED

LED = 1;   // 拉高PA1
LED = 0;   // 拉低PA1
聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 上拉電阻
    +關(guān)注

    關(guān)注

    5

    文章

    355

    瀏覽量

    30446
  • GPIO
    +關(guān)注

    關(guān)注

    16

    文章

    1175

    瀏覽量

    51515
  • 調(diào)試器
    +關(guān)注

    關(guān)注

    1

    文章

    297

    瀏覽量

    23568
  • 開漏輸出
    +關(guān)注

    關(guān)注

    0

    文章

    34

    瀏覽量

    7282
  • STM32F103ZET6
    +關(guān)注

    關(guān)注

    9

    文章

    67

    瀏覽量

    21001
收藏 人收藏

    評論

    相關(guān)推薦

    STM32 GPIO的工作模式

    在之前圍繞STM32GPIO的基本結(jié)構(gòu)進行了介紹,圖1為STM32的5V容忍的GPIO口內(nèi)部基本結(jié)構(gòu)圖,圖2
    發(fā)表于 04-14 10:40 ?1717次閱讀
    <b class='flag-5'>STM32</b> <b class='flag-5'>GPIO</b>的工作模式

    STM32學(xué)習(xí)筆記_DAY2_GPIO

    STM32學(xué)習(xí)筆記_DAY2_GPIO,附帶工程文件
    發(fā)表于 08-14 12:44

    STM32 GPIO學(xué)習(xí)筆記

    STM32學(xué)習(xí)筆記GPIOSTM32F103RCT6共有51個GPIO:PA(B,C,D) 0-15 和PD 0-2GPIO相關(guān)寄存器端口配
    發(fā)表于 11-30 07:35

    STM32各模塊學(xué)習(xí)筆記

    GPIO...............................................15 STM32筆記之六 運行的必要硬件庫 ........................................2
    發(fā)表于 11-30 03:32 ?3083次閱讀

    MCU學(xué)習(xí)筆記_GPIO工作原理

    MCU學(xué)習(xí)筆記STM32時鐘1. STM32 GPIO基礎(chǔ)知識2. STM32
    發(fā)表于 10-25 11:21 ?17次下載
    MCU學(xué)習(xí)<b class='flag-5'>筆記</b>_<b class='flag-5'>GPIO</b>工作原理

    STM32 通用GPIO模擬I2C實現(xiàn)

    STM32 模擬I2C實現(xiàn)#通用GPIO模擬I2C通信實現(xiàn)樣例1 GPIO初始化``#ifdef HW_I
    發(fā)表于 11-29 15:21 ?28次下載
    <b class='flag-5'>STM32</b> 通用<b class='flag-5'>GPIO</b>模擬I<b class='flag-5'>2</b>C實現(xiàn)

    STM32F407標準庫學(xué)習(xí)筆記-GPIO

    STM32F407標準庫學(xué)習(xí)筆記-GPIO頭文件 gpio.h枚舉-列舉同一寄存器的不同選項typedef enum{ GPIO_Low
    發(fā)表于 11-29 15:51 ?46次下載
    <b class='flag-5'>STM32</b>F407標準庫學(xué)習(xí)<b class='flag-5'>筆記</b>-<b class='flag-5'>GPIO</b>

    STM32學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之keil5編程與GPIO開發(fā)

    STM32學(xué)習(xí)筆記1——軟硬件基礎(chǔ)之keil5編程與GPIO開發(fā)
    發(fā)表于 11-30 12:36 ?4次下載
    <b class='flag-5'>STM32</b>學(xué)習(xí)<b class='flag-5'>筆記</b>1——軟硬件基礎(chǔ)之keil5編程與<b class='flag-5'>GPIO</b>開發(fā)

    STM32學(xué)習(xí)筆記-GPIO使用超強總結(jié)

    STM32 GPIO使用超強總結(jié)1 GPIO使用步驟1.1. 使能GPIO對應(yīng)的外設(shè)時鐘例如://使能GPIOA、GPIOB、GPIOC對應(yīng)的外設(shè)時鐘RCC_APB
    發(fā)表于 12-02 20:06 ?13次下載
    <b class='flag-5'>STM32</b>學(xué)習(xí)<b class='flag-5'>筆記</b>-<b class='flag-5'>GPIO</b>使用超強總結(jié)

    STM32f1學(xué)習(xí)筆記——GPIO

    通用輸入/輸出GPIO參考文章:“STM32自學(xué)筆記”Stn32可以提供很多GPIO,一般分別在5個端口(PORT)(GPIOA-GPIOE),每個端口有16個
    發(fā)表于 12-05 13:21 ?1次下載
    <b class='flag-5'>STM32</b>f1學(xué)習(xí)<b class='flag-5'>筆記</b>——<b class='flag-5'>GPIO</b>

    [STM32CubeMX]學(xué)習(xí)筆記1:GPIO輸出LED流水燈

    [STM32CubeMX]學(xué)習(xí)筆記1:GPIO輸出LED流水燈
    發(fā)表于 12-05 13:36 ?12次下載
    [<b class='flag-5'>STM32</b>CubeMX]學(xué)習(xí)<b class='flag-5'>筆記</b>1:<b class='flag-5'>GPIO</b>輸出LED流水燈

    STM32學(xué)習(xí)筆記 P1 GPIO 梳理加理解

    ://www.bilibili.com/video/BV1eb411V7hf?p=9STM32引腳說明64引腳—51IO口GPIO基本結(jié)構(gòu)查閱30頁(FT)標識:可承擔5V電壓GPIO工作方式1-4輸入 5-8輸出 3種最大反
    發(fā)表于 01-13 16:07 ?3次下載
    <b class='flag-5'>STM32</b>學(xué)習(xí)<b class='flag-5'>筆記</b> P1 <b class='flag-5'>GPIO</b> 梳理加理解

    STM32學(xué)習(xí)筆記---GPIO

    STM32的學(xué)習(xí)筆記GPIO我使用的是STM32F401ZGT6,有7組IO口,每組16個引腳,共112個引腳。因為太菜了,確實容易出錯,還請賜教參考官方文檔:八種IO口模式區(qū)別結(jié)構(gòu)
    發(fā)表于 01-13 16:31 ?6次下載
    <b class='flag-5'>STM32</b>學(xué)習(xí)<b class='flag-5'>筆記</b>---<b class='flag-5'>GPIO</b>

    STM32GPIO配置

    STM32微控制器通用輸入/輸出引腳(GPIO)提供許多與應(yīng)用框架內(nèi)外部電路相連接的方法。本應(yīng)用筆記提供有關(guān)GPIO配置的基本信息,以及硬件和軟件開發(fā)人員使用
    發(fā)表于 08-31 10:50 ?1次下載

    STM32 GPIO的基本結(jié)構(gòu)

    STM32中,所有GPIO都是掛在APB2這個總線上面的;
    的頭像 發(fā)表于 10-24 09:24 ?921次閱讀
    <b class='flag-5'>STM32</b> <b class='flag-5'>GPIO</b>的基本結(jié)構(gòu)