#|51单片机入门(4)蜂鸣器(无源+有源)

上一节我们学习了LED的一些有趣的实验,这节我们换一种外设——蜂鸣器,蜂鸣器是一种常见的发声器件,电子产品等设备经常会配备蜂鸣器作为声音指示器。

文章目录
  • 蜂鸣器是什么
  • 无源蜂鸣器工作原理
  • 实验代码
  • 编译+烧录
  • 实验效果
  • 有源蜂鸣器代码

  • 先简单介绍本文将用到的硬件及软件:
    硬件平台:普中51开发板-单核A2
    软件:Keil5(C51)、STC-ISP(或其他ISP软件)、Proteus8.9(用于仿真,非必须)
蜂鸣器是什么
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。比如台式电脑的主机开机会"滴"一声、洗衣机按下按键及洗衣完成都会有声响,以上这些声音都是通过蜂鸣器来发出的。
下图是蜂鸣器的电路图形符号(蜂鸣器也是有正负极之分的)
#|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

蜂鸣器按驱动方式可分为有源蜂鸣器(内含驱动线路)和无源蜂鸣器(外部驱动)。这里的“”指的是激励源。
无源蜂鸣器内部没有激励源,只有给它一定频率的方波信号,才能让蜂鸣器的振动装置起振,从而实现发声,同时,输入的方波频率不同,发出的声音也不同(所以无源蜂鸣器可以模拟曲调实现音乐效果)。
有源蜂鸣器则不需要外部的激励源,只需要接入直流电源,即可自动发出声音(声音频率相对固定)。
由于有源蜂鸣器较为简单,只需要单片机给出高低电平即可控制其工作发声(还需借助三极管放大电路),这和上两节讲的LED很类似,所以本节就不重点讨论有源蜂鸣器(但文末有简单代码介绍),只研究单片机如何控制无源蜂鸣器。
我之前写过一篇文章详细介绍蜂鸣器,里面介绍了蜂鸣器的种类和一些简单的硬件知识,感兴趣的可以看看,传送门:(点我)
无源蜂鸣器工作原理 #|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

无源蜂鸣器需要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表示你调用了52或者51单片机的资源,也就是可以直接对单片机的相关寄存器与引脚进行操作,里面涉及和很多内容,这里只要知道它是一个必须加的一个头文件即可。
  • sbit beep = P1^5; sbit是定义特殊功能寄存器的位变量(bitsbit都是C51扩展的变量类型,即C51特有的,而不是C语言标准变量类型),这里我们只需要把sbit当成一个类型即可,就像char、int,只不过char指的是一个字节,而sbit指的是字节里的一个位。
    上面还提到特殊功能寄存器(SFR),SFR是80C51单片机中各功能部件对应的寄存器,用于存放相应功能部件的控制命令,状态或数据,SFR(sfr)也是一种扩充数据类型,占用一个内存单元(1字节)。上面式子中的P1就是一个SFR,在reg52.h中,定义了P1寄存器的地址,如果我们对P1进行赋值,就等同于对51单片机的特殊功能寄存器赋值,即P1对应的8个IO端口。
    知道了sbitP1的含义,那么理解sbit beep = P1^5; 就不难了,即定义P1.5引脚的状态为beepP1^5也是C51的特有用法,表示P1的第5位数据。
  • while(1){}:这是一个死循环,由于单片机上电后要不停的工作,所以我们不能让main函数结束,而是让它不停地执行while函数内部的工作。
  • Simulate_Pwm(100, 50); :上面已经提过了,用于模拟PWM输出,可以让蜂鸣器IO输出一定频率的方波(第二个参数需要选50),方波频率由函数第一个参数决定,当第一个参数(period)为100时,对应的频率为1/(100*10us)=1KHz
编译+烧录 程序编写完成后,接下来的操作就是编译+烧录了,这些步骤已经在本系列第一篇文章中讲述,传送门:(点我)。不过这里还是会简单描述一下操作过程:
  • 点击编译按钮,如果怕出现意外,可以点第三个(重新编译),编译完成后Build Output窗口会显示报错信息,如果没有错误和警告(如果这几行都有警告,那说明有问题),且生成了hex文件,说明编译成功。
#|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

  • 将刚才生成的hex文件烧录到单片机中,即可听到蜂鸣器在响了。
#|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

实验效果
  • 实际效果:(实际效果就不方便展示了)
  • 仿真效果:上电后蜂鸣器响起。
    【Proteus软件的安装和使用可以参考我的另一篇博客(带安装包下载链接),传送门:(点我)
#|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

有源蜂鸣器代码 这里简单介绍一下有源蜂鸣器的控制代码:
功能:让有源蜂鸣器以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 } }

仿真效果:
【#|51单片机入门(4)蜂鸣器(无源+有源)】有源蜂鸣器以大约500ms的间隔进行鸣叫
【Proteus软件的安装和使用可以参考我的另一篇博客(带安装包下载链接),传送门:(点我)
#|51单片机入门(4)蜂鸣器(无源+有源)
文章图片

如果文章对你有帮助,请留下你的点赞吧,这是我继续更新的最大动力。

    推荐阅读