当前位置: 首页 > news >正文

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速度,赋值为50MHzGPIO_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);										//延时500msGPIO_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速度,赋值为50MHzGPIO_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);				//延时100msGPIO_Write(GPIOA, ~0x0002);	//0000 0000 0000 0010,PA1引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0004);	//0000 0000 0000 0100,PA2引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0008);	//0000 0000 0000 1000,PA3引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0010);	//0000 0000 0001 0000,PA4引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0020);	//0000 0000 0010 0000,PA5引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_Write(GPIOA, ~0x0040);	//0000 0000 0100 0000,PA6引脚为低电平,其他引脚均为高电平Delay_ms(100);				//延时100msGPIO_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速度,赋值为50MHzGPIO_Init(GPIOB, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数//函数内部会自动根据结构体的参数配置相应寄存器//实现GPIOB的初始化/*主循环,循环体内的代码会一直循环执行*/while (1){GPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫Delay_ms(100);							//延时100msGPIO_SetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为高电平,蜂鸣器停止Delay_ms(100);							//延时100msGPIO_ResetBits(GPIOB, GPIO_Pin_12);		//将PB12引脚设置为低电平,蜂鸣器鸣叫Delay_ms(100);							//延时100msGPIO_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

相关文章:

  • AI PPT创作原理解析:让你的演示文稿更智能
  • vue3中slot(插槽)的详细使用
  • SpringBoot入门实战(第六篇:项目接口-登录)
  • 数据结构初阶:二叉树(四)
  • 使用Python求解泊松方程
  • 静态存储区(Static Storage Area)的总结
  • 从零手写 RPC-version1
  • docker在windows下wsl存储路径的变更与数据迁移
  • 区块链技术在物联网中的应用:构建可信的智能世界
  • 从白平衡色温坐标系调整的角度消除硬件不一致性引起的偏色问题
  • Godot学习-3D基本环境设置以及3D角色移动
  • 叶面温度传感器选清易高精度电热感应器 叶片温度变送器
  • OpenGL学习笔记(Blinn-Phong、伽马矫正、阴影)
  • 第一章:基于Docker环境快速搭建LangChain框架的智能对话系统:从langchain环境搭建到多轮对话代码实现(大语言模型加载)
  • 【专题刷题】滑动窗口(四):
  • 介绍 IntelliJ IDEA 快捷键操作
  • HCIP-OSPF综合实验
  • 通过智能分块策略、动态分块、多路召回与重排序融合、异构数据关联与溯源提升Ragflow与LangChain提升RAG的召回率
  • 【高频考点精讲】JavaScript中的访问者模式:从AST解析到数据转换的艺术
  • windos端远程控制ubuntu运行脚本程序并转发ubuntu端脚本输出的网页
  • 2025一季度,上海有两把刷子
  • 股市劝服马斯克
  • 魔都眼·上海车展③ |被外籍展商围观的国产品牌
  • 外贸50城,谁在“扛大旗”?
  • “从山顶到海洋”科技成果科普巡展在重庆启动,免费开放
  • 助力中国足球未来,香港赛马会鼎力支持U15国少选拔队赴英训练