STM32 GPIO函数详解与实战操作指南

目录

  • 1.LED和蜂鸣器
  • 1.1 LED
  • 1.2 蜂鸣器
  • 2.实验
  • 2.1 库函数:RCC和GPIO
  • 2.1.1 RCC函数
  • 1. `RCC_AHBPeriphClockCmd`
  • 2. `RCC_APB2PeriphClockCmd`
  • 3. `RCC_APB1PeriphClockCmd`
  • 2.1.2 GPIO函数
  • 1. `GPIO_DeInit`
  • 2. `GPIO_AFIODeInit`
  • 3. `GPIO_Init`
  • 4. `GPIO_StructInit`
  • 5. `GPIO_ReadInputDataBit`
  • 6. `GPIO_ReadInputData`
  • 7. `GPIO_ReadOutputDataBit`
  • 8. `GPIO_ReadOutputData`
  • 9. `GPIO_SetBits`
  • 10. `GPIO_ResetBits`
  • 11. `GPIO_WriteBit`
  • 12. `GPIO_Write`
  • 13. `GPIO_PinLockConfig`
  • 14. `GPIO_EventOutputConfig`
  • 15. `GPIO_EventOutputCmd`
  • 16. `GPIO_PinRemapConfig`
  • 17. `GPIO_EXTILineConfig`
  • 2.2 LED灯闪烁
  • 2.3 LED流水灯
  • 2.4 蜂鸣器
  • 2.5 按键控制LED
  • 2.5.1 电路接法
  • 2.5.2 编写
  • 2.6 光敏传感器控制器蜂鸣器
  • 2.6.1 传感器介绍
  • 2.6.2 电路接法
  • 2.6.3 编程
  • 3.OLED
  • 3.1 介绍
  • 3.2 API
  • 3.3 代码
  • img

    1.LED和蜂鸣器

    1.1 LED

    img

    或者长脚是正极、短脚是负极,led的电路接法可以两种,主要是看IO的高/低电平驱动能力去选择

    img

    上半是低电平驱动的电路,IO口处于推挽模式,当输出数据寄存器输出的是1时,上管P-MOS管导通,输出的是高电平,但由于LED外部(正极)接的是3.3V的电压,也就是此时LED两边电压差为0,因此不亮。那么输出低电平,产生电压差了,LED就亮了,所以是低电平去驱动的。

    下半则是高电平驱动的,其实是差不多的,就是负极接的GND,正极接的IO口,IO口输出高电平的时候才会亮。

    需要注意的是在连接的时候最好加一个保护电阻。

    1.2 蜂鸣器

    这个蜂鸣器是低电平触发的。

    img

    img

    使用的是三极管驱动电路来实现的,也有两种接法。

    对于上半,接的是一个PNP三极管,对于PNP三极管,当基极输出的是低电平的时候,三极管就导通,也就是3.3V的电压会经过蜂鸣器,就会发出声响

    对于下半,接的则是NPN三极管,当E接地的时候,B作为控制引脚,当B输出高电平,那么三极管就导通了,3.3V电压能顺利经过蜂鸣器,然后经过三极管到接地,发出声响。

    所以一样也是分为低电平驱动和高电平驱动两种方式,具体可根据实际情况去选择。

    2.实验

    2.1 库函数:RCC和GPIO

    主要涉及RCC和GPIO两个外设,所需要的库函数在Lidrary目录下的.h文件:📎stm32f10x_rcc.h、📎stm32f10x_gpio.h。文件的末尾一般都是该设备的相关函数

    2.1.1 RCC函数

    其中对于RCC(复位和时钟控制),负责管理各种时钟源和时钟分频,以及为各个外设提供时钟使能。其中最常用的就行下面三个函数:

    void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
    void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
    void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
    

    下面是函数的定义,官方给的注释是中文,个人按照自己的理解转换了一下:

    1. RCC_AHBPeriphClockCmd
    /**
      * @brief  启用或禁用 AHB 总线的外设时钟。
      * @param  RCC_AHBPeriph: 指定要控制其时钟的 AHB 外设。
      * 
      *   对于 STM32 的 Connectivity 版本设备,此参数可以是以下值的组合:
      *     @arg RCC_AHBPeriph_DMA1  // DMA1 控制器
      *     @arg RCC_AHBPeriph_DMA2  // DMA2 控制器
      *     @arg RCC_AHBPeriph_SRAM  // SRAM 存储器
      *     @arg RCC_AHBPeriph_FLITF // 闪存接口
      *     @arg RCC_AHBPeriph_CRC   // CRC 计算单元
      *     @arg RCC_AHBPeriph_OTG_FS // USB OTG 全速接口
      *     @arg RCC_AHBPeriph_ETH_MAC // 以太网 MAC 接口
      *     @arg RCC_AHBPeriph_ETH_MAC_Tx // 以太网 MAC 传输
      *     @arg RCC_AHBPeriph_ETH_MAC_Rx // 以太网 MAC 接收
      * 
      *   对于其他 STM32 设备,此参数可以是以下值的组合:
      *     @arg RCC_AHBPeriph_DMA1
      *     @arg RCC_AHBPeriph_DMA2
      *     @arg RCC_AHBPeriph_SRAM
      *     @arg RCC_AHBPeriph_FLITF
      *     @arg RCC_AHBPeriph_CRC
      *     @arg RCC_AHBPeriph_FSMC // 灵活静态存储控制器
      *     @arg RCC_AHBPeriph_SDIO // SDIO 接口
      *   
      * @note  SRAM 和 FLITF 时钟仅在睡眠模式下可以禁用。
      * @param  NewState: 指定外设时钟的新状态,可以是 ENABLE 或 DISABLE。
      * @retval 无
      */
    void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState)
    {
      /* 检查传入的参数是否合法 */
      assert_param(IS_RCC_AHB_PERIPH(RCC_AHBPeriph));
      assert_param(IS_FUNCTIONAL_STATE(NewState));
    
      if (NewState != DISABLE)  // 如果新状态为启用
      {
        /* 通过设置相应位启用外设的 AHB 时钟 */
        RCC->AHBENR |= RCC_AHBPeriph;
      }
      else  // 如果新状态为禁用
      {
        /* 通过清除相应位禁用外设的 AHB 时钟 */
        RCC->AHBENR &= ~RCC_AHBPeriph;
      }
    }
    
    2. RCC_APB2PeriphClockCmd
    /**
      * @brief  启用或禁用 APB2 高速总线的外设时钟。
      * @param  RCC_APB2Periph: 指定要控制其时钟的 APB2 外设。
      *   此参数可以是以下值的组合:
      *     @arg RCC_APB2Periph_AFIO // 外设功能 IO
      *     @arg RCC_APB2Periph_GPIOA, RCC_APB2Periph_GPIOB, RCC_APB2Periph_GPIOC, RCC_APB2Periph_GPIOD, RCC_APB2Periph_GPIOE,
      *     @arg RCC_APB2Periph_GPIOF, RCC_APB2Periph_GPIOG // GPIO 端口
      *     @arg RCC_APB2Periph_ADC1, RCC_APB2Periph_ADC2, RCC_APB2Periph_ADC3 // ADC 模数转换器
      *     @arg RCC_APB2Periph_TIM1, RCC_APB2Periph_TIM8, RCC_APB2Periph_TIM15, RCC_APB2Periph_TIM16, RCC_APB2Periph_TIM17,
      *          RCC_APB2Periph_TIM9, RCC_APB2Periph_TIM10, RCC_APB2Periph_TIM11 // 定时器
      *     @arg RCC_APB2Periph_SPI1 // SPI 接口
      *     @arg RCC_APB2Periph_USART1 // USART 接口
      * @param  NewState: 指定外设时钟的新状态,可以是 ENABLE 或 DISABLE。
      * @retval 无
      */
    void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
    {
      /* 检查传入的参数是否合法 */
      assert_param(IS_RCC_APB2_PERIPH(RCC_APB2Periph));
      assert_param(IS_FUNCTIONAL_STATE(NewState));
    
      if (NewState != DISABLE)  // 如果新状态为启用
      {
        /* 通过设置相应位启用外设的 APB2 时钟 */
        RCC->APB2ENR |= RCC_APB2Periph;
      }
      else  // 如果新状态为禁用
      {
        /* 通过清除相应位禁用外设的 APB2 时钟 */
        RCC->APB2ENR &= ~RCC_APB2Periph;
      }
    }
    
    3. RCC_APB1PeriphClockCmd
    /**
      * @brief  启用或禁用 APB1 低速总线的外设时钟。
      * @param  RCC_APB1Periph: 指定要控制其时钟的 APB1 外设。
      *   此参数可以是以下值的组合:
      *     @arg RCC_APB1Periph_TIM2, RCC_APB1Periph_TIM3, RCC_APB1Periph_TIM4, RCC_APB1Periph_TIM5,
      *          RCC_APB1Periph_TIM6, RCC_APB1Periph_TIM7 // 定时器
      *     @arg RCC_APB1Periph_WWDG // 窗口看门狗
      *     @arg RCC_APB1Periph_SPI2, RCC_APB1Periph_SPI3 // SPI 接口
      *     @arg RCC_APB1Periph_USART2, RCC_APB1Periph_USART3, RCC_APB1Periph_USART4, RCC_APB1Periph_USART5 // USART 接口
      *     @arg RCC_APB1Periph_I2C1, RCC_APB1Periph_I2C2 // I2C 接口
      *     @arg RCC_APB1Periph_USB // USB 接口
      *     @arg RCC_APB1Periph_CAN1 // CAN 接口
      *     @arg RCC_APB1Periph_BKP // 备份寄存器
      *     @arg RCC_APB1Periph_PWR // 电源管理
      *     @arg RCC_APB1Periph_DAC // 数模转换器
      *     @arg RCC_APB1Periph_CEC // 消费电子控制
      *     @arg RCC_APB1Periph_TIM12, RCC_APB1Periph_TIM13, RCC_APB1Periph_TIM14 // 定时器
      * @param  NewState: 指定外设时钟的新状态,可以是 ENABLE 或 DISABLE。
      * @retval 无
      */
    void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState)
    {
      /* 检查传入的参数是否合法 */
      assert_param(IS_RCC_APB1_PERIPH(RCC_APB1Periph));
      assert_param(IS_FUNCTIONAL_STATE(NewState));
    
      if (NewState != DISABLE)  // 如果新状态为启用
      {
        /* 通过设置相应位启用外设的 APB1 时钟 */
        RCC->APB1ENR |= RCC_APB1Periph;
      }
      else  // 如果新状态为禁用
      {
        /* 通过清除相应位禁用外设的 APB1 时钟 */
        RCC->APB1ENR &= ~RCC_APB1Periph;
      }
    }
    

    这些函数通过设置或清除寄存器中的位来控制不同外设的时钟,使能(启用)或失能(禁用)外设的时钟信号。根据所连接的设备去选择想要使用的时钟使能函数,这里只暂时介绍这三个。

    2.1.2 GPIO函数

    stm32f10x_gpio.h文件中给出了以下的函数声明:

    /**
      * @brief  Deinitializes the GPIOx peripheral registers to their default reset values.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @retval None
      */
    void GPIO_DeInit(GPIO_TypeDef* GPIOx);
    
    /**
      * @brief  Deinitializes the Alternate Functions (remap, event control
      *   and EXTI configuration) registers to their default reset values.
      * @param  None
      * @retval None
      */
    void GPIO_AFIODeInit(void);
    
    /**
      * @brief  Initializes the GPIOx peripheral according to the specified
      *         parameters in the GPIO_InitStruct.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_InitStruct: pointer to a GPIO_InitTypeDef structure that
      *         contains the configuration information for the specified GPIO peripheral.
      * @retval None
      */
    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
    
    /**
      * @brief  Fills each GPIO_InitStruct member with its default value.
      * @param  GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will
      *         be initialized.
      * @retval None
      */
    void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
    
    /**
      * @brief  Reads the specified input port pin.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin:  specifies the port bit to read.
      *   This parameter can be GPIO_Pin_x where x can be (0..15).
      * @retval The input port pin value.
      */
    uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    /**
      * @brief  Reads the specified GPIO input data port.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @retval GPIO input data port value.
      */
    uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
    
    /**
      * @brief  Reads the specified output data port bit.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin:  specifies the port bit to read.
      *   This parameter can be GPIO_Pin_x where x can be (0..15).
      * @retval The output port pin value.
      */
    uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    /**
      * @brief  Reads the specified GPIO output data port.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @retval GPIO output data port value.
      */
    uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
    
    /**
      * @brief  Sets the selected data port bits.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin: specifies the port bits to be written.
      *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
      * @retval None
      */
    void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    /**
      * @brief  Clears the selected data port bits.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin: specifies the port bits to be written.
      *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
      * @retval None
      */
    void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    /**
      * @brief  Sets or clears the selected data port bit.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin: specifies the port bit to be written.
      *   This parameter can be one of GPIO_Pin_x where x can be (0..15).
      * @param  BitVal: specifies the value to be written to the selected bit.
      *   This parameter can be one of the BitAction enum values:
      *     @arg Bit_RESET: to clear the port pin
      *     @arg Bit_SET: to set the port pin
      * @retval None
      */
    void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
    
    
    /**
      * @brief  Writes data to the specified GPIO data port.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  PortVal: specifies the value to be written to the port output data register.
      * @retval None
      */
    void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
    
    
    /**
      * @brief  Locks GPIO Pins configuration registers.
      * @param  GPIOx: where x can be (A..G) to select the GPIO peripheral.
      * @param  GPIO_Pin: specifies the port bit to be written.
      *   This parameter can be any combination of GPIO_Pin_x where x can be (0..15).
      * @retval None
      */
    void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
    /**
      * @brief  Selects the GPIO pin used as Event output.
      * @param  GPIO_PortSource: selects the GPIO port to be used as source
      *   for Event output.
      *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..E).
      * @param  GPIO_PinSource: specifies the pin for the Event output.
      *   This parameter can be GPIO_PinSourcex where x can be (0..15).
      * @retval None
      */
    void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    
    /**
      * @brief  Enables or disables the Event Output.
      * @param  NewState: new state of the Event output.
      *   This parameter can be: ENABLE or DISABLE.
      * @retval None
      */
    void GPIO_EventOutputCmd(FunctionalState NewState);
    
    /**
      * @brief  Changes the mapping of the specified pin.
      * @param  GPIO_Remap: selects the pin to remap.
      *   This parameter can be one of the following values:
      *     @arg GPIO_Remap_SPI1             : SPI1 Alternate Function mapping
      *     @arg GPIO_Remap_I2C1             : I2C1 Alternate Function mapping
      *     @arg GPIO_Remap_USART1           : USART1 Alternate Function mapping
      *     @arg GPIO_Remap_USART2           : USART2 Alternate Function mapping
      *     @arg GPIO_PartialRemap_USART3    : USART3 Partial Alternate Function mapping
      *     @arg GPIO_FullRemap_USART3       : USART3 Full Alternate Function mapping
      *     @arg GPIO_PartialRemap_TIM1      : TIM1 Partial Alternate Function mapping
      *     @arg GPIO_FullRemap_TIM1         : TIM1 Full Alternate Function mapping
      *     @arg GPIO_PartialRemap1_TIM2     : TIM2 Partial1 Alternate Function mapping
      *     @arg GPIO_PartialRemap2_TIM2     : TIM2 Partial2 Alternate Function mapping
      *     @arg GPIO_FullRemap_TIM2         : TIM2 Full Alternate Function mapping
      *     @arg GPIO_PartialRemap_TIM3      : TIM3 Partial Alternate Function mapping
      *     @arg GPIO_FullRemap_TIM3         : TIM3 Full Alternate Function mapping
      *     @arg GPIO_Remap_TIM4             : TIM4 Alternate Function mapping
      *     @arg GPIO_Remap1_CAN1            : CAN1 Alternate Function mapping
      *     @arg GPIO_Remap2_CAN1            : CAN1 Alternate Function mapping
      *     @arg GPIO_Remap_PD01             : PD01 Alternate Function mapping
      *     @arg GPIO_Remap_TIM5CH4_LSI      : LSI connected to TIM5 Channel4 input capture for calibration
      *     @arg GPIO_Remap_ADC1_ETRGINJ     : ADC1 External Trigger Injected Conversion remapping
      *     @arg GPIO_Remap_ADC1_ETRGREG     : ADC1 External Trigger Regular Conversion remapping
      *     @arg GPIO_Remap_ADC2_ETRGINJ     : ADC2 External Trigger Injected Conversion remapping
      *     @arg GPIO_Remap_ADC2_ETRGREG     : ADC2 External Trigger Regular Conversion remapping
      *     @arg GPIO_Remap_ETH              : Ethernet remapping (only for Connectivity line devices)
      *     @arg GPIO_Remap_CAN2             : CAN2 remapping (only for Connectivity line devices)
      *     @arg GPIO_Remap_SWJ_NoJTRST      : Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST
      *     @arg GPIO_Remap_SWJ_JTAGDisable  : JTAG-DP Disabled and SW-DP Enabled
      *     @arg GPIO_Remap_SWJ_Disable      : Full SWJ Disabled (JTAG-DP + SW-DP)
      *     @arg GPIO_Remap_SPI3             : SPI3/I2S3 Alternate Function mapping (only for Connectivity line devices)
      *                                        When the SPI3/I2S3 is remapped using this function, the SWJ is configured
      *                                        to Full SWJ Enabled (JTAG-DP + SW-DP) but without JTRST.   
      *     @arg GPIO_Remap_TIM2ITR1_PTP_SOF : Ethernet PTP output or USB OTG SOF (Start of Frame) connected
      *                                        to TIM2 Internal Trigger 1 for calibration (only for Connectivity line devices)
      *                                        If the GPIO_Remap_TIM2ITR1_PTP_SOF is enabled the TIM2 ITR1 is connected to 
      *                                        Ethernet PTP output. When Reset TIM2 ITR1 is connected to USB OTG SOF output.    
      *     @arg GPIO_Remap_PTP_PPS          : Ethernet MAC PPS_PTS output on PB05 (only for Connectivity line devices)
      *     @arg GPIO_Remap_TIM15            : TIM15 Alternate Function mapping (only for Value line devices)
      *     @arg GPIO_Remap_TIM16            : TIM16 Alternate Function mapping (only for Value line devices)
      *     @arg GPIO_Remap_TIM17            : TIM17 Alternate Function mapping (only for Value line devices)
      *     @arg GPIO_Remap_CEC              : CEC Alternate Function mapping (only for Value line devices)
      *     @arg GPIO_Remap_TIM1_DMA         : TIM1 DMA requests mapping (only for Value line devices)
      *     @arg GPIO_Remap_TIM9             : TIM9 Alternate Function mapping (only for XL-density devices)
      *     @arg GPIO_Remap_TIM10            : TIM10 Alternate Function mapping (only for XL-density devices)
      *     @arg GPIO_Remap_TIM11            : TIM11 Alternate Function mapping (only for XL-density devices)
      *     @arg GPIO_Remap_TIM13            : TIM13 Alternate Function mapping (only for High density Value line and XL-density devices)
      *     @arg GPIO_Remap_TIM14            : TIM14 Alternate Function mapping (only for High density Value line and XL-density devices)
      *     @arg GPIO_Remap_FSMC_NADV        : FSMC_NADV Alternate Function mapping (only for High density Value line and XL-density devices)
      *     @arg GPIO_Remap_TIM67_DAC_DMA    : TIM6/TIM7 and DAC DMA requests remapping (only for High density Value line devices)
      *     @arg GPIO_Remap_TIM12            : TIM12 Alternate Function mapping (only for High density Value line devices)
      *     @arg GPIO_Remap_MISC             : Miscellaneous Remap (DMA2 Channel5 Position and DAC Trigger remapping, 
      *                                        only for High density Value line devices)     
      * @param  NewState: new state of the port pin remapping.
      *   This parameter can be: ENABLE or DISABLE.
      * @retval None
      */
    void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
    
    /**
      * @brief  Selects the GPIO pin used as EXTI Line.
      * @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
      *   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
      * @param  GPIO_PinSource: specifies the EXTI line to be configured.
      *   This parameter can be GPIO_PinSourcex where x can be (0..15).
      * @retval None
      */
    void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    
    /**
      * @brief  Selects the Ethernet media interface.
      * @note   This function applies only to STM32 Connectivity line devices.  
      * @param  GPIO_ETH_MediaInterface: specifies the Media Interface mode.
      *   This parameter can be one of the following values:
      *     @arg GPIO_ETH_MediaInterface_MII: MII mode
      *     @arg GPIO_ETH_MediaInterface_RMII: RMII mode    
      * @retval None
      */
    void GPIO_ETH_MediaInterfaceConfig(uint32_t GPIO_ETH_MediaInterface);
    

    以下是这些 GPIO 函数的详细介绍以及如何使用它们的解释:

    1. GPIO_DeInit
    /**
      * @brief  将指定的 GPIO 外设寄存器恢复到默认的复位值。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @retval 无
      */
    void GPIO_DeInit(GPIO_TypeDef* GPIOx);
    
  • 功能:此函数将指定的 GPIO 外设寄存器恢复到它们的默认复位值。用于重置 GPIO 配置,恢复到未配置的状态。
  • 用法:如果要将 GPIOA 恢复到初始状态,调用 GPIO_DeInit(GPIOA);。这样,所有引脚都会复位,原来的配置会被清除。
  • 2. GPIO_AFIODeInit
    /**
      * @brief  将 Alternate Functions(包括重映射、事件控制和 EXTI 配置)寄存器恢复到默认复位值。
      * @param  无
      * @retval 无
      */
    void GPIO_AFIODeInit(void);
    
  • 功能:该函数将用于外设重映射、事件输出、EXTI 线路的 AFIO 配置恢复为默认复位状态。
  • 用法:在初始化新的 AFIO 设置之前可以调用,以确保配置干净。例如:GPIO_AFIODeInit();
  • 3. GPIO_Init
    /**
      * @brief  根据指定的配置结构体初始化 GPIO 外设。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_InitStruct: 指向 GPIO_InitTypeDef 结构体的指针,其中包含指定 GPIO 外设的配置信息。
      * @retval 无
      */
    void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
    
  • 功能:通过配置结构体 GPIO_InitStruct 对 GPIO 端口初始化,比如设置为输入、输出、上拉、下拉等模式。
  • 用法:首先创建 GPIO_InitTypeDef 结构体,设置结构体中的各项参数,然后调用此函数。例如:
  • GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    4. GPIO_StructInit
    /**
      * @brief  将 GPIO_InitStruct 结构体的每个成员填充为其默认值。
      * @param  GPIO_InitStruct: 指向将被初始化的 GPIO_InitTypeDef 结构体的指针。
      * @retval 无
      */
    void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
    
  • 功能:该函数会将 GPIO_InitTypeDef 结构体的成员填充为默认值,以确保结构体初始化时的干净状态。
  • 用法:可以调用 GPIO_StructInit(&GPIO_InitStruct); 将结构体的所有成员置为默认值,然后再配置特定的参数。
  • 5. GPIO_ReadInputDataBit
    /**
      * @brief  读取指定输入端口引脚的状态。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_Pin: 指定读取的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15)。
      * @retval 输入端口引脚的状态。
      */
    uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
  • 功能:该函数读取指定 GPIO 引脚的输入电平,可以用来检测引脚输入状态(高或低)。
  • 用法:调用 GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0); 获取 GPIOA 端口引脚 0 的电平状态。
  • 6. GPIO_ReadInputData
    /**
      * @brief  读取指定 GPIO 输入数据端口的值。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @retval GPIO 输入数据端口的值。
      */
    uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
    
  • 功能:读取整个 GPIO 端口的输入数据。
  • 用法:例如 GPIO_ReadInputData(GPIOA); 会返回 GPIOA 端口所有引脚的输入状态。
  • 7. GPIO_ReadOutputDataBit
    /**
      * @brief  读取指定输出端口引脚的状态。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_Pin: 指定读取的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15)。
      * @retval 输出端口引脚的状态。
      */
    uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
  • 功能:该函数用于读取 GPIO 输出引脚的当前输出状态。
  • 用法:例如 GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_0); 会返回 GPIOA 端口引脚 0 的输出状态。
  • 8. GPIO_ReadOutputData
    /**
      * @brief  读取指定 GPIO 输出数据端口的值。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @retval GPIO 输出数据端口的值。
      */
    uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
    
  • 功能:读取整个 GPIO 端口的输出数据。
  • 用法:例如 GPIO_ReadOutputData(GPIOA); 会返回 GPIOA 端口所有引脚的输出状态。
  • 9. GPIO_SetBits
    /**
      * @brief  设置指定的数据端口位。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_Pin: 指定要设置的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15) 的组合。
      * @retval 无
      */
    void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
  • 功能:该函数设置指定的 GPIO 引脚为高电平。
  • 用法:例如 GPIO_SetBits(GPIOA, GPIO_Pin_0); 将 GPIOA 引脚 0 设为高电平。
  • 10. GPIO_ResetBits
    /**
      * @brief  清除指定的数据端口位。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_Pin: 指定要清除的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15) 的组合。
      * @retval 无
      */
    void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
  • 功能:该函数清除指定的 GPIO 引脚为低电平。
  • 用法:例如 GPIO_ResetBits(GPIOA, GPIO_Pin_0); 将 GPIOA 引脚 0 设为低电平。
  • 11. GPIO_WriteBit
    /**
      * @brief  设置或清除选定的数据端口位。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  GPIO_Pin: 指定要写入的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15)。
      * @param  BitVal: 指定写入的值,可以是 Bit_RESET(低)或 Bit_SET(高)。
      * @retval 无
      */
    void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
    
  • 功能:根据 BitVal 设置或清除指定的引脚状态。
  • 用法:例如 GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET); 将 GPIOA 引脚 0 设置为高。
  • 12. GPIO_Write
    /**
      * @brief  向指定的 GPIO 数据端口写入数据。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设。
      * @param  PortVal: 要写入端口输出数据寄存器的值。
      * @retval 无
      */
    void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
    
  • 功能:向整个 GPIO 端口写入指定的数据值。
  • 用法:例如 GPIO_Write(GPIOA, 0xFFFF); 将 GPIOA 的所有引脚设为高电平。
  • 13. GPIO_PinLockConfig
    /**
      * @brief  锁定 GPIO 引脚配置寄存器。
      * @param  GPIOx: x 可以为 (A..G),用于选择 GPIO 外设
    
    。
      * @param  GPIO_Pin: 指定要锁定的端口位,可以是 GPIO_Pin_x,其中 x 为 (0..15) 的组合。
      * @retval 无
      */
    void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
    
  • 功能:锁定指定的 GPIO 引脚配置,防止后续更改。
  • 用法:调用 GPIO_PinLockConfig(GPIOA, GPIO_Pin_0); 锁定 GPIOA 引脚 0 的配置。
  • 14. GPIO_EventOutputConfig
    /**
      * @brief  配置 GPIO 事件输出。
      * @param  GPIO_PortSource: 选择事件输出端口源,可以是 GPIO_PortSourceGPIOx,其中 x 为 (A..G)。
      * @param  GPIO_PinSource: 选择事件输出引脚源,可以是 GPIO_PinSourcex,其中 x 为 (0..15)。
      * @retval 无
      */
    void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    
  • 功能:配置 GPIO 的事件输出源端口和引脚。事件输出允许在特定条件下触发事件,通常与中断结合使用。
  • 用法:例如 GPIO_EventOutputConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); 设置 GPIOA 的引脚 0 为事件输出。
  • 15. GPIO_EventOutputCmd
    /**
      * @brief  启用或禁用 GPIO 事件输出。
      * @param  NewState: 事件输出的新状态,可以是 ENABLE(启用)或 DISABLE(禁用)。
      * @retval 无
      */
    void GPIO_EventOutputCmd(FunctionalState NewState);
    
  • 功能:启用或禁用 GPIO 事件输出功能。
  • 用法:例如 GPIO_EventOutputCmd(ENABLE); 启用事件输出,或 GPIO_EventOutputCmd(DISABLE); 禁用事件输出。
  • 16. GPIO_PinRemapConfig
    /**
      * @brief  改变指定引脚的映射配置。
      * @param  GPIO_Remap: 选择要重新映射的引脚。
      *   此参数可以是以下值之一:
      *     @arg GPIO_Remap_SPI1             : SPI1 引脚的备用功能映射
      *     @arg GPIO_Remap_I2C1             : I2C1 引脚的备用功能映射
      *     @arg GPIO_Remap_USART1           : USART1 引脚的备用功能映射
      *     @arg GPIO_Remap_USART2           : USART2 引脚的备用功能映射
      *     @arg GPIO_PartialRemap_USART3    : USART3 部分备用功能映射
      *     @arg GPIO_FullRemap_USART3       : USART3 完全备用功能映射
      *     @arg GPIO_PartialRemap_TIM1      : TIM1 部分备用功能映射
      *     @arg GPIO_FullRemap_TIM1         : TIM1 完全备用功能映射
      *     @arg GPIO_PartialRemap1_TIM2     : TIM2 部分1备用功能映射
      *     @arg GPIO_PartialRemap2_TIM2     : TIM2 部分2备用功能映射
      *     @arg GPIO_FullRemap_TIM2         : TIM2 完全备用功能映射
      *     @arg GPIO_PartialRemap_TIM3      : TIM3 部分备用功能映射
      *     @arg GPIO_FullRemap_TIM3         : TIM3 完全备用功能映射
      *     @arg GPIO_Remap_TIM4             : TIM4 备用功能映射
      *     @arg GPIO_Remap1_CAN1            : CAN1 备用功能映射1
      *     @arg GPIO_Remap2_CAN1            : CAN1 备用功能映射2
      *     @arg GPIO_Remap_PD01             : PD01 备用功能映射
      *     @arg GPIO_Remap_TIM5CH4_LSI      : LSI 连接到 TIM5 通道4输入捕获用于校准
      *     @arg GPIO_Remap_ADC1_ETRGINJ     : ADC1 外部触发注入转换映射
      *     @arg GPIO_Remap_ADC1_ETRGREG     : ADC1 外部触发常规转换映射
      *     @arg GPIO_Remap_ADC2_ETRGINJ     : ADC2 外部触发注入转换映射
      *     @arg GPIO_Remap_ADC2_ETRGREG     : ADC2 外部触发常规转换映射
      *     @arg GPIO_Remap_ETH              : 以太网映射(仅适用于 Connectivity 系列设备)
      *     @arg GPIO_Remap_CAN2             : CAN2 映射(仅适用于 Connectivity 系列设备)
      *     @arg GPIO_Remap_SWJ_NoJTRST      : 全 SWJ(启用 JTAG-DP 和 SW-DP,但不包含 JTRST)
      *     @arg GPIO_Remap_SWJ_JTAGDisable  : 禁用 JTAG-DP,启用 SW-DP
      *     @arg GPIO_Remap_SWJ_Disable      : 禁用全 SWJ(禁用 JTAG-DP 和 SW-DP)
      *     @arg GPIO_Remap_SPI3             : SPI3/I2S3 备用功能映射(仅适用于 Connectivity 系列设备)
      *                                        当 SPI3/I2S3 使用此函数重新映射时,SWJ 配置为全 SWJ 启用但不包含 JTRST。
      *     @arg GPIO_Remap_TIM2ITR1_PTP_SOF : 以太网 PTP 输出或 USB OTG SOF(帧起始)连接到 TIM2 内部触发 1 用于校准(仅适用于 Connectivity 系列设备)
      *                                        启用 GPIO_Remap_TIM2ITR1_PTP_SOF 时,TIM2 ITR1 连接到以太网 PTP 输出;重置时 TIM2 ITR1 连接到 USB OTG SOF 输出。
      *     @arg GPIO_Remap_PTP_PPS          : 以太网 MAC PPS_PTS 输出连接到 PB05(仅适用于 Connectivity 系列设备)
      *     @arg GPIO_Remap_TIM15            : TIM15 备用功能映射(仅适用于 Value 系列设备)
      *     @arg GPIO_Remap_TIM16            : TIM16 备用功能映射(仅适用于 Value 系列设备)
      *     @arg GPIO_Remap_TIM17            : TIM17 备用功能映射(仅适用于 Value 系列设备)
      *     @arg GPIO_Remap_CEC              : CEC 备用功能映射(仅适用于 Value 系列设备)
      *     @arg GPIO_Remap_TIM1_DMA         : TIM1 DMA 请求映射(仅适用于 Value 系列设备)
      *     @arg GPIO_Remap_TIM9             : TIM9 备用功能映射(仅适用于 XL-density 系列设备)
      *     @arg GPIO_Remap_TIM10            : TIM10 备用功能映射(仅适用于 XL-density 系列设备)
      *     @arg GPIO_Remap_TIM11            : TIM11 备用功能映射(仅适用于 XL-density 系列设备)
      *     @arg GPIO_Remap_TIM13            : TIM13 备用功能映射(仅适用于 High density Value 系列和 XL-density 系列设备)
      *     @arg GPIO_Remap_TIM14            : TIM14 备用功能映射(仅适用于 High density Value 系列和 XL-density 系列设备)
      *     @arg GPIO_Remap_FSMC_NADV        : FSMC_NADV 备用功能映射(仅适用于 High density Value 系列和 XL-density 系列设备)
      *     @arg GPIO_Remap_TIM67_DAC_DMA    : TIM6/TIM7 和 DAC DMA 请求映射(仅适用于 High density Value 系列设备)
      *     @arg GPIO_Remap_TIM12            : TIM12 备用功能映射(仅适用于 High density Value 系列设备)
      *     @arg GPIO_Remap_MISC             : 其他映射(DMA2 通道5位置和 DAC 触发映射,仅适用于 High density Value 系列设备)     
      * @param  NewState: 引脚映射的新状态。
      *   此参数可以是:ENABLE 或 DISABLE。
      * @retval 无
      */
    void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
    
  • 功能:配置 GPIO 的引脚重映射,将引脚的默认功能重新分配到其他引脚上。这在某些特殊的硬件需求下非常有用。
  • 用法:例如 GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE); 将 USART1 的默认引脚重映射到指定引脚上。
  • 17. GPIO_EXTILineConfig
    /**
      * @brief  选择 GPIO 引脚作为外部中断线路的输入。
      * @param  GPIO_PortSource: 选择要配置的端口源,可以是 GPIO_PortSourceGPIOx。
      * @param  GPIO_PinSource: 选择外部中断的引脚源,可以是 GPIO_PinSourcex。
      * @retval 无
      */
    void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource);
    
  • 功能:选择 GPIO 引脚来作为外部中断(EXTI)线路的输入源,使得引脚事件可以触发中断。
  • 用法:例如 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); 将 GPIOA 的引脚 0 配置为外部中断线路的输入源。
  • 2.2 LED灯闪烁

    📎3-1 LED闪烁.zip

    img

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    
    int main(void)
    {
    	/*开启时钟*/
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
    															//使用各个外设前必须开启时钟,否则对外设的操作无效
    	
    	/*GPIO初始化*/
    	GPIO_InitTypeDef GPIO_InitStructure;				
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//GPIO引脚,赋值为第0号引脚
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
    	
    	GPIO_Init(GPIOA, &GPIO_InitStructure);						
    															
    	
    	/*主循环,循环体内的代码会一直循环执行*/
    	while (1)
    	{
    		/*设置PA0引脚的高低电平,实现LED闪烁,下面展示3种方法*/
    		
    		// /*方法1:GPIO_ResetBits设置低电平,GPIO_SetBits设置高电平*/
    		// GPIO_ResetBits(GPIOA, GPIO_Pin_0);					//将PA0引脚设置为低电平
    		// Delay_ms(500);										//延时500ms
    		// GPIO_SetBits(GPIOA, GPIO_Pin_0);					//将PA0引脚设置为高电平
    		// Delay_ms(500);										//延时500ms
    		
    		/*方法2:GPIO_WriteBit设置低/高电平,由Bit_RESET/Bit_SET指定*/
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);		//将PA0引脚设置为低电平
    		Delay_ms(500);										//延时500ms
    		GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);			//将PA0引脚设置为高电平
    		Delay_ms(500);										//延时500ms
    		
    		// /*方法3:GPIO_WriteBit设置低/高电平,由数据0/1指定,数据需要强转为BitAction类型*/
    		// GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);		//将PA0引脚设置为低电平
    		// Delay_ms(500);										//延时500ms
    		// GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);		//将PA0引脚设置为高电平
    		// Delay_ms(500);										//延时500ms
    	}
    }
    

    大概就是使能APB2总线的RCC时钟,这个GPIOA模块是挂载在APB2总线上的,其有16个端口,要选择哪个gpio引脚、哪种工作模式、速率是根据构造GPIO_InitStructure结构体来决定

    typedef struct
    {
      uint16_t GPIO_Pin;             /*!< 指定要配置的GPIO引脚。
                                          此参数可以是@ref GPl0 pins define的任意值 */
    
      GPIOSpeed_TypeDef GPIO_Speed;  /*!< 指定所选引脚的速度
                                          此参数可以是@refGPl0Speed_TypeDef的值 */
    
      GPIOMode_TypeDef GPIO_Mode;    /*!< 指定所选引脚的操作模式。
                                          此参数可以是@ref GPI0Mode_TypeDef的值 */
    }GPIO_InitTypeDef;
    

    其中对于GPIOMode_TypeDef GPIO_Mode就有8种工作模式,之前也有提到过:

    typedef enum
    { 
        GPIO_Mode_AIN = 0x0,           // 模拟输入模式
        GPIO_Mode_IN_FLOATING = 0x04,  // 浮空输入模式
        GPIO_Mode_IPD = 0x28,          // 下拉输入模式
        GPIO_Mode_IPU = 0x48,          // 上拉输入模式
        GPIO_Mode_Out_OD = 0x14,       // 开漏输出模式
        GPIO_Mode_Out_PP = 0x10,       // 推挽输出模式
        GPIO_Mode_AF_OD = 0x1C,        // 开漏复用输出模式
        GPIO_Mode_AF_PP = 0x18         // 推挽复用输出模式
        } GPIOMode_TypeDef;
    

    下面是江科大资料提供的接线图:

    img

    需要注意的是低电平来驱动led亮的,因为led是连接着从板子导通出来的电源的:也就是LED引脚的正极(连接着Vdd)和负极(IO口)需要有电压差才能亮。

    img

    这个工程还需要添加一个System的文件夹(自己随便取名也行)来存放延迟所需要的相关函数:📎Delay.h📎Delay.c

    2.3 LED流水灯

    📎3-2 LED流水灯.zip

    img

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    
    int main(void)
    {
    	/*开启时钟*/
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
    															//使用各个外设前必须开启时钟,否则对外设的操作无效
    	
    	/*GPIO初始化*/
    	GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;				//GPIO引脚,赋值为所有引脚
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
    	
    	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数
    															//函数内部会自动根据结构体的参数配置相应寄存器
    															//实现GPIOA的初始化
    	
    	/*主循环,循环体内的代码会一直循环执行*/
    	while (1)
    	{
    		/*使用GPIO_Write,同时设置GPIOA所有引脚的高低电平,实现LED流水灯*/
    		GPIO_Write(GPIOA, ~0x0001);	//0000 0000 0000 0001,PA0引脚为低电平,其他引脚均为高电平,注意数据有按位取反
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010,PA1引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100,PA2引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000,PA3引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000,PA4引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000,PA5引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000,PA6引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    		GPIO_Write(GPIOA, ~0x0080);	//0000 0000 1000 0000,PA7引脚为低电平,其他引脚均为高电平
    		Delay_ms(100);				//延时100ms
    	}
    }
    

    2.4 蜂鸣器

    📎3-3 蜂鸣器.zip

    img

    #include "stm32f10x.h"                  // Device header
    #include "Delay.h"
    
    int main(void)
    {
    	/*开启时钟*/
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	//开启GPIOB的时钟
    															//使用各个外设前必须开启时钟,否则对外设的操作无效
    	
    	/*GPIO初始化*/
    	GPIO_InitTypeDef GPIO_InitStructure;					//定义结构体变量
    	
    	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		//GPIO模式,赋值为推挽输出模式
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;				//GPIO引脚,赋值为第12号引脚
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
    	
    	GPIO_Init(GPIOB, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数
    															//函数内部会自动根据结构体的参数配置相应寄存器
    															//实现GPIOB的初始化
    	
    	/*主循环,循环体内的代码会一直循环执行*/
    	while (1)
    	{
    		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫
    		Delay_ms(100);							//延时100ms
    		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止
    		Delay_ms(100);							//延时100ms
    		GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫
    		Delay_ms(100);							//延时100ms
    		GPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止
    		Delay_ms(700);							//延时700ms
    	}
    }
    

    2.5 按键控制LED

    按键:常见的输入设备,按下导通,松手断开

    按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动(在这个实验中使用延迟手段进行解决)

    img

    2.5.1 电路接法

    img

    对于左上角的接法,要求输入模式是上拉模式,当按下按钮的时候,接地,也就是PA0输入的是低电平,当松开的时候PA0断开,引脚处于悬浮的状态,无法确定高低电平,这样是不行的,因此得设置为上拉输入模式,保证悬浮的时候默认是高电平。

    对于右上角,则是接了一个上拉的电阻,这样在按下按钮的时候,接地,也就是分走了所有的电压,这就使得PA0输入的是低电平;当松开按钮的时候,由于上拉电阻的作用,将PA0拔高,也就是输入的高电平。这两种情况下引脚不会出现悬空的状态。对于这种接法引脚的输入模式可以设置为浮空状态。

    img

    2.5.2 编写

    Hardware:

  • 📎LED.c
  • 📎LED.h
  • 📎Key.c
  • 📎Key.h
  • User:

  • 📎main.c
  • System:

  • 📎Delay.h
  • 📎Delay.c
  • 2.6 光敏传感器控制器蜂鸣器

    2.6.1 传感器介绍

    传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出

    下图从左到右分别是:光敏电阻传感器、热敏电阻传感器、对射式红外传感器、反射式红外传感器

    img

    img

    以上图第3个电路为例子,它是模块的内部电路,也就是第5个电路图P1内部有关AO口输出的内部实现。对于该电路的电容在分析的时候可以屏蔽掉,它就个滤波电容,用来保证电路的稳定。

    剩下的则是两个电阻了,对于接着Vcc的是定值电阻,对于接着GND的则是传感电阻,这两个其实就形成了上拉电阻和下拉电阻。

    只不过对于下拉电阻比较特殊,在整个电路是起着分压的作用,也就是说当传感电阻阻值下降的时候,下拉电阻分到的电压就更多,对于AO口处的电压越小,即会输出低电平,在极端的情况下传感电阻阻值为0,电流完全流入GND(下拉分走了所有的电压),AO输出的电压就为0了。反过来,极端情况下传感电阻阻值为无穷大,也就是下拉处的电路断路了,那么这时候由于上拉电阻的作用,会将AO口的电压拔高(AO口分走了所有的电压),也就是输出高电平了。

    简单点就是:当传感电阻阻值下降时,下拉作用增强,AO口输出低电平;阻值上升时,下拉作用减弱,这时候由于上拉起作用,AO口就是高电平。当上拉下拉旗鼓相当的时候,AO就差不多是Vcc/2的电压。

    上拉/下拉在电路中是很常见的,其中就有弱上拉/下拉、强上拉/下拉,这里的强和弱就是指阻值的大小。


    同时对于传感器还支持二值化的输出,也就是数字信号的输出,主要是P1口的DO引脚,内部是第一个电路图中的U1 LM393芯片的实现:

    img

    主要是靠运算放大器,当IN-(倒向输入端)是大于IN+(非倒向输入端)的时候,也就是Ud<0,此时输出端DO就会瞬间升为最小值,反过来就则是升为最大值,从而实现对模拟电压进行二值化处理,使得输入的是模拟电压,输出的(DO)的是数字电压。

    img

    而P1处的DO口还接着一个LED,就是用来指示DO口输出的高电平还是低电平,而接着VCC的R5则是为了保证DO默认输出的是高电平。

    2.6.2 电路接法

    img

    img

    2.6.3 编程

    Hardware:

  • 📎LightSensor.h
  • 📎LightSensor.c
  • 📎Buzzer.h
  • 📎Buzzer.c
  • User:

  • 📎main.c
  • System:

  • 📎Delay.h
  • 📎Delay.c
  • 3.OLED

    3.1 介绍

    串口调试:通过串口通信,将调试信息发送到电脑端,电脑使用串口助手显示调试信息

    显示屏调试:直接将显示屏连接到单片机,将调试信息打印在显示屏上

    Keil调试模式:借助Keil软件的调试模式,可使用单步运行、设置断点、查看寄存器及变量等功能


    OLED(Organic Light Emitting Diode):有机发光二极管

    OLED显示屏:性能优异的新型显示屏,具有功耗低、相应速度快、宽视角、轻薄柔韧等特点

    0.96寸OLED模块:小巧玲珑、占用接口少、简单易用,是电子设计中非常常见的显示屏模块

    供电:3~5.5V,通信协议:I2C/SPI,分辨率:128*64

    img


    img

    3.2 API

    函数设计如下,需要用到的时候导入工程就行了:

    📎7针脚SPI版本.zip

    📎4针脚I2C版本.zip

    函数 作用
    OLED_Init(); 初始化
    OLED_Clear(); 清屏
    OLED_ShowChar(1, 1, ‘A’); 显示一个字符
    OLED_ShowString(1, 3, “HelloWorld!”); 显示字符串
    OLED_ShowNum(2, 1, 12345, 5); 显示十进制数字
    OLED_ShowSignedNum(2, 7, -66, 2); 显示有符号十进制数字
    OLED_ShowHexNum(3, 1, 0xAA55, 4); 显示十六进制数字
    OLED_ShowBinNum(4, 1, 0xAA55, 16); 显示二进制数字

    img

    3.3 代码

    📎4-1 OLED显示屏.zip

    Hardware:

  • 📎OLED_Font.h
  • 📎Key.c
  • 📎Key.h
  • 📎LED.c
  • 📎LED.h
  • 📎OLED.c
  • 📎OLED.h
  • User:

  • 📎main.c
  • 作者:憧憬一下

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32 GPIO函数详解与实战操作指南

    发表回复