上一节我们学习了LED的一些有趣的实验,这节我们换一种外设——蜂鸣器,蜂鸣器是一种常见的发声器件,电子产品等设备经常会配备蜂鸣器作为声音指示器。
- 先简单介绍本文将用到的硬件及软件:
硬件平台:普中51开发板-单核A2
软件:Keil5(C51)、STC-ISP(或其他ISP软件)、Proteus8.9(用于仿真,非必须)
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。比如台式电脑的主机开机会"滴"一声、洗衣机按下按键及洗衣完成都会有声响,以上这些声音都是通过蜂鸣器来发出的。
下图是蜂鸣器的电路图形符号(蜂鸣器也是有正负极之分的)
蜂鸣器按驱动方式可分为有源蜂鸣器
(内含驱动线路)和无源蜂鸣器
(外部驱动)。这里的“源
”指的是激励源。
无源蜂鸣器内部没有激励源,只有给它一定频率的方波信号
,才能让蜂鸣器的振动装置起振
,从而实现发声,同时,输入的方波频率不同,发出的声音也不同(所以无源蜂鸣器可以模拟曲调实现音乐效果)。
有源蜂鸣器则不需要外部的激励源,只需要接入直流电源
,即可自动发出声音(声音频率相对固定)。
由于有源蜂鸣器较为简单,只需要单片机给出高低电平即可控制其工作发声(还需借助三极管放大电路),这和上两节讲的LED很类似,所以本节就不重点讨论有源蜂鸣器(但文末有简单代码介绍),只研究单片机如何控制无源蜂鸣器。
我之前写过一篇文章详细介绍蜂鸣器,里面介绍了蜂鸣器的种类和一些简单的硬件知识,感兴趣的可以看看,传送门:(点我)
无源蜂鸣器
需要1.5~2.5kHz
(与蜂鸣器种类有关)的音频信号,这个音频信号即一个高低变化频率为1.5-2.5kHz的方波
。实际上频率小于1.5kHz也是有声音的,只是不那么准了,可能是嘟嘟
声。
在写代码前,我们需要先创建一个Keil工程,创建工程的步骤已经在本系列第一篇文章中讲述,传送门:(点我)。这里就不进行赘述。
前面提到无源蜂鸣器需要一定频率的高低变化的信号才能驱动发声,那么怎么用代码产生一个高低变化的信号(方波)呢?
和上节所讲的呼吸灯一样,我用到了模拟PWM,void Simulate_Pwm(unsigned char period, unsigned char duty)
实现了类似PWM输出的功能,period
为周期,控制整个过程的时间长度(对应蜂鸣器的频率,频率=1/周期
),duty
表示低电平时间占周期时间的比例,在这个实验里,这个值对蜂鸣器影响不大(选择50%即可)。
#include //此文件中定义了单片机的一些特殊功能寄存器
sbit beep = P1^5; //定义蜂鸣器的引脚
/******************************************************************************
* @ 函数名 : Delay_10us
* @ 功 能 : 10us粗略延时
* @ 参 数 : 延时时间--单位10us
* @ 返回值 : 无
******************************************************************************/
void Delay_10us(unsigned int time)
{
while(time--);
}
/******************************************************************************
* @ 函数名 : Simulate_Pwm
* @ 功 能 : 模拟PWM控制(需要不停运行)
* @ 参 数 : period 周期(单位10us)
* duty 占空比(低电平,0-100)
* @ 返回值 : 无
******************************************************************************/
void Simulate_Pwm(unsigned char period, unsigned char duty)
{
unsigned char low = period / 100 * duty; //低电平延时时间
unsigned char high = period - low; //高电平延时时间
beep = 0; //蜂鸣器IO电平置低
Delay_10us(low); //低电平延时时间
beep = 1; //蜂鸣器IO电平置高
Delay_10us(high);//高电平延时时间
}
/******************************************************************************
* @ 函数名 : main
* @ 功 能 : 主函数
* @ 参 数 : 无
* @ 返回值 : 无
******************************************************************************/
int main()
{
while(1)
{
//使用模拟PWM控制蜂鸣器
Simulate_Pwm(100, 50); //周期100*10us,占空比50%——频率:1KHz
}
}
reg52.h
:sbit beep = P1^5;
:sbit
是定义特殊功能寄存器的位变量(bit
和sbit
都是C51扩展的变量类型,即C51特有的,而不是C语言标准变量类型),这里我们只需要把sbit当成一个类型即可,就像char、int,只不过char指的是一个字节,而sbit指的是字节里的一个位。sfr
)也是一种扩充数据类型,占用一个内存单元(1字节)。上面式子中的P1
就是一个SFR,在reg52.h
中,定义了P1
寄存器的地址,如果我们对P1
进行赋值,就等同于对51单片机的特殊功能寄存器赋值,即P1对应的8个IO端口。sbit
和P1
的含义,那么理解sbit beep = P1^5;
就不难了,即定义P1.5引脚的状态为beep
,P1^5
也是C51的特有用法,表示P1
的第5位数据。while(1){}
:这是一个死循环,由于单片机上电后要不停的工作,所以我们不能让main
函数结束,而是让它不停地执行while
函数内部的工作。Simulate_Pwm(100, 50);
:上面已经提过了,用于模拟PWM输出,可以让蜂鸣器IO输出一定频率的方波(第二个参数需要选50),方波频率由函数第一个参数决定,当第一个参数(period
)为100时,对应的频率为1/(100*10us)=1KHz
。程序编写完成后,接下来的操作就是编译+烧录了,这些步骤已经在本系列第一篇文章中讲述,传送门:(点我)。不过这里还是会简单描述一下操作过程:
Build Output
窗口会显示报错信息,如果没有错误和警告(如果这几行都有警告,那说明有问题),且生成了hex
文件,说明编译成功。hex
文件烧录到单片机中,即可听到蜂鸣器在响了。实际效果:(实际效果就不方便展示了)
仿真效果:上电后蜂鸣器响起。
【Proteus软件的安装和使用可以参考我的另一篇博客(带安装包下载链接),传送门:(点我)】
这里简单介绍一下有源蜂鸣器的控制代码:
功能:让有源蜂鸣器以500ms的间隔进行鸣叫。
#include //此文件中定义了单片机的一些特殊功能寄存器
sbit beep = P1^5; //定义蜂鸣器的引脚
/******************************************************************************
* @ 函数名 : Delay_10us
* @ 功 能 : 10us粗略延时
* @ 参 数 : 延时时间--单位10us
* @ 返回值 : 无
******************************************************************************/
void Delay_10us(unsigned int time)
{
while(time--);
}
/******************************************************************************
* @ 函数名 : main
* @ 功 能 : 主函数
* @ 参 数 : 无
* @ 返回值 : 无
******************************************************************************/
int main()
{
while(1)
{
beep = ~beep; //高低电平切换
Delay_10us(50000); //延时约500ms
}
}
仿真效果:
有源蜂鸣器以大约500ms的间隔进行鸣叫
【Proteus软件的安装和使用可以参考我的另一篇博客(带安装包下载链接),传送门:(点我)】
如果文章对你有帮助,请留下你的点赞吧,这是我继续更新的最大动力。