STM32F407之GPIO


因為有新人需要學習STM32的應用,一遍遍講又感覺效率低,時間上大大的浪費了,遂打算寫下一些筆記供其他人觀看、學習和糾錯,同時也鞏固下基礎。近期用到STM32F407VET6的開發板,所以用到的標准庫都是F4系列的,不過沒關系,不管是F4還是F103或者其他系列的,原理都是一樣的。


今天主要總結的是關於GPIO的配置,GPIO的定義是General Purpose Input Output (通用輸入/輸出),也是STM32最基礎和最常用的配置。這里假設事先已經下載好STM32F4的標准庫文件以及配置好STM32的開發環境了,如果還不會的可以先去百度一會。

使能時鍾

要想使用GPIO,我們首先需要初始化GPIO的時鍾。

從芯片手冊的截圖中我們可以看到,所有GPIO的時鍾都是由AHB1總線提供的,這里暫且不用管STM32的時鍾分類,關於STM32時鍾有時間會專門作介紹。所以這里GPIO時鍾的初始化就一行代碼帶過

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

結構體聲明

在STM32F4標准庫文件中有一個“stm32f4xx_gpio.h”的頭文件,里面包含了GPIO配置的所有信息,我們可以一步一步來分析如何配置滿足要求的GPIO。首先找到GPIO初始化結構體聲明如下:

/** 
  * @brief   GPIO Init structure definition  
  */ 
typedef struct
{
  uint32_t GPIO_Pin;              /*!< Specifies the GPIO pins to be configured.
                                       This parameter can be any value of @ref GPIO_pins_define */

  GPIOMode_TypeDef GPIO_Mode;     /*!< Specifies the operating mode for the selected pins.
                                       This parameter can be a value of @ref GPIOMode_TypeDef */

  GPIOSpeed_TypeDef GPIO_Speed;   /*!< Specifies the speed for the selected pins.
                                       This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOOType_TypeDef GPIO_OType;   /*!< Specifies the operating output type for the selected pins.
                                       This parameter can be a value of @ref GPIOOType_TypeDef */

  GPIOPuPd_TypeDef GPIO_PuPd;     /*!< Specifies the operating Pull-up/Pull down for the selected pins.
                                       This parameter can be a value of @ref GPIOPuPd_TypeDef */
}GPIO_InitTypeDef;

所以在初始化結構體中一共需要配置5個東西,我們先聲明一個GPIO初始化結構體變量再來一步步配置。聲明如下:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

需要注意,在keil的編譯器中,變量聲明要在使用之前,所以初始化變量的聲明要在我們剛剛說的時鍾初始化之前。

1、GPIO_Pin

第一個是選擇你所需要用的的引腳,從“stm32f4xx_gpio.h”的頭文件中可以看到由如下幾個宏定義:

/** @defgroup GPIO_pins_define 
  * @{
  */ 
#define GPIO_Pin_0                 ((uint16_t)0x0001)  /* Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /* Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /* Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /* Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /* Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /* Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /* Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /* Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /* Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /* Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /* Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /* Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /* Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /* Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /* Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /* Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /* All pins selected */

也就是STM32F407VET6所有引出的引腳了,這里我們選擇一個或多個引腳可以這么些:

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;

選擇多個的時候可以用'|'隔開。

2、GPIO_Mode

第二個是選擇所選擇引腳的工作模式,從頭文件中我們可以看到STM32引腳的工作模式一共有4種,分別是GPIO輸入模式、GPIO輸出模式、GPIO復用模和GPIO模擬模式。

typedef enum
{ 
  GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */
  GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */
  GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;

這幾種模式的功能和應用這里不作介紹,我們這里選擇最常用的輸出模式,即GPIO_Mode_OUT,代碼如下:

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

3、GPIO_Speed

顧名思義,接下來要配置的是GPIO的頻率或速度,事實上芯片為我們提供了4種速度模式

typedef enum
{ 
  GPIO_Low_Speed     = 0x00, /*!< Low speed    */
  GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
  GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
  GPIO_High_Speed    = 0x03  /*!< High speed   */
}GPIOSpeed_TypeDef;

/* Add legacy definition */
#define  GPIO_Speed_2MHz    GPIO_Low_Speed    
#define  GPIO_Speed_25MHz   GPIO_Medium_Speed 
#define  GPIO_Speed_50MHz   GPIO_Fast_Speed 
#define  GPIO_Speed_100MHz  GPIO_High_Speed  

分別是2MHz、25MHz、50MHz、100MHz,關於這GPIO速度的選擇可以去了解下“香農采樣定理”,這里我們選擇最高速100MHz。

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

4、GPIO_OType

第四個是關於輸出的形式,因為我們之前將引腳配置為輸出模式,所以我們這里還得配置輸出的形式,一共有兩個,分別是推挽輸出PP和開漏輸出OD,關於推挽輸出和開漏輸出的區別可以點擊這里 http://www.51hei.com/mcu/3988.html 我們這里選擇推挽輸出。

GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

5、GPIO_PuPd

typedef enum
{ 
  GPIO_PuPd_NOPULL = 0x00,
  GPIO_PuPd_UP     = 0x01,
  GPIO_PuPd_DOWN   = 0x02
}GPIOPuPd_TypeDef;

第五個是關於引腳有無上下拉的選擇,這個不用多做介紹,如果有不了解的可以了解下上拉和下拉的作用。這里我們選擇沒有上拉和下拉。

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

6、初始化

STM32F407VET6將引腳分成了GPIO PORT A、B、C、D、E五組,每組有15個引腳,所以我們需要確定到底要選擇的是那個PORT的引腳,這里我們選擇PORT A,對應上面的引腳,既是PA1、PA2和PA3這三個引腳。最后我們還需要調用GPIO初始化函數,將結構體變量中的信息傳遞給芯片。

GPIO_Init(GPIOA,&GPIO_InitStructure);

總結

至此關於GPIO的配置已經基本完成,這里只做了一個簡單的介紹,GPIO有很多復雜的功能需要去查看相關手冊去使用,同時網絡上的許多博客也是我們學習的資源。以下是完整代碼:

void GPIO_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);

  // typedef struct
  // {
  //   uint32_t GPIO_Pin;              /*!< Specifies the GPIO pins to be configured.
  //                                        This parameter can be any value of @ref GPIO_pins_define */
  //
  //   GPIOMode_TypeDef GPIO_Mode;     /*!< Specifies the operating mode for the selected pins.
  //                                        This parameter can be a value of @ref GPIOMode_TypeDef */
  //
  //   GPIOSpeed_TypeDef GPIO_Speed;   /*!< Specifies the speed for the selected pins.
  //                                        This parameter can be a value of @ref GPIOSpeed_TypeDef */
  //
  //   GPIOOType_TypeDef GPIO_OType;   /*!< Specifies the operating output type for the selected pins.
  //                                        This parameter can be a value of @ref GPIOOType_TypeDef */
  //
  //   GPIOPuPd_TypeDef GPIO_PuPd;     /*!< Specifies the operating Pull-up/Pull down for the selected pins.
  //                                        This parameter can be a value of @ref GPIOPuPd_TypeDef */
  // }GPIO_InitTypeDef;

  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_2|GPIO_Pin_3;
  // #define GPIO_Pin_0                 ((uint16_t)0x0001)  /* Pin 0 selected */
  // #define GPIO_Pin_1                 ((uint16_t)0x0002)  /* Pin 1 selected */
  // #define GPIO_Pin_2                 ((uint16_t)0x0004)  /* Pin 2 selected */
  // #define GPIO_Pin_3                 ((uint16_t)0x0008)  /* Pin 3 selected */
  // #define GPIO_Pin_4                 ((uint16_t)0x0010)  /* Pin 4 selected */
  // #define GPIO_Pin_5                 ((uint16_t)0x0020)  /* Pin 5 selected */
  // #define GPIO_Pin_6                 ((uint16_t)0x0040)  /* Pin 6 selected */
  // #define GPIO_Pin_7                 ((uint16_t)0x0080)  /* Pin 7 selected */
  // #define GPIO_Pin_8                 ((uint16_t)0x0100)  /* Pin 8 selected */
  // #define GPIO_Pin_9                 ((uint16_t)0x0200)  /* Pin 9 selected */
  // #define GPIO_Pin_10                ((uint16_t)0x0400)  /* Pin 10 selected */
  // #define GPIO_Pin_11                ((uint16_t)0x0800)  /* Pin 11 selected */
  // #define GPIO_Pin_12                ((uint16_t)0x1000)  /* Pin 12 selected */
  // #define GPIO_Pin_13                ((uint16_t)0x2000)  /* Pin 13 selected */
  // #define GPIO_Pin_14                ((uint16_t)0x4000)  /* Pin 14 selected */
  // #define GPIO_Pin_15                ((uint16_t)0x8000)  /* Pin 15 selected */
  // #define GPIO_Pin_All               ((uint16_t)0xFFFF)  /* All pins selected */

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  // typedef enum
  // {
  //   GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */
  //   GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */
  //   GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
  //   GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
  // }GPIOMode_TypeDef;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  // typedef enum
  // {
  //   GPIO_Low_Speed     = 0x00, /*!< Low speed    */
  //   GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
  //   GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
  //   GPIO_High_Speed    = 0x03  /*!< High speed   */
  // }GPIOSpeed_TypeDef;

  /* Add legacy definition */
  // #define  GPIO_Speed_2MHz    GPIO_Low_Speed
  // #define  GPIO_Speed_25MHz   GPIO_Medium_Speed
  // #define  GPIO_Speed_50MHz   GPIO_Fast_Speed
  // #define  GPIO_Speed_100MHz  GPIO_High_Speed

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  // typedef enum
  // {
  //   GPIO_OType_PP = 0x00,
  //   GPIO_OType_OD = 0x01
  // }GPIOOType_TypeDef;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  // typedef enum
  // {
  //   GPIO_PuPd_NOPULL = 0x00,
  //   GPIO_PuPd_UP     = 0x01,
  //   GPIO_PuPd_DOWN   = 0x02
  // }GPIOPuPd_TypeDef;

  GPIO_Init(GPIOA,&GPIO_InitStructure);
  // void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM