stm32之GPIO函数详解和上机实验

news2025/4/25 10:51:39

目录

  • 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2342355.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

用 PyQt5 和 asyncio 打造接口并发测试 GUI 工具

接口并发测试是测试工程师日常工作中的重要一环&#xff0c;而一个直观的 GUI 工具能有效提升工作效率和体验。本篇文章将带你用 PyQt5 和 asyncio 从零实现一个美观且功能实用的接口并发测试工具。 我们将实现以下功能&#xff1a; 请求方法选择器 添加了一个下拉框 QComboBo…

Qt实战之将自定义插件(minGW)显示到Qt Creator列表的方法

Qt以其强大的跨平台特性和丰富的功能&#xff0c;成为众多开发者构建图形用户界面&#xff08;GUI&#xff09;应用程序的首选框架。而在Qt开发的过程中&#xff0c;自定义插件能够极大地拓展应用程序的功能边界&#xff0c;让开发者实现各种独特的、个性化的交互效果。想象一下…

【Vue】TypeScript与Vue3集成

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Vue 文章目录 1. 前言2. 环境准备与基础搭建2.1. 安装 Node.js 与 npm/yarn/pnpm2.2. 创建 Vue3 TypeScript 项目2.2.1. 使用 Vue CLI2.2.2. 使用 Vite&#xff08;推荐&#xff09;2.2.3. 目录结构简述 3. Vue3 TS 基础语法整…

Linux之七大难命令(The Seven Difficult Commands of Linux)

Linux之七大难命令 、背景 作为Linux的初学者&#xff0c;肯定要先掌握高频使用的指令&#xff0c;这样才能让Linux的学习在短时间内事半功倍。但是&#xff0c;有些指令虽然功能强大&#xff0c;但因参数多而让初学者们很害怕&#xff0c;今天介绍Linux中高频使用&#xff0…

5.3.1 MvvmLight以及CommunityToolkit.Mvvm介绍

MvvmLight、CommunityToolkit.Mvvm是开源包,他们为实现 MVVM(Model-View-ViewModel)模式提供了一系列实用的特性和工具,能帮助开发者更高效地构建 WPF、UWP、MAUI 等应用程序。 本文介绍如下: 一、使用(旧)的MvvmLight库 其特点如下,要继承的基类是ViewModelBase;且使用…

Dbeaver 执行 SQL 语句和执行 SQL 脚本的区别

执行 SQL 语句 执行 SQL 语句对应图标&#xff1a; 适用于执行单个 SQL 的情形&#xff0c;默认是在光标处或选中的文本上执行 SQL 查询。 实际上同时选择多个 SQL 并通过该方式去执行也可能成功&#xff0c;只是有失败的风险。因此不建议使用它来同时执行多个 SQL 语句。 情况…

《Python3网络爬虫开发实战(第二版)》配套案例 spa6

Scrape | Moviehttps://spa6.scrape.center/ 请求影片列表api时&#xff0c;不仅有分页参数&#xff0c;还多了一个token&#xff0c;通过重发请求发现token有时间限制&#xff0c;所以得逆向token的生成代码。 通过xhr断点定位到接口请求位置 刷新页面或者点翻页按钮&#x…

Python基础语法:字面量,注释,关键字,标识符,变量和引用,程序执行的3大流程

目录 字面量&#xff08;数据的类型&#xff09; 字面量的含义 常见字面量类型&#xff08;6种&#xff09; 输出各类字面量&#xff08;print语句&#xff09; 注释&#xff08;单行和多行注释&#xff09; 注释的作用 单行注释和多行注释 单行注释&#xff08;ctrl/&a…

SPL 量化 获取数据

下载数据 我们将股票数据分享在百度网盘上供下载&#xff0c;每工作日更新。 目前可供下载的数据有 A 股的日 K 线数据、股票代码列表和上市公司的基本面数据 下载链接&#xff1a; 百度网盘 下载数据的文件格式为 btx&#xff0c;是 SPL 的特有二进制格式。 btx 称为集文…

Rust 学习笔记:安装 Rust

Rust 学习笔记&#xff1a;安装 Rust Rust 学习笔记&#xff1a;安装 Rust在 Windows 上安装 Rust命令行创建 Rust 项目在 Mac/Linux 上安装 Rust一些命令升级卸载cargo -hrustc -h 安装 RustRoverrust-analyzer Rust 学习笔记&#xff1a;安装 Rust 在 Windows 上安装 Rust …

编译 C++ 报错“找不到 g++ 编译器”的终极解决方案(含 Windows/Linux/macOS)

前言 在使用终端编译 C 程序时&#xff0c;报错&#xff1a; 或类似提示&#xff0c;意味着你的系统尚未正确安装或配置 g 编译器。本篇将从零手把手教你在 Windows / Linux / macOS 下安装并配置 g&#xff0c;适用于新手或 C 入门阶段的你。 什么是 g&#xff1f; g 是 GN…

html单页业务介绍源码

源码介绍 html单页业务介绍源码&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行 效果预览 源码免费获取 html单页业务介绍源码

单体OJ项目

单体项目版本、微服务版还需我再钻研钻研。 项目介绍 在系统前台&#xff0c;管理员可以创建、管理题目;用户可以自由搜索题目、阅读题目、编写并提交代码。 在系统后端&#xff0c;能够根据管理员设定的题目测试用例在代码沙箱 中对代码进行编译、运行、判断输出是否正确。 其…

豆包桌面版 1.47.4 可做浏览器,免安装绿色版

自己动手升级更新办法&#xff1a; 下载新版本后安装&#xff0c;把 C:\Users\用户名\AppData\Local\Doubao\Application 文件夹的文件&#xff0c;拷贝替换 DoubaoPortable\App\Doubao 文件夹的文件&#xff0c;就升级成功了。 再把安装的豆包彻底卸载就可以。 桌面版比网页版…

【MySQL】索引失效问题详解

目录 1. 最左前缀原则 2. 条件左边有函数或运算 3. 隐式类型转换 4. LIKE 模糊查询以 % 开头 5、MySQL 优化器选择全表扫描 ⭐对 in 关键字特别说明⭐ &#xff08;1&#xff09;列表太大时&#xff0c;走全表扫描了 &#xff08;2&#xff09;隐式类型转换 &#xff…

优选算法第十讲:字符串

优选算法第十讲&#xff1a;字符串 1.最长公共前缀2.最长回文子串3.二进制求和4.字符串相乘 1.最长公共前缀 2.最长回文子串 3.二进制求和 4.字符串相乘

【扣子Coze 智能体案例四】五行八卦占卜智能体

目录 一、意图识别 二、时间格式转换 三、八字转换 四、八字提取 五、八字提取2 六、数据汇总 七、统计五行占比 八、雷达图生成 九、表格生成 十、AI占卜 十一、结束节点 一、意图识别 用户输入的信息包含各种时间格式的年月日时 用户输入的信息包含天干地支八字…

5.学习笔记-SpringMVC(P61-P70)

SpringMVC-SSM整合-接口测试 (1)业务层接口使用junit接口做测试 (2)表现层用postman做接口测试 (3)事务处理— 1&#xff09;在SpringConfig.java&#xff0c;开启注解&#xff0c;是事务驱动 2&#xff09;配置事务管理器&#xff08;因为事务管理器是要配置数据源对象&…

【专题刷题】二分查找(一):深度解刨二分思想和二分模板

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的基础算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

硬核解析!电动汽车能耗预测与续驶里程的关键技术研究

引言 随着电动汽车的普及,续航里程和能耗表现成为用户关注的核心痛点。然而,表显续航与实际续航的差异、低温环境下的电量衰减等问题始终困扰着消费者。本文基于《电动汽车能耗预测与续驶里程研究》的实验成果,深入剖析电动汽车能耗预测的核心模型、多环境测试方法及续航里…