使用固件库控制STM32F103的GPIO输出高低电平,实现LED灯的亮灭

在编写有关于LED灯结构体的时候,需要先进行GPIO端口时钟设置,输入输出模式设置,GPIO引脚高低电平设置。
接下来将分别介绍各个结构体如何配置

  1. GPIO介绍
    General Purpose Input Output (通用输入/输出)简称为GPIO,STM32F103VET6共有80个GPIO,这些IO管脚被分成了A、B、C、D、E 5组,每组编号0~15个管脚。可以通过软件来控制这些管脚的基本状态,如管脚的高低电平、输入输出状态等。但是在使用GPIO管脚之前需要对其进行设置,主要包括外设时钟设置、输入输出模式设置和引脚速率设置。

(1)外设时钟设置使用库函数RCC_APB2PeriphClockCmd(),例如,设置GPIO中A组管脚,代码如下所示:

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE)

(2)输入输出模式、管脚速率设置
管脚输入输出模式和管脚速率可以通过固件库中的一个结构体来进行设置,结构体代码如下所示;

 typedef struct
      {
         uint16_t GPIO_Pin;
         GPIOSpeed_TypeDef GPIO_Speed;
         GPIOMode_TypeDef GPIO_Mode;
      }GPIO_InitTypeDef;

管脚的输入输出模式有以下几种:
模拟输入GPIO_AIN ——应用ADC模拟输入,或者低功耗下省电;
浮空输入GPIO_IN_FLOATING ——浮空输入,可以做KEY识别;
带上拉输入GPIO_IPU——IO内部上拉电阻输入;
带下拉输入GPIO_IPD—— IO内部下拉电阻输入;
开漏输出GPIO_OUT_OD ——IO输出0接GND,IO输出1,悬空;
推挽输出GPIO_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC;
复用功能的推挽输出GPIO_AF_PP ——片内外设功能(I2C的SCL,SDA);
复用功能的开漏输出GPIO_AF_OD——片内外设功能。

2.LED灯控制原理

img


LED灯与GPIO管脚连接如下图所示,其中PB0、PB1、PB5分别是STM32F103VET中GPIO B组的第0、1、5三个管脚,
只需要将PB0、PB1、PB5设置为低电平,就可以点亮对应的LED灯。

3.参数的宏定义
(1)LED灯引脚的宏定义

      #define LED_G_GPIO_PIN         GPIO_PIN_0
      #define LED_G_GPIO_PORT        GPIOB
      #define LED_G_GOIO_CLK         RCC_APB2Periph_GPIOB

      #define LED_B_GPIO_PIN                GPIO_PIN_1
      #define LED_B_GPIO_PORT       GPIOB
      #define LED_B_GPIO_CLK        RCC_APB2Periph_GPIOB

      #define LED_R_GPIO_PIN                GPIO_PIN_5
      #define LED_R_GPIO_PORT       GPIOB
      #define LED_R_GPIO_CLK        RCC_APB2Periph_GPIOB

(2)LED灯亮灭状态的宏定义

      #define     LED_G(a)   if(a)\
          GPIO_SetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN);\
              else  GPIO_ResetBits(LED_G_GPIO_PORT,LED_G_GPIO_PIN);
      void LED_GPIO_Config(void);

      #define     LED_B(a)   if(a)\
          GPIO_SetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);\
              else  GPIO_ResetBits(LED_B_GPIO_PORT,LED_B_GPIO_PIN);
      void LED_GPIO_Config(void);

      #define     LED_R(a)   if(a)\
          GPIO_SetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);\
              else  GPIO_ResetBits(LED_R_GPIO_PORT,LED_R_GPIO_PIN);
      void LED_GPIO_Config(void);

使用带参宏选择性执行GPIO_SetBits()和GPIO_ResetBits()函数,这两个函数为固件库中定义的管脚高低电平的设置函数。

(3)LED_GPIO的初始化
利用上面的宏,编写LED 灯的初始化函数,代码如下所示:

 void LED_GPIO_Config(void)
      {
    GPIO_InitTypeDef   GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(LED_G_GOIO_CLK|LED_B_GOIO_CLK|LED_R_GOIO_CLK,ENABLE);      //使能时钟
    GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN_0;           //选择要控制的引脚
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;          //设置引脚输出模式
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;        //设置引脚速率
    GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
    
    GPIO_InitTypeDef   GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(LED_B_GOIO_CLK,ENABLE);
    GPIO_InitStruct.GPIO_Pin = LED_B_GPIO_PIN_1;
    GPIO_Init(LED_B_GPIO_PORT, &GPIO_InitStruct);
    
    GPIO_InitTypeDef   GPIO_InitStruct;
    RCC_APB2PeriphClockCmd(LED_R_GOIO_CLK,ENABLE);
    GPIO_InitStruct.GPIO_Pin = LED_R_GPIO_PIN_5;
    GPIO_Init(LED_R_GPIO_PORT, &GPIO_InitStruct);
    
    GPIO_SetBits(LED_G_GPIO_PORT, macLED1_GPIO_PIN);      //关闭LED灯
        GPIO_SetBits(LED_B_GPIO_PORT, macLED2_GPIO_PIN);     
        GPIO_SetBits(LED_R_GPIO_PORT, macLED3_GPIO_PIN);
      }

(4)主函数调用
在main 函数中,调用前面定义的LED_GPIO_Config 初始化好LED 的控制引脚,然后直接调用各种控制LED 灯亮灭的宏来实现LED 灯的控制。

      LED_GPIO_Config();         //初始化GPIO
      while (1)
      {
          LED1( ON );              // 灯亮
          Delay(0x0FFFFF);
          LED1( OFF );          // 灯灭

          LED2( ON );              
          Delay(0x0FFFFF);
          LED2( OFF );          

          LED3( ON );              
          Delay(0x0FFFFF);
          LED3( OFF );          
      }

这是问啥呢?