文章目录

  • STM32 GPIO
  • 1. GPIO简介
  • 2. GPIO工作模式
  • 3. GPIO相关寄存器
  • 4. 通用外设驱动模型
  • 5. GPIO配置步骤
  • 6. 点亮LED灯
  • 7. LED流水灯
  • 8. 按键控制LED灯
  • STM32 GPIO

    1. GPIO简介

  • 什么是GPIO?

    GPIO:General Purpose Input Output,即通用输入输出端口,简称GPIO

    作用:负责采集外部器件的信息或者控制外部器件工作,即输入输出

    STM32F103ZET6芯片是144脚的芯片,具有GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF和GPIOG七组GPIO口,共有112个IO口可供编程使用。

  • GPIO特点?

    1. 不同型号芯片IO口数量可能不一样
    2. 快速翻转
    3. 每个IO口都可以做中断
    4. 支持8种工作模式
  • GPIO电气特性?

    1. STM32工作电压范围:2 V <= VDD <= 3.6 V

    2. GPIO识别电压范围:CMOS端口:-0.3 V <= 低电平 <= 1.164 V 1.833 V <= 高电平 <= 3.6 V

    3. GPIO输出电流:单个IO,最大25mA

  • GPIO引脚分布?

    STM32引脚类型:电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚

  • 2. GPIO工作模式

    1. 浮空输入

    2. 上拉输入

    3. 下拉输入

    4. 模拟输入

    5. 开漏输出

    6. 复用开漏输出

    7. 推挽输出

    8. 复用推挽输出

    3. GPIO相关寄存器

    CRL CRH IDR ODR BSRR BRR LCKR
    配置工作模式,输出速度 配置工作模式,输出速度 输入数据 输出数据 设置ODR寄存器的值 F4之后没有这个寄存器,考虑代码兼容性的话不建议使用 配置锁定,用得不多
  • CRL寄存器
  • 作用:配置GPIOxPx0~Px7工作模式输出速度

  • CRH寄存器

    作用:配置GPIOxPx8~Px15工作模式输出速度

  • IDR寄存器

  • ODR寄存器

  • BSRR寄存器

  • 4. 通用外设驱动模型

    1. 初始化:时钟设置、参数设置、IO设置(可选)、中断设置(可选)
    2. 读函数(可选):从外设读取数据
    3. 写函数(可选):往外设写入数据
    4. 中断服务函数(可选):根据中断标志,处理外设各种中断事物

    5. GPIO配置步骤

  • 配置步骤

    1. 使能时钟 __HAL_RCC_GPIOx_CLK_ENABLE()
    2. 设置工作模式 HAL_GPIO_Init()
    3. 设置输出状态(可选) HAL_GPIO_WritePin() HAL_GPIO_TogglePin()
    4. 读取输入状态 HAL_GPIO_ReadPin()
  • 相关HAL库函数

    HAL库驱动函数 主要寄存器 功能
    __HAL_RCC_GPIOx_CLK_ENABLE() F1:RCC_APB2ENR F4:RCC_AHB1ENR F7:RCC_AHB1ENR H7:RCC_AHB4ENR 开启GPIO时钟
    HAL_GPIO_Init(…) F1:CRL、CRH、ODR F4/F7/H7:MODER、OTYPER、OSPEEDR、PUPDR 初始化GPIO
    HAL_GPIO_WritePin(…) BSRR 控制IO输出高/低电平
    HAL_GPIO_TogglePin(…) BSRR 每次调用IO输出电平翻转一次
    HAL_GPIO_ReadPin(…) IDR 读取IO电平
  • 具体配置步骤,以GPIOA为例

    1. 使能时钟:__HAL_RCC_GPIOx_CLK_ENABLE()

      #define __HAL_RCC_GPIOA_CLK_ENABLE()   
      do { \
               __IO uint32_t tmpreg; \
               SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
                /* Delay after an RCC peripheral clock enabling */\
                tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);\
                UNUSED(tmpreg); \
               } while(0U)
      

      主要代码为SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN);,此代码第一个参数为APB2外设使能寄存器,第二个参数代表偏移量,使能这个寄存器的哪一位由这个偏移量来决定。使能GPIOA的时钟时,偏移量为2.

      #define RCC_APB2ENR_IOPAEN_Pos  (2U)                              
      #define RCC_APB2ENR_IOPAEN_Msk  (0x1UL << RCC_APB2ENR_IOPAEN_Pos)/*!< 0x00000004 */
      #define RCC_APB2ENR_IOPAEN      RCC_APB2ENR_IOPAEN_Msk /*!< I/O port A clock enable */
      
    2. 设置工作模式:HAL_GPIO_Init()

      void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
      {
        uint32_t position = 0x00u;
        uint32_t ioposition;
        uint32_t iocurrent;
        uint32_t temp;
        uint32_t config = 0x00u;
        __IO uint32_t *configregister; /* Store the address of CRL or CRH register based on pin number */
        uint32_t registeroffset;       /* offset used during computation of CNF and MODE bits placement inside CRL or CRH register */
      
        /* Check the parameters */
        assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
        assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
        assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
      
        /* Configure the port pins */
        while (((GPIO_Init->Pin) >> position) != 0x00u)
        {
          /* Get the IO position */
          ioposition = (0x01uL << position);
      
          /* Get the current IO position */
          iocurrent = (uint32_t)(GPIO_Init->Pin) & ioposition;
      
          if (iocurrent == ioposition)
          {
            /* Check the Alternate function parameters */
            assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
      
            /* Based on the required mode, filling config variable with MODEy[1:0] and CNFy[3:2] corresponding bits */
            switch (GPIO_Init->Mode)
            {
              /* If we are configuring the pin in OUTPUT push-pull mode */
              case GPIO_MODE_OUTPUT_PP:
                /* Check the GPIO speed parameter */
                assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
                config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_PP;
                break;
      
              /* If we are configuring the pin in OUTPUT open-drain mode */
              case GPIO_MODE_OUTPUT_OD:
                /* Check the GPIO speed parameter */
                assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
                config = GPIO_Init->Speed + GPIO_CR_CNF_GP_OUTPUT_OD;
                break;
      
              /* If we are configuring the pin in ALTERNATE FUNCTION push-pull mode */
              case GPIO_MODE_AF_PP:
                /* Check the GPIO speed parameter */
                assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
                config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_PP;
                break;
      
              /* If we are configuring the pin in ALTERNATE FUNCTION open-drain mode */
              case GPIO_MODE_AF_OD:
                /* Check the GPIO speed parameter */
                assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
                config = GPIO_Init->Speed + GPIO_CR_CNF_AF_OUTPUT_OD;
                break;
      
              /* If we are configuring the pin in INPUT (also applicable to EVENT and IT mode) */
              case GPIO_MODE_INPUT:
              case GPIO_MODE_IT_RISING:
              case GPIO_MODE_IT_FALLING:
              case GPIO_MODE_IT_RISING_FALLING:
              case GPIO_MODE_EVT_RISING:
              case GPIO_MODE_EVT_FALLING:
              case GPIO_MODE_EVT_RISING_FALLING:
                /* Check the GPIO pull parameter */
                assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
                if (GPIO_Init->Pull == GPIO_NOPULL)
                {
                  config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_FLOATING;
                }
                else if (GPIO_Init->Pull == GPIO_PULLUP)
                {
                  config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
      
                  /* Set the corresponding ODR bit */
                  GPIOx->BSRR = ioposition;
                }
                else /* GPIO_PULLDOWN */
                {
                  config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_INPUT_PU_PD;
      
                  /* Reset the corresponding ODR bit */
                  GPIOx->BRR = ioposition;
                }
                break;
      
              /* If we are configuring the pin in INPUT analog mode */
              case GPIO_MODE_ANALOG:
                config = GPIO_CR_MODE_INPUT + GPIO_CR_CNF_ANALOG;
                break;
      
              /* Parameters are checked with assert_param */
              default:
                break;
            }
      
            /* Check if the current bit belongs to first half or last half of the pin count number
             in order to address CRH or CRL register*/
            configregister = (iocurrent < GPIO_PIN_8) ? &GPIOx->CRL     : &GPIOx->CRH;
            registeroffset = (iocurrent < GPIO_PIN_8) ? (position << 2u) : ((position - 8u) << 2u);
      
            /* Apply the new configuration of the pin to the register */
            MODIFY_REG((*configregister), ((GPIO_CRL_MODE0 | GPIO_CRL_CNF0) << registeroffset), (config << registeroffset));
      
            /*--------------------- EXTI Mode Configuration ------------------------*/
            /* Configure the External Interrupt or event for the current IO */
            if ((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
            {
              /* Enable AFIO Clock */
              __HAL_RCC_AFIO_CLK_ENABLE();
              temp = AFIO->EXTICR[position >> 2u];
              CLEAR_BIT(temp, (0x0Fu) << (4u * (position & 0x03u)));
              SET_BIT(temp, (GPIO_GET_INDEX(GPIOx)) << (4u * (position & 0x03u)));
              AFIO->EXTICR[position >> 2u] = temp;
      
      
              /* Configure the interrupt mask */
              if ((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
              {
                SET_BIT(EXTI->IMR, iocurrent);
              }
              else
              {
                CLEAR_BIT(EXTI->IMR, iocurrent);
              }
      
              /* Configure the event mask */
              if ((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
              {
                SET_BIT(EXTI->EMR, iocurrent);
              }
              else
              {
                CLEAR_BIT(EXTI->EMR, iocurrent);
              }
      
              /* Enable or disable the rising trigger */
              if ((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
              {
                SET_BIT(EXTI->RTSR, iocurrent);
              }
              else
              {
                CLEAR_BIT(EXTI->RTSR, iocurrent);
              }
      
              /* Enable or disable the falling trigger */
              if ((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
              {
                SET_BIT(EXTI->FTSR, iocurrent);
              }
              else
              {
                CLEAR_BIT(EXTI->FTSR, iocurrent);
              }
            }
          }
      
      	position++;
        }
      }
      

      此函数有两个参数,都为结构体指针类型,第一个参数代表GPIO所使用的寄存器的基地址,第二个参数代表GPIO模式配置,GPIO相关寄存器上述已经详细描述各个寄存器代表的功能和用途,下面列出相关结构体定义。

      typedef struct
      {
        __IO uint32_t CRL;  //HAL_GPIO_Init()函数使用
        __IO uint32_t CRH;  //HAL_GPIO_Init()函数使用
        __IO uint32_t IDR;  //HAL_GPIO_ReadPin()函数使用
        __IO uint32_t ODR;  //HAL_GPIO_Init()函数使用
        __IO uint32_t BSRR; //HAL_GPIO_WritePin()和HAL_GPIO_TogglePin()函数使用
        __IO uint32_t BRR;  //一般情况下不使用
        __IO uint32_t LCKR; //一般情况下不使用
      } GPIO_TypeDef;
      

      下面介绍GPIO初始化配置结构体,里面包含四个成员变量,第一个成员变量为引脚号,第二个成员变量为模式设置,第三个成员变量为上拉下拉设置,第四个成员变量为速度设置,每一个成员变量的值都是固定的,不是任意设置的,都有相关的宏定义,下面一一介绍相关宏定义。

      typedef struct
      {
        uint32_t Pin;      //引脚号 
        uint32_t Mode;     //模式设置   
        uint32_t Pull;     //上拉下拉设置 
        uint32_t Speed;    //速度设置 
      } GPIO_InitTypeDef;
      

      引脚号取值范围:

      #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 */
      

      模式设置取值范围:

      #define  GPIO_MODE_INPUT               0x00000000u      //配合pull设置上拉下拉浮空输入
      #define  GPIO_MODE_OUTPUT_PP           0x00000001u      //推挽输出
      #define  GPIO_MODE_OUTPUT_OD           0x00000011u      //开漏输出
      #define  GPIO_MODE_AF_PP               0x00000002u      //复用推挽输出
      #define  GPIO_MODE_AF_OD               0x00000012u      //复用开漏输出
      #define  GPIO_MODE_AF_INPUT            GPIO_MODE_INPUT         
      
      #define  GPIO_MODE_ANALOG              0x00000003u      //模拟输入
      
      //以下为外部中断或外部事件模式
      #define  GPIO_MODE_IT_RISING           0x10110000u   
      #define  GPIO_MODE_IT_FALLING          0x10210000u   
      #define  GPIO_MODE_IT_RISING_FALLING   0x10310000u  
      
      #define  GPIO_MODE_EVT_RISING          0x10120000u   
      #define  GPIO_MODE_EVT_FALLING         0x10220000u   
      #define  GPIO_MODE_EVT_RISING_FALLING  0x10320000u   
      

      上拉下拉设置取值范围:

      #define  GPIO_NOPULL   0x00000000u   //浮空输入
      #define  GPIO_PULLUP   0x00000001u   //上拉输入
      #define  GPIO_PULLDOWN 0x00000002u   //下拉输入
      

      速度设置取值范围:

      #define  GPIO_SPEED_FREQ_LOW      (GPIO_CRL_MODE0_1) //低速
      #define  GPIO_SPEED_FREQ_MEDIUM   (GPIO_CRL_MODE0_0) //中速
      #define  GPIO_SPEED_FREQ_HIGH     (GPIO_CRL_MODE0)   //高速
      
    3. 设置输出状态: HAL_GPIO_WritePin() HAL_GPIO_TogglePin()

      HAL_GPIO_WritePin()函数有三个参数,第一个参数为上述所提的寄存器基地址,第二个参数为引脚号,第三个参数为要写入的值(GPIO状态:0或1).

      void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
      {
        /* Check the parameters */
        assert_param(IS_GPIO_PIN(GPIO_Pin));
        assert_param(IS_GPIO_PIN_ACTION(PinState));
      
        if (PinState != GPIO_PIN_RESET)
        {
          GPIOx->BSRR = GPIO_Pin;
        }
        else
        {
          GPIOx->BSRR = (uint32_t)GPIO_Pin << 16u;
        }
      }
      

      HAL_GPIO_TogglePin()函数有两个参数,第一个参数为上述所提的寄存器基地址,第二个参数为引脚号.

      void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
      {
        uint32_t odr;
      
        /* Check the parameters */
        assert_param(IS_GPIO_PIN(GPIO_Pin));
      
        /* get current Ouput Data Register value */
        odr = GPIOx->ODR;
      
        /* Set selected pins that were at low level, and reset ones that were high */
        GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
      }
      
    4. 读取输入状态: HAL_GPIO_ReadPin()

      HAL_GPIO_ReadPin()函数有两个参数,第一个参数为上述所提的寄存器基地址,第二个参数为引脚号.

      GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
      {
        GPIO_PinState bitstatus;
      
        /* Check the parameters */
        assert_param(IS_GPIO_PIN(GPIO_Pin));
      
        if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)GPIO_PIN_RESET)
        {
          bitstatus = GPIO_PIN_SET;
        }
        else
        {
          bitstatus = GPIO_PIN_RESET;
        }
        return bitstatus;
      }
      
  • 6. 点亮LED灯

  • 硬件连接图

    从硬件电路图可以看出,STM32F1开发板包含三个LED灯,一个蓝色的电源指示灯,一个红色,一个绿色。电源指示灯接地,上电后就会点亮。红灯和绿灯一端共阳,一端由PB5PE5控制,只要给PB5和PE5接低电平,LED0和LED1就会亮。

  • 代码配置步骤

    1. 使能时钟

      //使能时钟
      __HAL_RCC_GPIOB_CLK_ENABLE();
      
    2. 设置工作模式

      //配置工作模式
      GPIO_InitTypeDef gpio_init_struct;
      gpio_init_struct.Pin = GPIO_PIN_5;
      gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
      gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOB, &gpio_init_struct);
      
      //设置初始化状态
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
      
    3. 设置输出状态

      //点亮LED0
      HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);
      
  • 实验结果展示

  • 7. LED流水灯

  • 代码配置步骤

    1. 使能时钟

      //使能时钟
      __HAL_RCC_GPIOB_CLK_ENABLE();
      __HAL_RCC_GPIOE_CLK_ENABLE();
      
    2. 设置工作模式

      //配置工作模式
      //引脚设置为第五个引脚
      gpio_init_struct.Pin = GPIO_PIN_5;
      //推挽输出
      gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
      //低速模式
      gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
      //往结构体传值
      HAL_GPIO_Init(GPIOB, &gpio_init_struct);
      
      gpio_init_struct.Pin = GPIO_PIN_5;
      gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP;
      gpio_init_struct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOE, &gpio_init_struct);
      
      //设置初始化状态
      HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
      HAL_GPIO_WritePin(GPIOE, GPIO_PIN_5, GPIO_PIN_SET);	
      
    3. 设置输出状态

      //直接使用HAL_GPIO_TogglePin()函数进行翻转
      HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
      delay_ms(300);
      HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);
      delay_ms(300);
      
  • 实验结果展示

  • 8. 按键控制LED灯

  • 硬件连接图

    KEY_UP按键一端接的高电平,当检测到PA0为1时,代表按键按下。KEY0KEY1KEY2按键共地,当检测到PE4、PE3、PE2为0时,代表按键按下。

    执行按键操作时,需要使用软件消抖,就是通过延时跳过抖动的时间段,再判断IO输入电平。

  • 代码配置

    按键初始化函数

    void key_init(void)
    {
        GPIO_InitTypeDef gpio_init_struct;
        
        //使能时钟
        __HAL_RCC_GPIOE_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();
        
        //配置工作模式
        gpio_init_struct.Pin = GPIO_PIN_3;
        gpio_init_struct.Mode = GPIO_MODE_INPUT;
        //配置上拉输入
        gpio_init_struct.Pull = GPIO_PULLUP;
        HAL_GPIO_Init(GPIOE, &gpio_init_struct);
        
        //配置工作模式
        gpio_init_struct.Pin = GPIO_PIN_0;
        gpio_init_struct.Mode = GPIO_MODE_INPUT;
        //配置下拉输入
        gpio_init_struct.Pull = GPIO_PULLDOWN;
        HAL_GPIO_Init(GPIOA, &gpio_init_struct);
    }
    

    红色LED按键控制函数

    uint8_t key_scan_red_led(void)
    {
        if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == 0)
        {
            delay_ms(10);  //消抖
            if(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == 0)
            {
                while(HAL_GPIO_ReadPin(GPIOE, GPIO_PIN_3) == 0);  //等待按键松开
                return 1;   //按键按下返回
            }
        }
    
        return 0;
    }
    

    绿色LED按键控制函数

    uint8_t key_scan_green_led(void)
    {
        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 1)
        {
            delay_ms(10);  //消抖
            if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 1)
            {
                while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == 1);
                return 1;   //按键按下返回
            }
        }
        
        return 0;
    }
    

    主函数

    int main(void)
    {
        HAL_Init();                         /* 初始化HAL库 */
        sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
        delay_init(72);                     /* 延时初始化 */
        led_init();                         /* LED初始化 */
        key_init();
        
        while(1)
        {
            //判断控制红色LED的按键是否按下
            if (key_scan_red_led())
            {
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);   
                delay_ms(100);
                HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
            }
            //判断控制绿色LED的按键是否按下
            if(key_scan_green_led())
            {
                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);    
                delay_ms(100);
                HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);
            }
        }
    }
    
  • 实验结果展示

  • 声明:资料来源(战舰STM32F103ZET6开发板资源包)

    1. Cortex-M3权威指南(中文).pdf
    2. STM32F10xxx参考手册_V10(中文版).pdf
    3. STM32F103 战舰开发指南V1.3.pdf
    4. STM32F103ZET6(中文版).pdf
    5. 战舰V4 硬件参考手册_V1.0.pdf
    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 GPIO控制详解

    发表评论