蜂鸣器是一种只能将电信号转换为声信号的器件,常用来产生设备的按键音、报警音等提示音。
蜂鸣器按照驱动方式可以分为有源蜂鸣器和无源蜂鸣器。
有源蜂鸣器:内部自带振荡源,将正负极街上直流电压(达到要求)即可持续发出声音,频率固定的。
无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可以持续发出声音。调整提供脉冲的振荡脉冲频率可以发出不同频率的声音的(设计的时候不能让无源蜂鸣器一直处于通电状态当中)开发板使用的就是无源蜂鸣器。
注→蜂鸣器只能发出一种鸣叫的声音(音色是只有一种的不能发出像其它乐理的声音)
NPN三极管⇢高电平触发。
PNP三极管⇢低电平触发。
注→在三极管的基极信号当中,这里的基极电阻的范围1k~10k都是可以的。
集成电路驱动:VCC连接了一个电阻再连接到蜂鸣器的一根引脚另一个脚的(BZ)的网络编号另一头连接到了五线四相步进电机(ULN2003)连接到OUT5(BZ)P15是单片机的引脚相当于控制信号。注:在这里的话给P15(高电平"1")的话是有驱动的,原因是里面有一个(非门)如下图原理图所示↓那么我们要让我们的单片机蜂鸣器响应也非常的简单我们给BZ低电平即可。
乐理
在学习蜂鸣器的同时我们也需要掌握一些基础的乐理这样我们就可以使用蜂鸣器来演奏不同的歌曲了。下面是钢琴键盘的无限谱对照表如下↓
降记号(b)表示将基本音级的音高降低半音,根据该记号所在的线或间而降音。
还原记号:表示把已经升高或降低的音还原。
升记号(#)表示将基本音级的音高升高半音,根据该记号所在的线或间而降音。
如下是音符,像我们最熟知的小⭐⭐基本以四分音符为一拍的。
我们可以列一个时间的基准值假设为0.5(s)那么二分音符就是1s、全音符就是2s。八分音符就是0.25(s)依次类推,从上述我们观察可以得出都是以2倍为β倍的。
红色框线中向上弯曲的曲线叫延音线,它可以将两个或两个以上相同音高的音符相连,在钢琴演奏时作爲一个音符,它的拍值等于这些音符的拍值总和。当然延音线也可以用向下弯曲的曲线表示。
音频与频率对照表
通过上述的音频与频率对照表根据频率(HZ)的值可以控制定时器产生相应频率的计时。如何用单片机产生频率就可以用定时器+中断。
周期的单位(s):T = 1/f(频率) 由于转换的时间单位数值比较小(s)单位的话,那么我们把周期时间单位转换成(us)乘以10^6次方。
注⇢在这里周期/2(us)是因为一个周期的占空比是(50%)也就是半个周期的高电平以及半个周期的低电平。重装载值就是定时器当中计数值在这里总数是65535us减去的数字是溢出差值这个就是决定了它的一个音调频率的一个值了。在写程序的时候我们可以把这些存放进数组当中去。然后获取相对应的值放到定时器中断当中即可。如果对这个定时器不熟悉或者是忘了的话可以看博主前面的文章哟(●'◡'●)
让蜂鸣器响应发声的话特别容易我们只需要把IO口翻转一下即可。
#include <REGX52.H>
sbit Buzzer = P1^5;
int main(void)
{
Buzzer=!Buzzer;
}
显然上述代码是不允许让蜂鸣器持续发生的,因为我们只是翻转了一次IO口相当于没有发出声音。所以我们需要用到循环和延迟保证让它翻转的时间够长。如下代码所示↓
#include <REGX52.H>
sbit Buzzer = P1^5;
void Delay(unsigned int xms)
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}
}
int main(void)
{
unsigned int i;
while(1)
{
for(i=0;i<500;i++)
{
Buzzer=!Buzzer;
Delay(1);
}
}
}
在上述代码当中是每隔1ms可以翻转一次IO口电平。
周期时间为高电平1ms低电平1ms一个周期时间为2ms。频率f=1/T=500HZ。
这里循环1次是1ms。那么这里的i<500就会以500HZ的频率响应500ms。
同理如果我们改成i<100的话会以100HZ的频率响应100ms。
#include <REGX52.H>
#include <INTRINS.H>
//蜂鸣器端口:
sbit Buzzer=P1^5;
/**
* @brief 蜂鸣器私有延时函数,延时500us
* @param 无
* @retval 无
*/
void Buzzer_Delay500us() //@12.000MHz
{
unsigned char i;
_nop_();
i = 247;
while (--i);
}
/**
* @brief 蜂鸣器发声
* @param ms 发声的时长(ms),范围:0~32767
* @retval 无
*/
void Buzzer_Time(unsigned int ms)
{
unsigned int i;
for(i=0;i<ms*2;i++)
{
Buzzer=!Buzzer;
Buzzer_Delay500us();//f=1/1ms=1000HZ,一个时间周期翻转两次。
}
}