STM32-06-STM32_GPIO

这篇具有很好参考价值的文章主要介绍了STM32-06-STM32_GPIO。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

STM32 GPIO

1. GPIO简介

  • 什么是GPIO?

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

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

    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

    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. 浮空输入
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  2. 上拉输入
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  3. 下拉输入
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  4. 模拟输入
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  5. 开漏输出
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  6. 复用开漏输出
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  7. 推挽输出
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  8. 复用推挽输出
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

3. GPIO相关寄存器

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

作用:配置GPIOxPx0~Px7工作模式输出速度
STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • CRH寄存器

    作用:配置GPIOxPx8~Px15工作模式输出速度
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • IDR寄存器
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • ODR寄存器

    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • BSRR寄存器
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

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就会亮。
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • 代码配置步骤

    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);
      
  • 实验结果展示
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

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时,代表按键按下。
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

    执行按键操作时,需要使用软件消抖,就是通过延时跳过抖动的时间段,再判断IO输入电平。
    STM32-06-STM32_GPIO,嵌入式,stm32,嵌入式硬件,单片机

  • 代码配置

    按键初始化函数

    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开发板资源包)文章来源地址https://www.toymoban.com/news/detail-788254.html

  1. Cortex-M3权威指南(中文).pdf
  2. STM32F10xxx参考手册_V10(中文版).pdf
  3. STM32F103 战舰开发指南V1.3.pdf
  4. STM32F103ZET6(中文版).pdf
  5. 战舰V4 硬件参考手册_V1.0.pdf

到了这里,关于STM32-06-STM32_GPIO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式硬件——stm32F103C8T6

    如下图:    处理器核心:STM32F103C8T6内置了ARM Cortex-M3处理器,这是一种高性能、低功耗的32位RISC处理器,适用于嵌入式系统。 时钟速度:它可以工作在不同的时钟速度,最高主频可达72 MHz。 存储器:包括64KB的Flash程序存储器用于存储程序代码,以及20KB的SRAM用于存储数据和

    2024年02月05日
    浏览(59)
  • 嵌入式毕设分享 stm32人脸识别快递柜系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年04月10日
    浏览(67)
  • 嵌入式毕设分享 stm32 RFID智能仓库管理系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(67)
  • 嵌入式毕设分享 stm32智能鱼缸监控投喂系统(源码+硬件+论文)

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年03月17日
    浏览(73)
  • 【嵌入式学习笔记】嵌入式基础9——STM32启动过程

    程序段交叉引用关系(Section Cross References):描述各文件之间函数调用关系 删除映像未使用的程序段(Removing Unused input sections from the image):描述工程中未用到被删除的冗余程序段(函数/数据) 映像符号表(Image Symbol Table):描述各符号(程序段/数据)在存储器中的地址、类

    2024年02月15日
    浏览(81)
  • stm32嵌入式实验考核

    STM32 实验考核题目 1. 利用 STM32 小板实现:控制外接 LED 灯每隔 3 秒钟亮暗变换,同 时在 PC 机上显示 MCU 的计时时间,MCU 的初始时间由 PC 机 方设置。 2. 利用 STM32 小板实现:利用导线外接 GPIO 口模拟 2 个按键输入, 根据输入组合的四种情况,分别控制三色灯四种流水灯效果

    2024年02月03日
    浏览(48)
  • STM32串口通信详解(嵌入式学习)

    时钟信号在电子领域中是指用于同步和定时电路操作的周期性信号。它在数字系统和通信系统中起着至关重要的作用,用于协调各个组件之间的数据传输和操作。 时钟信号有以下几个重要的方面: 频率:时钟信号的频率是指单位时间内信号周期的数量。它通常以赫兹(Hz)为

    2024年02月09日
    浏览(67)
  • STM32的时钟系统(嵌入式学习)

    时钟是指用于计量和同步时间的装置或系统。时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,例如:串口数据的发送、AD转换、定时器计数等。因此时钟对于计算机系统是至关重要的,通常时钟系

    2024年02月16日
    浏览(47)
  • 嵌入式 STM32 通讯协议--MODBUS

    目录 一、自定义通信协议 1、协议介绍 2、网络协议 3、自定义的通信协议  二、MODBUS通信协议 1、概述 2、MODBUS帧结构  协议描述 3、MODBUS数据模型   4、MODBUS事务处理的定义 5、MODBUS功能码  6、功能码定义   7、MODBUS数据链路层 8、MODBUS地址规则  9、MODBUS帧描述 10、MODBUS两种

    2024年02月11日
    浏览(62)
  • 嵌入式——新建STM32工程(标准库)

    目录 一、初识标准库 1.CMSIS标准及库层级关系 2.库文件介绍 (1)Libraries文件夹 ①CMSIS文件夹 ②STM32F10x_Std_Periph_Driver文件夹 ③ 在用库建立一个完整的工程时,还需要添加stm32f10x_it.c、 stm32f10x_conf.h 和 system_stm32f10x.c文件 (2)Project文件夹 (3)Utilities文件夹 3.库各文件之间的关

    2024年01月23日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包