【普中STM32精灵开发攻略】--第 13 章 蜂鸣器实验

发布于:2025-08-10 ⋅ 阅读:(15) ⋅ 点赞:(0)

(1)实验平台:

普中STM32精灵开发板https://item.taobao.com/item.htm?id=739076227953(2)资料下载:普中科技-各型号产品资料下载链接


        在前面章节中我们已经介绍了如何控制 STM32 的IO 口输出高低电平,本章我们通过另外一个实验来讲述 STM32 IO 口的输出。通过STM32F1 芯片的一个IO口控制板载无源蜂鸣器,实现蜂鸣器控制。学习本章可以参考《STM32F1xx 中文参考手册》 8 通用 I/O(GPIO)章节,或者参考前面 LED 实验章节。本章分为如下几部分内容:

 

13.1 蜂鸣器介绍

13.2 硬件设计

13.3 软件设计

13.3.1 蜂鸣器初始化及报警函数

13.3.2 主函数

13.4 实验现象


13.1 蜂鸣器介绍

        蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。

        压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V 直流工作电压),多谐振荡器起振,输出 1.5~5kHZ 的音频信号,阻抗匹配器推动压电蜂鸣片发声。

        电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。

        其实一句话就可概括它们之间的区别,要想压电式蜂鸣器发声,需提供一定频率的脉冲信号;要想电磁式蜂鸣器发声,只需提供电源即可。

        我们开发板上使用的蜂鸣器是无源蜂鸣器,属于压电式蜂鸣器类型。这里说的有源无源,并不是指电源的意思,而是指蜂鸣器内部是否含有振荡电路,有源蜂鸣器内部自带振荡电路,只需提供电源即可发声,而无源蜂鸣器则需提供一定频率的脉冲信号才能发声,频率大小通常在 1.5-5KHz 之间。蜂鸣器实物图如下图所示:

        如果给无源蜂鸣器加一个 1.5-5KHz 的脉冲信号会发声,而且改变这个频率,就可以调节蜂鸣器音调,产生各种不同音色、音调的声音。如果改变输出电平的高低电平占空比,则可以改变蜂鸣器的声音大小。

13.2 硬件设计

        在前面章节中我们已经对 STM32 的 GPIO 做了简单介绍,并且还使用了其中IO 口直接控制开发板上的 LED。对于本章要实现蜂鸣器的控制,我们能否直接使用 STM32 的 IO 口驱动呢?根据 STM32F1 芯片数据手册可知,单个IO 口的最大输出电流是 25mA,而蜂鸣器的驱动电流是 30mA 左右,两者非常接近,有的朋友就想直接用 IO 口来驱动,但是有没有考虑到整个芯片的输出电流,整个芯片的输出电流最大也就 150mA,如果在驱动蜂鸣器上就耗掉了30mA,那么STM32 其他的IO 口及外设电流就非常拮据了。所以我们不会直接使用IO 口驱动蜂鸣器,而是通过外部驱动电路后再驱动蜂鸣器,这样 STM32 的 IO 口只需要提供不到1mA的电流就可控制蜂鸣器。所以我们也经常说到 STM32 芯片是用来做控制的,而不是驱动。

        我们 STM32F1 开发板上的蜂鸣器模块电路如下图所示:

        从电路图中可以看到,STM32 芯片的 PB0 引脚是用来控制蜂鸣器的,驱动电路 ULN2003 芯片 OUT5 管脚输出驱动蜂鸣器,ULN2003 芯片使用简单,输入为高电平,输出则为低电平,输入为低电平,输出则为高组态;输出低电平时蜂鸣器得到电压,高组态时,蜂鸣器断开,只要不断输出一定频率高低电平脉冲信号即可发出声音。

13.3 软件设计

        我们打开“\4--实验程序\1--基础实验\7-蜂鸣器实验”工程,在APP 文件夹内可以看到又新建了一个 beep 文件夹,这个在前面LED 实验的时候也说过为什么要这样操作。

13.3.1 蜂鸣器初始化及报警函数

        我们打开工程中 beep.c 文件,里面代码如下:

#include "beep.h"
#include "SysTick.h"

/*******************************************************************************
* 函 数 名         : BEEP_Init
* 函数功能		   : 蜂鸣器初始化
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void BEEP_Init(void)	  //端口初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;	//声明一个结构体变量,用来初始化GPIO

	RCC_APB2PeriphClockCmd(BEEP_PORT_RCC,ENABLE);   /* 开启GPIO时钟 */

	/*  配置GPIO的模式和IO口 */
	GPIO_InitStructure.GPIO_Pin=BEEP_PIN;		//选择你要设置的IO口
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;		  //设置推挽输出模式
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;	  //设置传输速率
	GPIO_Init(BEEP_PORT,&GPIO_InitStructure); 	 /* 初始化GPIO */
	
	GPIO_ResetBits(BEEP_PORT,BEEP_PIN);
}

//蜂鸣器报警
//times:报警次数
//us:延时微秒时间
void BEEP_Alarm(u8 times,u8 us)
{
	while(times--)
	{
		BEEP=!BEEP;
		delay_us(us);
	}
}

        BEEP_Init 函数用来初始化蜂鸣器的端口及时钟,在函数内我们看到有几个参数不是库函数内的,比如 BEEP_PIN、BEEP_PORT、BEEP_PORT_RCC,这种情况一般是我们自己定义的宏,通常放在对应的头文件内;

        BEEP_Alarm 函数用来实现蜂鸣器报警,函数内有两个参数,times 为循环次数,us 为触发脉冲时间,通过传递不同的 us 值从而改变不同频率。

        我们打开 beep.h,可以看到如下代码:

#ifndef _beep_H
#define _beep_H

#include "system.h"

/*  蜂鸣器时钟端口、引脚定义 */
#define BEEP_PORT 			GPIOB   
#define BEEP_PIN 			GPIO_Pin_0
#define BEEP_PORT_RCC		RCC_APB2Periph_GPIOB

#define BEEP PBout(0)

//函数声明
void BEEP_Init(void);
void BEEP_Alarm(u8 times,u8 us);

#endif

        里面就将蜂鸣器的 GPIO 端口及管脚和端口时钟进行了宏定义,这样做是方便大家移植程序,只需要对这个宏修改就能实现蜂鸣器的初始化修改。假如你们自己做的板子,蜂鸣器放在 PA5 管脚上控制,那你只需要修改beep.h 头文件内容,把 RCC_APB2Periph_GPIOB 改为 RCC_APB2Periph_GPIOA,GPIOB 改为GPIOA,GPIO_PIN_8 改为 GPIO_PIN_5,把 PBout(8)改为 PAout(5),而beep.c 文件完全不用修改,是不是非常方便呢?

13.3.2 主函数

        我们打开工程中 main.c 文件,里面代码如下:

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "beep.h"


int main()
{
	SysTick_Init(72);
	LED_Init();
	BEEP_Init();
	
	while(1)
	{
		LED0=!LED0;
		BEEP_Alarm(100,100);
		delay_ms(200);
	}
}

        主函数实现的功能比较简单,首先将使用到的外设硬件进行初始化,然后进入 while 循环,不断翻转 led 管脚状态,同时调用蜂鸣器报警函数,传递循环次数未 100,脉冲时间为 100us,因为使用到了 delay_ms 延时函数,所以在main函数开始处就需要调用 SysTick_Init(72)初始化,这个在我们后面所有程序都会使用,后面就不重复。

13.4 实验现象

        将工程程序编译下载到开发板内,可以看到核心板上指示灯间隔200ms 闪烁一次,同时蜂鸣器发声一次。


网站公告

今日签到

点亮在社区的每一天
去签到