STM32标准库——(2)GPIO输出

1.GPIO简介

  • GPIO(General Purpose Input Output)通用输入输出口
  • 可配置为8种输入输出模式
  • 引脚电平:0V~3.3V部分引脚可容忍5V
  • 输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等
  • 输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

每个GPI/O端口有两个32位配置寄存器(GPIOx_CRL,GPIOx_CRH),两个32位数据寄存器
(GPIOx_IDR和GPIOx_ODR),一个32位置位/复位寄存器(GPIOx_BSRR),一个16位复位寄存
器(GPIOx_BRR)和一个32位锁定寄存器(GPIOx_LCKR)。
根据数据手册中列出的每个I/O端口的特定硬件特征,GPIO端口的每个位可以由软件分别配置成
多种模式。

  • ─ 输入浮空
  • ─ 输入上拉
  • ─ 输入下拉
  • ─ 模拟输入
  • ─ 开漏输出
  • ─ 推挽式输出
  • ─ 推挽式复用功能
  • ─ 开漏复用功能

每个I/O端口位可以自由编程,然而必须按照32位字访问I/O端口寄存器(不允许半字或字节访
问)。GPIOx_BSRR和GPIOx_BRR寄存器允许对任何GPIO寄存器进行读/更改的独立访问;这
样,在读和更改访问之间产生IRQ时不会发生危险。

2.GPIO结构

2.1 GPIO基本结构

  • 寄存器是一段特殊的存储器 内核可以通过APB2总线对寄存器进行读写 这样就可以完成输出电平和读取电平的功能 寄存器的每一位对应一个引脚 其中输出寄存器写1 对应的引脚就会输出高电平 写0 就输出低电平 输入寄存器读取为1 就证明对应的端口目前是高电平 读取为0 就是低电平 由于STM32是32位的单片机 所以STM32内部的寄存器是32位的 如图可以看到 这个端口只有16位 所以这个寄存器只有低16位对应的有端口 高16位是没有用到的
  • 驱动器是用来增加信号的驱动能力的 寄存器只负责存储数据 如果要进行点灯这样的操作 还是需要驱动器来负责增大驱动能力

2.2 GPIO系统结构

在STM32中 所有的GPIO都是挂载在APB2外设总线上的

2.3 GPIO位结构

IO端口位的基本结构

5伏兼容I/O端口位的基本结构

  1. 保护二极管:对输入电压进行限幅 上面二极管接VDD(3.3V) 下面接VSS(0V) 如果输入电压比3.3V还要高 那上方二极管就会导通 输入电压产生的电流就会直接流入VDD而不会流入内部电路 这样就可以避免过高的电压对内部这些电路产生伤害 如果输入电压比0V还要低 那下方二极管会导通 电流会从VSS直接流出去 而不会从内部电路汲取电路 也是可以保护内部电路的 如果输入电压在0~3.3V之间 两个二极管均不会导通 这时二极管对电路没有影响 这就是保护二极管的用途
  2. 上面导通下面断开 就是上拉输入模式 下面导通上面断开 就是下拉输入模式 两个都断开 就是浮空输入模式(引脚的输入电平极易受到外界干扰而改变) 接入上拉电阻 当引脚悬空时 还有上拉电阻来保证引脚的高电平 所以上拉输入又可以称作是默认为高电平的输入模式 下拉也同理 就是默认为低电平的输入模式
  3. 模拟输入:连接到ADC上 因为ADC需要接收模拟量 所以这跟线是接到肖特基触发器前面
  4. 复用功能输入:连接到其他需要读取端口的外设上的 比如串口的输入引脚等 这根线接收的是数字量 所以在肖特基触发器后面
  5. 输入数据寄存器:用程序读取输入数据寄存器某一位的数据 就可以知道端口的输入电平
  6. 输出数据寄存器:普通的IO口输出 写这个数据寄存器的某一位就可以操作对应的某个端口
  7. 位设置/清楚寄存器:用来单独操作输出数据寄存器的某一位 而不影响其他位 (库函数所使用的方法)
  8.  因为输出数据寄存器同时控制16个端口 并且这个寄存器只能整体读写 所以如果想单独控制其中某一个端口而不影响其他端口的话 就需要一些特殊的操作模式 第一种方式是先读出这个寄存器 然后用按位与、按位或的方式更改某一位 最后再将更改后的数据写回去 在C语言中就是&=和|=的操作 该方法比较麻烦 效率不高 对于IO口的操作而言不太合适 第二种就是通过设置这个位设置/位清除寄存器 如果我们对某一位进行置1操作 在位设置寄存器的对应位写1即可 剩下不需要操作的写0 这样它内部就会有电路 自动将输出数据寄存器中对应位置为1 而剩下写0的位则保持不变 这样就保证了只操作其中某一位而不影响其他位 并且这是一步到位的操作 如果想对某一位进行清0操作 就在位清除寄存器对应位写1即可 这样内部电路就会把这一位清0 第三种是读写STM32中的”位带“区域 位带作用跟51单片机的位寻址作用差不多 在STM32中 专门分配的有一段地域区域 这段地址映射了RAM和外设寄存器所有的位 读写这段地址中的数据 就相当于读写所映射位置的某一位
  9. MOS管是一种电子开关 信号来控制开关的导通和关闭 开关负责将IO口接到VDD或者VSS 在这里可以选择推挽、开漏或关闭三种输出方式 推挽输出模式:P-MOS和N-MOS均有效 数据寄存器为1时 上管导通 下管断开 输出直接接到VDD 就是输出高电平 数据寄存器为0时 上管断开 下管导通 输出直接接到VSS 就是输出低电平 该模式下 高低电平均有较强的驱动能力 所以推挽输出模式也可以叫做强推输出模式 同时STM32对IO口有绝对的控制权 高低电平都有STM说了算 开漏输出模式:P-MOS无效 只有N-MOS在工作 数据寄存器为1 下管断开 这时输出相当于断开 也就是高阻模式 数据寄存器为0时 下管导通 输出直接接到VSS 也就是输出低电平 这种模式下 只有低电平有驱动能力 高电平是没有驱动能力的 该模式可以作为通信协议的驱动方式 比如I2C通信的引脚 就是使用的开漏模式 在多机通信的情况下 这个模式可以避免各个设备的相互干扰 另外开漏模式还可以使用输出5V的电平信号 比如在IO口外接一个上拉电阻到5V的电源 当输出低电平时 由内部的N-MOS直接接到VSS 当输出高电平时 由外部的上拉电阻拉高至5V 这样就可以输出5V的电平信号 用于兼容一些5V电平的设备 关闭模式:当引脚配置为输入模式的时候 两个MOS管都无效 也就是输出关闭 端口的电平由外部信号来控制

3.GPIO模式

通过配置GPIO的端口配置寄存器,端口可以配置成以下8种模式:

端口配置

输出模式位

3.1 浮空输入

浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。也就是说,I/O的电平状态是不确定的,完全由外部输入决定;如果在该引脚悬空(在无信号输入)的情况下,读取该端口的电平是不确定的。所以在要读取外部信号时通常配置IO口为浮空输入模式。

3.2 上拉输入

上拉输入模式下,I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在高电平;并且在I/O端口输入为低电平的时候,输入端的电平为低电平。

3.3 下拉输入

下拉输入模式下,IO口工作方式刚好和上拉模式相反。I/O端口的电平信号直接进入输入数据寄存器。但是在I/O端口悬空(在无信号输入)的情况下,输入端的电平可以保持在低电平;并且在I/O端口输入为高电平的时候,输入端为高电平。

3.4 模拟输入

模拟输入模式下,I/O端口的模拟信号(电压信号,而非电平信号)直接模拟输入到片上外设模块,比如ADC模块等等。(除了模拟输入这个模式会关闭数字的输入功能 在其他7个模式中 所有的输入都是有效的)

3.5 开漏输出

开漏输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,控制MOS管的导通。这里要注意N-MOS管,当设置输出的值为高电平的时候,N-MOS管处于关闭状态,此时I/O端口的电平就不会由输出的高低电平决定,而是由I/O端口外部的上拉或者下拉决定;当设置输出的值为低电平的时候,N-MOS管处于开启状态,此时I/O端口的电平就是低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,I/O端口的电平不一定是输出的电平。通常使用开漏输出时外部要加一个上拉电阻。

3.6 开漏复用输出

开漏复用输出模式,与开漏输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

3.7 推挽输出

推挽输出模式下,通过设置位设置/清除寄存器或者输出数据寄存器的值,控制P-MOS管和N-MOS管的导通来控制IO口输出高电平还是低电平。这里要注意P-MOS管和N-MOS管,当设置输出的值为1的时候,P-MOS管处于开启状态,N-MOS管处于关闭状态,此时I/O端口的电平就由P-MOS管决定为高电平;当设置输出的值为0的时候,P-MOS管处于关闭状态,N-MOS管处于开启状态,此时I/O端口的电平就由N-MOS管决定为低电平。同时,I/O端口的电平也可以通过输入电路进行读取;注意,此时I/O端口的电平一定是输出的电平。

3.8 推挽复用输出

推挽复用输出模式,与推挽输出模式很是类似。只是输出的高低电平的来源,不是让CPU直接写输出数据寄存器,取而代之利用片上外设模块的复用功能输出来决定的。

4.LED和蜂鸣器简介

  • LED:发光二极管,正向通电点亮,反向通电不亮
  • 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
  • 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音

硬件电路

  • PA0输出低电平时 LED两端产生电压差 形成正向导通电流 LED会被点亮 PA0输出高电平时 LED两端都是3.3V的电压 不会形成电流 所以高电平LED就是熄灭(下面与之相反)
  • 限流电阻作用:防止LED因为电流过大而烧毁 也可以调整LED的亮度

5.面包板

面包板概述

面包板使用示例

6.相关API

6.1 GPIOSpeed_TypeDef

/** 
  * @brief  Output Maximum frequency selection  最大频率选择
  */

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

6.2 GPIOMode_TypeDef

/** 
  * @brief  Configuration Mode enumeration  配置模式枚举
  */

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;

6.3 GPIO_InitTypeDef

/** 
  * @brief  GPIO Init structure definition  
  */

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured. 指定要配置的GPIO引脚。
                                      This parameter can be any value of @ref 该参数可以是@ref的任意值        
  GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins. 指定所选引脚的速度。
                                      This parameter can be a value of @ref 
  GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins. 指定所选引脚的工作模式。
                                      This parameter can be a value of @ref 
  GPIOMode_TypeDef */
}GPIO_InitTypeDef;


6.4 BitAction

/** 
  * @brief  Bit_SET and Bit_RESET enumeration  位SET和位RESET枚举
  */

typedef enum
{ Bit_RESET = 0,
  Bit_SET = 1;
}BitAction;
//这里一般用来强转 如果输入高低电平不是特定参数 而是0或1 则需要在0或1前面加上BitAction 如下:
    GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)0);
	Delay_ms(500);
	GPIO_WriteBit(GPIOA,GPIO_Pin_0,(BitAction)1);
	Delay_ms(500);

6.5 GPIO_pins_define

/** @defgroup GPIO_pins_define GPIO引脚定义
  * @{
  */

#define GPIO_Pin_0                 ((uint16_t)0x0001)  /*!< Pin 0 selected */
#define GPIO_Pin_1                 ((uint16_t)0x0002)  /*!< Pin 1 selected */
#define GPIO_Pin_2                 ((uint16_t)0x0004)  /*!< Pin 2 selected */
#define GPIO_Pin_3                 ((uint16_t)0x0008)  /*!< Pin 3 selected */
#define GPIO_Pin_4                 ((uint16_t)0x0010)  /*!< Pin 4 selected */
#define GPIO_Pin_5                 ((uint16_t)0x0020)  /*!< Pin 5 selected */
#define GPIO_Pin_6                 ((uint16_t)0x0040)  /*!< Pin 6 selected */
#define GPIO_Pin_7                 ((uint16_t)0x0080)  /*!< Pin 7 selected */
#define GPIO_Pin_8                 ((uint16_t)0x0100)  /*!< Pin 8 selected */
#define GPIO_Pin_9                 ((uint16_t)0x0200)  /*!< Pin 9 selected */
#define GPIO_Pin_10                ((uint16_t)0x0400)  /*!< Pin 10 selected */
#define GPIO_Pin_11                ((uint16_t)0x0800)  /*!< Pin 11 selected */
#define GPIO_Pin_12                ((uint16_t)0x1000)  /*!< Pin 12 selected */
#define GPIO_Pin_13                ((uint16_t)0x2000)  /*!< Pin 13 selected */
#define GPIO_Pin_14                ((uint16_t)0x4000)  /*!< Pin 14 selected */
#define GPIO_Pin_15                ((uint16_t)0x8000)  /*!< Pin 15 selected */
#define GPIO_Pin_All               ((uint16_t)0xFFFF)  /*!< All pins selected */
//c语言不支持2进制 需要写成16进制格式 最后一个对应16个端口

6.6 GPIO_Init

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
功能:
	根据 GPIO_InitStruct 中指定的参数初始化外设 GPIOx 寄存器
参数:
	GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
    GPIO_InitStruct:指向结构 GPIO_InitTypeDef 的指针,包含了外设 GPIO 的配置信息    
返回值:
	无

6.7 GPIO_SetBits

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:
	设置指定的数据端口位
参数:
	GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
    GPIO_Pin:待设置的端口位    
返回值:
	无

6.8 GPIO_ResetBits

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
功能:
	清除指定的数据端口位
参数:
	GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
    GPIO_Pin:待设置的端口位    
返回值:
	无

6.9 GPIO_WriteBit

void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
功能:
	设置或者清除指定的数据端口位
参数:
	GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
    GPIO_Pin:待设置或者清除指的端口位 
返回值:
	无

6.10 GPIO_Write

void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
功能:
	向指定 GPIO 数据端口写入数据
参数:
	GPIOx:x 可以是 A,B,C,D 或者 E,来选择 GPIO 外设
    PortVal: 待写入端口数据寄存器的值
返回值:
	无
//第二个参数需要写16进制 由于c语言不支持二进制 格式如下:
    GPIO_Write(GPIOA,~0x0002);//0000 0000 0000 0010
	Delay_ms(100);
	GPIO_Write(GPIOA,~0x0004);//0000 0000 0000 0100
	Delay_ms(100);

7.LED闪烁

7.1 接线图

7.2 相关代码

main.c

#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;//推挽模式(高低电平都能驱动):长脚接+ 短脚接PA0/ 短脚接PA0 长脚接-
	//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏模式(低电平驱动):长脚接+ 短脚接PA0
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//GPIO引脚,赋值为第0号引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//GPIO速度,赋值为50MHz
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将赋值后的构体变量传递给GPIO_Init函数
															//函数内部会自动根据结构体的参数配置相应寄存器
															//实现GPIOA的初始化
	
	/*主循环,循环体内的代码会一直循环执行*/
	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
	}
}

7.3 相关现象

接PA0口的LED灯会以每500ms闪烁一次

8.LED流水灯

8.1 接线图

8.2 相关代码

main.c

#include "stm32f10x.h"                  // Device header
#include "Delay.h"

int main(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽模式(高低电平都能驱动):长脚接+ 短脚接PA0/ 短脚接PA0 长脚接-
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;//开漏模式(低电平驱动):长脚接+ 短脚接PA0
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;//这里只用了低八位来演示 高八位暂时用不到 索性直接选择了全部 如果要只选择前八位 可以用以下格式:GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2...以此类推
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//GPIO速度,赋值为50MHz
	GPIO_Init(GPIOA,&GPIO_InitStructure);
	
	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
	}
	}

}

8.3 相关现象

接PA0-PA7口的8个LED灯每隔100ms闪烁一次

9.蜂鸣器

9.1 接线图

9.2 相关代码

main.c

#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
	}
}

9.3 相关现象

蜂鸣器第一次叫后间隔100ms 第二次叫后隔700ms 类似于闹钟声音

相关推荐

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-01-27 00:16:01       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-01-27 00:16:01       100 阅读
  3. 在Django里面运行非项目文件

    2024-01-27 00:16:01       82 阅读
  4. Python语言-面向对象

    2024-01-27 00:16:01       91 阅读

热门阅读

  1. mysql字符集

    2024-01-27 00:16:01       48 阅读
  2. SpringCloudStream整合MQ(待完善)

    2024-01-27 00:16:01       56 阅读
  3. TestNG @BeforeGroups 注解

    2024-01-27 00:16:01       53 阅读
  4. 云安全中常见的云漏洞

    2024-01-27 00:16:01       44 阅读
  5. 第一章 基础算法(二)(高精度加减乘除)

    2024-01-27 00:16:01       56 阅读
  6. LeetCode-题目整理【10】:单词搜索

    2024-01-27 00:16:01       55 阅读
  7. SpringBoot中从HikariCP迁移到Oracle UCP指南

    2024-01-27 00:16:01       42 阅读
  8. Tcp实现聊天

    2024-01-27 00:16:01       47 阅读
  9. 2024.1.23力扣每日一题——最长交替子数组

    2024-01-27 00:16:01       60 阅读
  10. 整数反转算法(leetcode第7题)

    2024-01-27 00:16:01       53 阅读
  11. vue3常用代码

    2024-01-27 00:16:01       58 阅读