STM32HAL库 -- 5.蜂鸣器报警

该文章已生成可运行项目,

目录

 1.简介

2.蜂鸣器模块

2.1有源蜂鸣器

2.2无源蜂鸣器

3.硬件连接

4.编写代码

4.1Beep.h编写

4.2蜂鸣器初始化代码

4.3蜂鸣器的打开和关闭

4.4蜂鸣器报警

4.5检查蜂鸣器的状态

5.全部代码

5.1Beep.h

5.2Beep.c

5.3main.c


1.简介

        通过上一个博客介绍的HAL库操作GPIO的函数,来实现蜂鸣器的的实验。笔者使用的开发板是STM32F103ZET6为MCU的正点原子精英板,读者可以使用自己的开发板来复现实验。开发板不是重点,重点是学习HAL库的使用。如果读者没学习过GPIO以及HAL库操作GPIO,可以通过下面的链接进行简单的学习一下:

STM32HAL库 -- 1.手把手创建HAL库工程模板

STM32HAL库 -- 2.介绍外设GPIO

STM32HAL库 -- 3.介绍HAL库中操作GPIO的函数

2.蜂鸣器模块

        蜂鸣器分为有源蜂鸣器和无源蜂鸣器两种,它们在结构、工作原理、驱动方式、声音特点和价格等方面存在明显的区别,下面展开介绍。

2.1有源蜂鸣器

        有源蜂鸣器内部自带振荡源,将振荡电路等集成在蜂鸣器内部,只需给它通电就可以发声。

        它的工作原理是基于压电效应或电磁效应工作。当接通直流电源后,内部的振荡电路产生一定频率的信号,驱动发声体振动发声。

        有源蜂鸣器的驱动较为简单,只需提供合适的直流电源即可发声。电源的极性通常是固定的,接反可能无法正常工作。由于内部振荡源的频率固定,所以发出的声音频率单一、音调固定,通常为持续的单音,如“滴、滴”声。

        由于有源蜂鸣器内部集成了振荡电路,其制造成本相对较高,价格通常比无源蜂鸣器贵一些。常用于对声音效果要求不高,只需要简单提示音的场合,如计算机、打印机、报警器等设备的状态提示。

2.2无源蜂鸣器

        无源蜂鸣器内部没有振荡源,只有发声装置,需要外部提供一定频率的脉冲信号才能发声。

        它也同样基于压电或电磁原理,但需要外部电路提供特定频率的交流电信号。当交流信号的频率与蜂鸣器的固有频率接近时,蜂鸣器发生共振,从而发出声音。

        但是驱动相对复杂,需要使用信号发生器或微控制器(如 Arduino、单片机等)产生特定频率和占空比的脉冲信号来驱动。可以通过改变脉冲信号的频率和占空比来控制蜂鸣器发出不同音调、节奏的声音。

        特点是可以通过调整输入信号的频率,发出不同音调的声音,还能模拟出多种复杂的声音效果,如音乐、警笛声等。

        无源蜂鸣器的结构简单,成本较低,价格更为便宜,在对成本敏感的大规模应用中具有优势。适用于需要发出不同音调、模拟各种声音的场景,如电子玩具、门铃、智能家电的语音提示等。

3.硬件连接

        笔者使用的正点原子的STM32F103ZE精英开发板上自带了一个有源蜂鸣器,连接在了PB8上,如下图所示:

        从图中可以看出,PB8连接到一个名为Q1的晶体管的栅极(G)。当PB8输出高电平时,Q1导通,使得蜂鸣器(BEEP)的两端有电压差,从而发声;当PB8输出低电平时,Q1截止,蜂鸣器就不发出声音了。

4.编写代码

        与上一章驱动LED的代码一样,首先要编写蜂鸣器初始化代码,然后编写打开蜂鸣器和关闭蜂鸣器代码,再编写蜂鸣器报警代码和检查蜂鸣器状态的代码。

STM32HAL库 -- 4.LED流水灯

4.1Beep.h编写

        在.h文件中使用宏定义写出端口和引脚,为后续编程提高可读性,再使用枚举,写出Beep的两个状态,以及函数的声明。

        比较简单,直接上代码:

#ifndef __BEEP_H__
#define __BEEP_H__


/*****************************************************
                头文件
******************************************************/
#include "sys.h"
#include "delay.h"


/*****************************************************
                宏定义
******************************************************/
#define     BEEP_PORT		 GPIOB
#define     BEEP_PIN         GPIO_PIN_8


/*****************************************************
                数据类型定义
******************************************************/
typedef enum
{
  Beep_OFF = 0u,
  Beep_ON = 1u
}Beep_State;


/*****************************************************
                函数声明
******************************************************/
void Beep_Init(void);
void Beep_TurnOn(void);
void Beep_TurnOff(void);
void Beep_Alarm(unsigned char count);
Beep_State Beep_CheckStatus(void);

#endif

4.2蜂鸣器初始化代码

        还是初始化GPIO,推挽输出模式,不使用上下拉,慢速,初始化PB8,再写入初始值即可。代码如下:

/**
 * @brief       Beep初始化函数
 * @param       无
 * @retval      无
 */
void Beep_Init(void)
{
	/*	1.打开时钟	*/
	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	/*	2.配置GPIO	*/
	GPIO_InitTypeDef gpio_initure = {0};
	gpio_initure.Pin = BEEP_PIN;				//Beep引脚
	gpio_initure.Mode = GPIO_MODE_OUTPUT_PP;	//推挽输出
	gpio_initure.Speed = GPIO_SPEED_FREQ_LOW;	//慢速
	gpio_initure.Pull = GPIO_NOPULL;			//不使用上下拉电阻,推挽输出模式下,上下拉电阻通常无实际作用
	HAL_GPIO_Init(BEEP_PORT, &gpio_initure);	//调用GPIO初始化函数
	
	/*	3.写入初始值,默认关闭	*/
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}

4.3蜂鸣器的打开和关闭

        PB8输出高电平时,蜂鸣器就响;输出低电平时,蜂鸣器就不响。根据这一点,编写两个函数,即蜂鸣器的打开和关闭。代码如下:

/**
 * @brief       打开蜂鸣器
 * @param       无
 * @retval      无
 */
void Beep_TurnOn(void)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_SET);
}


/**
 * @brief       关闭蜂鸣器
 * @param       无
 * @retval      无
 */
void Beep_TurnOff(void)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}

4.4蜂鸣器报警

        再编写一个函数,我们传递一个无符号字符型参数,传递的数值是几,蜂鸣器就报警几次,发出滴滴滴的声音。如果传递的数值大于等于10,就按10次算,就滴10下。代码如下:

/**
 * @brief       蜂鸣器报警
 * @param       count:报警的次数,数值为小于等于10的整数
 * @retval      无
 */
void Beep_Alarm(unsigned char count)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
	
	if(count >= 10)
	{
		count = 10;
	}
	
	for(int i = 0; i < count; i++)
	{
		HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_SET);
		delay_ms(100);
		HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
		delay_ms(100);
	}
	
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}

4.5检查蜂鸣器的状态

        再设计一个函数,每次调用之后,返回值就是蜂鸣器的工作状态,比如蜂鸣器正在发出声音,此时我们调用该函数之后,得到的返回值就是Beep_ON。代码如下:

/**
 * @brief       查询蜂鸣器状态
 * @param       无
 * @retval      Beep_State,Beep_OFF为关闭状态,Beep_ON为开启状态
 */
Beep_State Beep_CheckStatus(void)
{
	GPIO_PinState bitstatus = (GPIO_PinState)0;
	Beep_State status = Beep_OFF;
	
	bitstatus = HAL_GPIO_ReadPin(BEEP_PORT, BEEP_PIN);
	
	if(bitstatus == GPIO_PIN_SET)
		status = Beep_ON;
	else if(bitstatus == GPIO_PIN_RESET)
		status = Beep_OFF;
	
	return status;
}

5.全部代码

        笔者把整体的Beep.c、Beep.h和main.c放在下面,供读者参考。

5.1Beep.h

#ifndef __BEEP_H__
#define __BEEP_H__


/*****************************************************
                头文件
******************************************************/
#include "sys.h"
#include "delay.h"


/*****************************************************
                宏定义
******************************************************/
#define     BEEP_PORT		 GPIOB
#define     BEEP_PIN         GPIO_PIN_8


/*****************************************************
                数据类型定义
******************************************************/
typedef enum
{
  Beep_OFF = 0u,
  Beep_ON = 1u
}Beep_State;


/*****************************************************
                函数声明
******************************************************/
void Beep_Init(void);
void Beep_TurnOn(void);
void Beep_TurnOff(void);
void Beep_Alarm(unsigned char count);
Beep_State Beep_CheckStatus(void);

#endif

5.2Beep.c

#include "Beep.h"


/**
 * @brief       Beep初始化函数
 * @param       无
 * @retval      无
 */
void Beep_Init(void)
{
	/*	1.打开时钟	*/
	__HAL_RCC_GPIOB_CLK_ENABLE();
	
	/*	2.配置GPIO	*/
	GPIO_InitTypeDef gpio_initure = {0};
	gpio_initure.Pin = BEEP_PIN;				//Beep引脚
	gpio_initure.Mode = GPIO_MODE_OUTPUT_PP;	//推挽输出
	gpio_initure.Speed = GPIO_SPEED_FREQ_LOW;	//慢速
	gpio_initure.Pull = GPIO_NOPULL;			//不使用上下拉电阻,推挽输出模式下,上下拉电阻通常无实际作用
	HAL_GPIO_Init(BEEP_PORT, &gpio_initure);	//调用GPIO初始化函数
	
	/*	3.写入初始值,默认关闭	*/
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}


/**
 * @brief       打开蜂鸣器
 * @param       无
 * @retval      无
 */
void Beep_TurnOn(void)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_SET);
}


/**
 * @brief       关闭蜂鸣器
 * @param       无
 * @retval      无
 */
void Beep_TurnOff(void)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}

/**
 * @brief       蜂鸣器报警
 * @param       count:报警的次数,数值为小于等于10的整数
 * @retval      无
 */
void Beep_Alarm(unsigned char count)
{
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
	
	if(count >= 10)
	{
		count = 10;
	}
	
	for(int i = 0; i < count; i++)
	{
		HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_SET);
		delay_ms(100);
		HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
		delay_ms(100);
	}
	
	HAL_GPIO_WritePin(BEEP_PORT, BEEP_PIN, GPIO_PIN_RESET);
}


/**
 * @brief       查询蜂鸣器状态
 * @param       无
 * @retval      Beep_State,Beep_OFF为关闭状态,Beep_ON为开启状态
 */
Beep_State Beep_CheckStatus(void)
{
	GPIO_PinState bitstatus = (GPIO_PinState)0;
	Beep_State status = Beep_OFF;
	
	bitstatus = HAL_GPIO_ReadPin(BEEP_PORT, BEEP_PIN);
	
	if(bitstatus == GPIO_PIN_SET)
		status = Beep_ON;
	else if(bitstatus == GPIO_PIN_RESET)
		status = Beep_OFF;
	
	return status;
}

5.3main.c

#include "sys.h"
#include "uart1.h"
#include "delay.h"

#include "Beep.h"


int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
	stm32_clock_init(RCC_PLL_MUL9); 	/* 设置时钟, 72Mhz */
    uart1_init(115200);
	Beep_Init();
	
	while(1)
	{
//		Beep_Alarm(5);
//		delay_s(5);
		Beep_TurnOn();
		delay_ms(200);
		Beep_TurnOff();
		delay_s(2);
	}
}

        

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值