目录
- 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 代码
1.LED和蜂鸣器
1.1 LED
或者长脚是正极、短脚是负极,led的电路接法可以两种,主要是看IO的高/低电平驱动能力去选择
上半是低电平驱动的电路,IO口处于推挽模式,当输出数据寄存器输出的是1时,上管P-MOS管导通,输出的是高电平,但由于LED外部(正极)接的是3.3V的电压,也就是此时LED两边电压差为0,因此不亮。那么输出低电平,产生电压差了,LED就亮了,所以是低电平去驱动的。
下半则是高电平驱动的,其实是差不多的,就是负极接的GND,正极接的IO口,IO口输出高电平的时候才会亮。
需要注意的是在连接的时候最好加一个保护电阻。
1.2 蜂鸣器
这个蜂鸣器是低电平触发的。
使用的是三极管驱动电路来实现的,也有两种接法。
对于上半,接的是一个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
#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;
下面是江科大资料提供的接线图:
需要注意的是低电平来驱动led亮的,因为led是连接着从板子导通出来的电源的:也就是LED引脚的正极(连接着Vdd)和负极(IO口)需要有电压差才能亮。
这个工程还需要添加一个System的文件夹(自己随便取名也行)来存放延迟所需要的相关函数:📎Delay.h📎Delay.c
2.3 LED流水灯
📎3-2 LED流水灯.zip
#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
#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
按键:常见的输入设备,按下导通,松手断开
按键抖动:由于按键内部使用的是机械式弹簧片来进行通断的,所以在按下和松手的瞬间会伴随有一连串的抖动(在这个实验中使用延迟手段进行解决)
2.5.1 电路接法
对于左上角的接法,要求输入模式是上拉模式,当按下按钮的时候,接地,也就是PA0输入的是低电平,当松开的时候PA0断开,引脚处于悬浮的状态,无法确定高低电平,这样是不行的,因此得设置为上拉输入模式,保证悬浮的时候默认是高电平。
对于右上角,则是接了一个上拉的电阻,这样在按下按钮的时候,接地,也就是分走了所有的电压,这就使得PA0输入的是低电平;当松开按钮的时候,由于上拉电阻的作用,将PA0拔高,也就是输入的高电平。这两种情况下引脚不会出现悬空的状态。对于这种接法引脚的输入模式可以设置为浮空状态。
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 传感器介绍
传感器模块:传感器元件(光敏电阻/热敏电阻/红外接收管等)的电阻会随外界模拟量的变化而变化,通过与定值电阻分压即可得到模拟电压输出,再通过电压比较器进行二值化即可得到数字电压输出
下图从左到右分别是:光敏电阻传感器、热敏电阻传感器、对射式红外传感器、反射式红外传感器
以上图第3个电路为例子,它是模块的内部电路,也就是第5个电路图P1内部有关AO口输出的内部实现。对于该电路的电容在分析的时候可以屏蔽掉,它就个滤波电容,用来保证电路的稳定。
剩下的则是两个电阻了,对于接着Vcc的是定值电阻,对于接着GND的则是传感电阻,这两个其实就形成了上拉电阻和下拉电阻。
只不过对于下拉电阻比较特殊,在整个电路是起着分压的作用,也就是说当传感电阻阻值下降的时候,下拉电阻分到的电压就更多,对于AO口处的电压越小,即会输出低电平,在极端的情况下传感电阻阻值为0,电流完全流入GND(下拉分走了所有的电压),AO输出的电压就为0了。反过来,极端情况下传感电阻阻值为无穷大,也就是下拉处的电路断路了,那么这时候由于上拉电阻的作用,会将AO口的电压拔高(AO口分走了所有的电压),也就是输出高电平了。
简单点就是:当传感电阻阻值下降时,下拉作用增强,AO口输出低电平;阻值上升时,下拉作用减弱,这时候由于上拉起作用,AO口就是高电平。当上拉下拉旗鼓相当的时候,AO就差不多是Vcc/2的电压。
上拉/下拉在电路中是很常见的,其中就有弱上拉/下拉、强上拉/下拉,这里的强和弱就是指阻值的大小。
同时对于传感器还支持二值化的输出,也就是数字信号的输出,主要是P1口的DO引脚,内部是第一个电路图中的U1 LM393芯片的实现:
主要是靠运算放大器,当IN-(倒向输入端)是大于IN+(非倒向输入端)的时候,也就是Ud<0,此时输出端DO就会瞬间升为最小值,反过来就则是升为最大值,从而实现对模拟电压进行二值化处理,使得输入的是模拟电压,输出的(DO)的是数字电压。
而P1处的DO口还接着一个LED,就是用来指示DO口输出的高电平还是低电平,而接着VCC的R5则是为了保证DO默认输出的是高电平。
2.6.2 电路接法
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
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); | 显示二进制数字 |
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