51单片机蜂鸣器的程序设计

2020-08-26 18:41发布

蜂鸣器发声原理是电流通过电磁线圈,使电磁线圈产生磁场来驱动振动膜发声的,因此需要一定的电流才能驱动它,单片机IO引脚输出的电流较小,单片机输出的TTL电平基本上驱动不了蜂鸣器,因此需要增加一个电流放大的电路。三极管的作用为驱动,通过三极管放大驱动电流,从而可以让蜂鸣器发出声音。  

有源蜂鸣器和无源蜂鸣器的区别:

这里的“源”不是指电源。而是指震荡源。 也就是说,有源蜂鸣器内部带震荡源,所以只要一通电就会叫。 


而无源内部不带震荡源,所以如果用直流信号无法令其鸣叫。必须用2K~5K的方波去驱动它。 


有源蜂鸣器往往比无源的贵,就是因为里面多个震荡电路。 


无源蜂鸣器的优点是:1。便宜,2。声音频率可控,可以做出“多来米发索拉西”的效果。3。在一些特例中,可以和LED复用一个控制口 有源蜂鸣器的优点是:程序控制方便 。  


例程,参考自网络。


/************************************************************************ [文件名] C51音乐程序(八月桂花) [功能] 通过单片机演奏音乐 /**********************************************************************/ 
#include 
#include 
//本例采用89C52, 晶振为11.0592MHZ //关于如何编制音乐代码, 其实十分简单,各位可以看以下代码. //频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍; //所以拿出谱子, 试探编吧! 
sbit Beep = P1^5 ; 
unsigned char n=0; //n为节拍常数变量 
unsigned char code music_tab[] ={ 0x18, 0x30, 0x1C , 0x10, //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数, 
0x20, 0x40, 0x1C , 0x10, 0x18, 0x10, 0x20 , 0x10, 0x1C, 0x10, 0x18 , 0x40, 0x1C, 0x20, 0x20 , 0x20, 0x1C, 0x20, 0x18 , 0x20, 0x20, 0x80, 0xFF , 0x20, 0x30, 0x1C, 0x10 , 0x18, 0x20, 0x15, 0x20 , 0x1C, 0x20, 0x20, 0x20 , 0x26, 0x40, 0x20, 0x20 , 0x2B, 0x20, 0x26, 0x20 , 0x20, 0x20, 0x30, 0x80 , 0xFF, 0x20, 0x20, 0x1C , 0x10, 0x18, 0x10, 0x20 , 0x20, 0x26, 0x20, 0x2B , 0x20, 0x30, 0x20, 0x2B , 0x40, 0x20, 0x20, 0x1C , 0x10, 0x18, 0x10, 0x20 , 0x20, 0x26, 0x20, 0x2B , 0x20, 0x30, 0x20, 0x2B , 0x40, 0x20, 0x30, 0x1C , 0x10, 0x18, 0x20, 0x15 , 0x20, 0x1C, 0x20, 0x20 , 0x20, 0x26, 0x40, 0x20 , 0x20, 0x2B, 0x20, 0x26 , 0x20, 0x20, 0x20, 0x30 , 0x80, 0x20, 0x30, 0x1C , 0x10, 0x20, 0x10, 0x1C , 0x10, 0x20, 0x20, 0x26 , 0x20, 0x2B, 0x20, 0x30 , 0x20, 0x2B, 0x40, 0x20 , 0x15, 0x1F, 0x05, 0x20 , 0x10, 0x1C, 0x10, 0x20 , 0x20, 0x26, 0x20, 0x2B , 0x20, 0x30, 0x20, 0x2B , 0x40, 0x20, 0x30, 0x1C , 0x10, 0x18, 0x20, 0x15 , 0x20, 0x1C, 0x20, 0x20 , 0x20, 0x26, 0x40, 0x20 , 0x20, 0x2B, 0x20, 0x26 , 0x20, 0x20, 0x20, 0x30 , 0x30, 0x20, 0x30, 0x1C , 0x10, 0x18, 0x40, 0x1C , 0x20, 0x20, 0x20, 0x26 , 0x40, 0x13, 0x60, 0x18 , 0x20, 0x15, 0x40, 0x13 , 0x40, 0x18, 0x80, 0x00 }; 

void int0() interrupt 1 //采用中断0 控制节拍 
{ 
TH0=0xd8; 
TL0=0xef; 
n--; 
} 

void delay (unsigned char m) //控制频率延时 
{ 
unsigned i=3*m; 
while(--i); 
} 

void delayms(unsigned char a) //豪秒延时子程序 
{ while(--a); //采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了! 
} 

void main() { 
unsigned char p,m; //m为频率常数变量 
unsigned char i=0; 
TMOD&=0x0f; 
TMOD|=0x01; 
TH0=0xd8;TL0=0xef; 
IE=0x82; 
play: 
while(1) 
{ 
a: p=music_tab[i]; 
if(p==0x00) 
{ 
i=0, delayms(1000); 
goto play;
} //如果碰到结束符,延时1秒,回到开始再来一遍 
else 
if(p==0xff) 
{ 
i=i+1;
delayms(100),TR0=0; 
goto a;
} //若碰到休止符,延时100ms,继续取下一音符 
else 
{
m=music_tab[i++], n=music_tab[i++];
} //取频率常数 和 节拍常数 
TR0=1; //开定时器1 
while(n!=0)
 Beep=~Beep,delay(m); //等待节拍完成, 通过P1口输出音频(可多声道哦!)            
TR0=0; //关定时器1 } }