蜂鸣器是什么?
蜂鸣器是什么呢?相信大家在做项目中肯定多多少少都会用到蜂鸣器,蜂鸣器呢是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。比如台式电脑的主机开机会”滴”一声、洗衣机按下按键及洗衣完成都会有声响,以上这些声音都是通过蜂鸣器来发出的。
蜂鸣器按驱动方式可分为有源蜂鸣器(内含驱动线路)和无源蜂鸣器(外部驱动)。这里的“源”指的是激励源。
无源蜂鸣器内部没有激励源,只有给它一定频率的方波信号,才能让蜂鸣器的振动装置起振,从而实现发声,同时,输入的方波频率不同,发出的声音也不同(所以无源蜂鸣器可以模拟曲调实现音乐效果)。
有源蜂鸣器则不需要外部的激励源,只需要接入直流电源,即可自动发出声音(声音频率相对固定)。
由于有源蜂鸣器较为简单,只需要单片机给出高低电平即可控制其工作发声(还需借助三极管放大电路),与点亮LED很类似,所以本节就不重点讨论有源蜂鸣器,只分享如何控制无源蜂鸣器按照预设的频率发出相对应的音调。
分享一篇文章详细介绍蜂鸣器,里面介绍了蜂鸣器的种类和一些简单的硬件知识,感兴趣的可以看看,传送门:(蜂鸣器)
无源蜂鸣器工作原理
无源蜂鸣器
需要1.5~2.5kHz
(与蜂鸣器种类有关)的音频信号,这个音频信号即一个高低变化频率为1.5-2.5kHz的方波
。实际上频率小于1.5kHz也是有声音的,只是不那么准了,可能是嘟嘟
声。
单片机产生音乐音调的原理:
音乐音调的产生主要是通过单片机的I/O口输出高低不同的脉冲信号来控制蜂鸣器发音,要想产生音频脉冲信号,需要算出某音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。利用单片机定时器计时这个半周期的时间,每当计时到后就输出脉冲的I/O口反相,这样就在此I/O口上得到此脉冲的频率。
通常,利用单片机的内部定时器0,工作在方式一下,改变计数初始值TH0和TL0来产生不同的率。
例如,若单片机采用12MHzs晶振,要产生频率为587Hzs的音频脉冲时,其音频信号的脉冲周期T=1/587=1703.5775us,半周期时间为852us,因此总要令计时器计数=852us/1us=852,在每计数852时将I/O口反相,就得到C大调的中调Re。
由于定时器0的在方式一计数方式为16位计数器,最多只能装载的数为2的16次方即65536个,也就是说定时器计数到65536就会进入中断函数,而在中断函数中将输出脉冲的I/O口反相即可,故只需设置好定时器0的初值就可以了发出特定的音频了。初值与音频的对应关系见下表所示:
音频 | 定时器初值 |
低1do | 63628 |
低2re | 63835 |
低3mi | 64021 |
低4fa | 64103 |
低5so | 64260 |
低6la | 64400 |
低7si | 64524 |
中1do | 64580 |
中2re | 64684 |
中3mi | 64777 |
中4fa | 64820 |
中5so | 64898 |
中6la | 64968 |
中7si | 65030 |
高1do | 65058 |
高2re | 65110 |
高3mi | 65157 |
高4fa | 65160 |
高5so | 65217 |
高6la | 65252 |
高7si | 65282 |
如何实现无源蜂鸣器发出特定的频率呢
ps:本文使用的例程芯片是MS51FB9AE
BEEP.H
#ifndef __BEEP__H___#define __BEEP__H___typedef struct __BEEP{ uint8_t select; uint8_t Music[20];uint8_t Stop_Index; uint8_t OpenBeep_Flag; }BEEP_DATA;extern BEEP_DATA BEEP_Data; void BEEP_GPIO_INIT(void);void BEEP_Poll(void);void BEEP_INIT(void);void Timer0Init(void);void BEEP_Start(void);void Clear_Music_Buf(void);void PowerON_Beep(void);void PowerOFF_Beep(void);#endif
BEEP_BOT.C
#include "MS51FB9AE.h"#include "beep.h"unsigned int code FreqTable[]={0,//停止符//dodo# re re#mi fafa# soso# lala#si //1 2 3 4 56789 10111263628,63731,63835,63928,64021,64103,64185,64260,64331,64400,64463,64524, //低音 //1314151617 181920 21 22232464580,64633,64684,64732,64777,64820,64860,64898,64934,64968,65000,65030, //中音 //2526272829 303132 33 34 353665058,65085,65110,65134,65157,65178,65198,65217,65235,6525,65268,65283, //高音};/****************************************** @description:* @param:void* @retval:void****************************************/void BEEP_GPIO_INIT(){P05=0;P05_PUSHPULL_MODE;P05=0;//配置蜂鸣器引脚Timer0Init();//定时器初始化}/****************************************** @description:* @param:void* @retval:void****************************************/void Timer0Init(){ENABLE_TIMER0_MODE1;//Timer 0 and Timer 1 mode configurationclr_T0M; TL0 = FreqTable[BEEP_Data.select]%256;TH0 = FreqTable[BEEP_Data.select]/256;set_ET0;//enable Timer0 interruptset_EA; //enable interruptsset_TR0;//Timer0 run}/****************************************** @description:* @param:void* @retval:void****************************************/void Timer0_TSR(void) interrupt 1{ if(FreqTable[BEEP_Data.select]){TL0 = FreqTable[BEEP_Data.select]%256;TH0 = FreqTable[BEEP_Data.select]/256;P05 = !P05;}}
BEEP_MID.C
#include "MS51FB9AE.h"#include "BEEP.h"/****************************************** @description:* @param:void* @retval:void****************************************/void Clear_Music_Buf(void){uint8_t i =0;for(i=0;i<22;i++) BEEP_Data.Music[i]=0x00;}/****************************************** @description:* @param:void* @retval:void****************************************/void BEEP_Start(void){uint8_t MusicSelect = 0x00,i=0;for(i=0;i<=BEEP_Data.Stop_Index;i++){BEEP_Data.select=BEEP_Data.Music[MusicSelect++];delay_ms(20);TR0=0;delay_ms(5);TR0=1;}Clear_Music_Buf();}
BEEP_TOP.C
#include "MS51FB9AE.h"#include "beep.h"BEEP_DATA BEEP_Data;/****************************************** @description:* @param:void* @retval:void****************************************/void BEEP_INIT(void){BEEP_Data.select =0x00;BEEP_GPIO_INIT();BEEP_Data.OpenBeep_Flag=0x01;}/****************************************** @description: * @param:void* @retval:void****************************************/void BEEP_Poll(void){uint8_t MusicSelect = 0x00,i=0;if(BEEP_Data.OpenBeep_Flag){ BEEP_Data.OpenBeep_Flag=0x00;for(i=0;i<=BEEP_Data.Stop_Index;i++){BEEP_Data.select=BEEP_Data.Music[MusicSelect++];delay_ms(20);TR0=0;delay_ms(5);TR0=1;}Clear_Music_Buf();}}/****************************************** @description:* @param:void* @retval:void****************************************/void PowerON_Beep(void){BEEP_Data.Stop_Index=3; BEEP_Data.Music[0]=13;BEEP_Data.Music[1]=15;BEEP_Data.Music[2]=17;BEEP_Data.Music[3]=0;}/****************************************** @description:* @param:void* @retval:void****************************************/void PowerOFF_Beep(void){BEEP_Data.Stop_Index=3; BEEP_Data.Music[0]=17;BEEP_Data.Music[1]=15;BEEP_Data.Music[2]=13;BEEP_Data.Music[3]=0;BEEP_Start();}/****************************************** @description:* @param:void* @retval:void****************************************/void ChangeSpeedUnit_Beep(void){BEEP_Data.Stop_Index=2; BEEP_Data.Music[0]=6;BEEP_Data.Music[1]=8;BEEP_Data.Music[2]=0; BEEP_Start();}
最后在main函数中初始化蜂鸣器BEEP_INIT(),每25ms调用一次BEEP_Poll()函数,在你需要的地方填写相对用的函数即可。例如,关机的时候调用PowerOFF_Beep(),开机的时候调用PowerOn_Beep()。