stm32f407
+ -

STM32F407ZG GPIO的初始化及使用

2021-12-31 24 0

GPIO的初始化使用GPIO_Init函数来实现,使用GPIO_SetBits函数和GPIO_ResetBits来置位。当然在初始化之前,必须先使能GPIO管脚所在GPIO组的时钟。

GPIO的寄存器

GPIO共有10个寄存器,也就是10个寄存器,一共可以控制一组GPIO的16个IO口。,分别为:

  • 一个端口模式寄存器(GPIOx_MODER)
  • 一个端口输出类型寄存器(GPIOx_OTYPER)
  • 一个端口输出速度寄存器(GPIOx_OSPEEDR)
  • 一个端口上拉下拉寄存器(GPIOx_PUPDR)
  • 一个端口输入数据寄存器(GPIOx_IDR)
  • 一个端口输出数据寄存器(GPIOx_ODR)
  • 一个端口置位/复位寄存器(GPIOx_BSRR)
  • 一个端口配置锁存寄存器(GPIOx_LCKR)
  • 两个复位功能寄存器(低位GPIOx_AFRL & GPIOx_AFRH)
  • 如果配置一个IO口需要2个位,那么刚好32位寄存器配置一组IO口16个IO口
  • 如果配置一个IO口只需要1个位,一般高16位保留.
  • BSRR寄存器32位分为低16位BSRRL和高16位BSRRH,BSRRL配置一组IO口的16个IO口的置位状态(1),BSRRH配置复位状态(0)。

使用模块时钟

时钟使能使用RCC_AHB1PeriphClockCmd函数来实现。

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)

RCC_AHB1Periph函数取模块名称,有:

#define RCC_AHB1Periph_GPIOA             ((uint32_t)0x00000001)
#define RCC_AHB1Periph_GPIOB             ((uint32_t)0x00000002)
#define RCC_AHB1Periph_GPIOC             ((uint32_t)0x00000004)
#define RCC_AHB1Periph_GPIOD             ((uint32_t)0x00000008)
#define RCC_AHB1Periph_GPIOE             ((uint32_t)0x00000010)
#define RCC_AHB1Periph_GPIOF             ((uint32_t)0x00000020)
#define RCC_AHB1Periph_GPIOG             ((uint32_t)0x00000040)
#define RCC_AHB1Periph_GPIOH             ((uint32_t)0x00000080)
#define RCC_AHB1Periph_GPIOI             ((uint32_t)0x00000100) 
#define RCC_AHB1Periph_GPIOJ             ((uint32_t)0x00000200)
#define RCC_AHB1Periph_GPIOK             ((uint32_t)0x00000400)
#define RCC_AHB1Periph_CRC               ((uint32_t)0x00001000)
#define RCC_AHB1Periph_FLITF             ((uint32_t)0x00008000)
#define RCC_AHB1Periph_SRAM1             ((uint32_t)0x00010000)
#define RCC_AHB1Periph_SRAM2             ((uint32_t)0x00020000)
#define RCC_AHB1Periph_BKPSRAM           ((uint32_t)0x00040000)
#define RCC_AHB1Periph_SRAM3             ((uint32_t)0x00080000)
#define RCC_AHB1Periph_CCMDATARAMEN      ((uint32_t)0x00100000)
#define RCC_AHB1Periph_DMA1              ((uint32_t)0x00200000)
#define RCC_AHB1Periph_DMA2              ((uint32_t)0x00400000)
#define RCC_AHB1Periph_DMA2D             ((uint32_t)0x00800000)
#define RCC_AHB1Periph_ETH_MAC           ((uint32_t)0x02000000)
#define RCC_AHB1Periph_ETH_MAC_Tx        ((uint32_t)0x04000000)
#define RCC_AHB1Periph_ETH_MAC_Rx        ((uint32_t)0x08000000)
#define RCC_AHB1Periph_ETH_MAC_PTP       ((uint32_t)0x10000000)
#define RCC_AHB1Periph_OTG_HS            ((uint32_t)0x20000000)
#define RCC_AHB1Periph_OTG_HS_ULPI       ((uint32_t)0x40000000)

为TRUE或FALSE.

管脚配置

打开时钟后,需要对我们需要的管脚进行配置。使用的函数是:

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

其中GPIOx对应寄存器的基地址,参数使用GPIO_InitStruct结构体来传递,结构体定义为:

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_Pin:一组GPIO为16位,使用GPIO_Pin指定相应的位地址。
  • GPIO_Mode:指明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_Speed:IO管脚时钟,有2M,25M,50M和100M,分别对应低速,中速,快速和高速。
    #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_OType:输出模式类型,仅用于当管脚为输出类型时,其余类型忽略。输出为型有推挽式,开漏式.
    GPIO_OType_PP = 0x00,
    GPIO_OType_OD = 0x01
    
    • 推挽输出:可以输出强高低电平,连接数字器件 .
    • 开漏输出:只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)
  • GPIO_PuPd:pull up和pull up即上拉与下拉配置。可选的有上下,下拉和浮空即无上下拉。
    typedef enum
    { 
    GPIO_PuPd_NOPULL = 0x00,
    GPIO_PuPd_UP     = 0x01,
    GPIO_PuPd_DOWN   = 0x02
    }GPIOPuPd_TypeDef;
    

置位与复位

置位与复位函数的参数相同,函数定义分别为:

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

GPIOx对应置位/复位寄存器.

GPIO输出示例代码

下面为对相应的LED指示灯点亮与熄灭,其硬件原理如下:
GPIO硬件连接图

相应的代码如下:

void Delay(__IO uint32_t nCount)
{
  while(nCount--){}
}

int main(void)
{

  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉,默认为高电平
  GPIO_Init(GPIOF, &GPIO_InitStructure);

  while(1)
    {
        GPIO_SetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
        Delay(0x7FFFFF);
        GPIO_ResetBits(GPIOF,GPIO_Pin_9|GPIO_Pin_10);
        Delay(0x7FFFFF);

    }
}

GPIO输入示例代码

下面为对相应的按键硬件连接图,其硬件原理如下:
按键硬件连接图

相应的代码如下:

#include "stm32f4xx.h"
int main(void)
{

    unsigned char key;
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

    //KEY
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3|GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

    while(1)
    {
        key = GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_2);
        if(key==1)
        {
            GPIO_SetBits(GPIOF,GPIO_Pin_9);
        }
        else
        {
            GPIO_ResetBits(GPIOF,GPIO_Pin_9);  
        }

        key = GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3);
        if(key==1)
        {
            GPIO_SetBits(GPIOF,GPIO_Pin_10);
        }
        else
        {
            GPIO_ResetBits(GPIOF,GPIO_Pin_10);  
        }

        key = GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4);
        if(key==1)
        {
            GPIO_ResetBits(GPIOF,GPIO_Pin_8);  
        }
        else
        {
            GPIO_SetBits(GPIOF,GPIO_Pin_8);
        }
    }


}

分别按KEY0,KEY1让对应的LED1,LED2熄灭或点亮。而KEY3对应的蜂鸣器,其对应的原理图如下:
蜂鸣器原理图

0 篇笔记 写笔记

STM32F407ZG GPIO的初始化及使用
GPIO的初始化使用GPIO_Init函数来实现,使用GPIO_SetBits函数和GPIO_ResetBits来置位。当然在初始化之前,必须先使能GPIO管脚所在GPIO组的时钟。GPIO的寄存器GPIO共有10个寄存器,也就是10个寄存器,一共可以控制一组GPIO的16个IO口。,分别为:......
作者信息
我爱开发
Windows驱动开发,网站开发
好好学习,天天向上。
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!