大家好,欢迎来到IT知识分享网。
1、蜂鸣器的原理
蜂鸣器分为有源蜂鸣器和无源蜂鸣器。这里的“源”不是指电源,而是指震荡源。
1.1、无源蜂鸣器
(1)早期蜂鸣器都是无源的。
(2)内部没有震荡电路,无源蜂鸣器比有源蜂鸣器更便宜。
(3)无源蜂鸣器内部没有震荡源,需要采用一定频率的方波才可以驱动发声。
(4)通过控制方波频率可以控制蜂鸣器的音调。
(5)声音大小由硬件决定,不能通过单片机程序改变。
(6)物体振动越快,频率越高,音调越高尖。
1.2、有源蜂鸣器
(1)内部有震荡电路,有源蜂鸣器比无源蜂鸣器贵。
(2)只要供电就会发出声音。
(3)不能改音调。
2、原理图
(1)上图为无源蜂鸣器。
(2)三极管的作用是因为单片机引脚驱动能力不够,通过J8引脚控制三级管的开关。
3、示例代码
3.1、让无源蜂鸣器响起来
#include <reg52.h> #include <intrins.h> sbit BUZZER = P0^0; /*无源蜂鸣器驱动引脚*/ void Delay100us(); void main() { while(1) { /*人耳听力频率范围为20Hz~20000Hz*/ Delay100us(); /*频率 = 1/200uS = 0.005MHZ = 5KHz*/ BUZZER = !BUZZER; } } void Delay100us() //@12.000MHz { unsigned char i; _nop_(); i = 47; while (--i); }
3.2、定时器控制蜂鸣器音调
(1)采用软件延时控制无源蜂鸣器的弊端:
不易精准控制时间;CPU控制蜂鸣器中不能做其他事。
(2)使蜂鸣器在100KHz发声
外部晶振12MHz + 12T设置 => 内部时钟频率1MHz => 时钟周期1uS;
10KHz => 1/10000s => 100us =>高电平+低电平一共100us,那高电平和低电平的时间都是50us,所以要定的时间就是50us。
(3)蜂鸣器音调与TH0、TL0寄存器值有关,如需经常修改音调,可写成宏定义。
例如:
#defien TONE 10000 Hz /*宏定义音调频率*/
#define TimingLength (1/TONE) * / 2 /*定时时长uS*/
TH0 = (TimingLength + 1) / 256
TL0 = (TimingLength + 1) % 256
TH0 = us /256
(4)代码
/* *功能:定时器控制蜂鸣器音调 *定时器:使用定时器0 *单片机型号:STC89C516 */ #include <reg52.h> #include <intrins.h> sbit BUZZER = P0^0; /*无源蜂鸣器驱动引脚*/ /*函数声明*/ void Timer0Init(void); /*定时器0初始化,50uS*/ void main() { Timer0Init(); ET0 = 1; //打开T0溢出中断 EA = 1; //打开总中断 while(1) { } } /* *功能: 定时器0初始化,50uS */ void Timer0Init(void) //50微秒@12.000MHz { TMOD &= 0xF0; //设置定时器模式,16位定时器/计数器,TL0、TH0全用,工作在定时器模式下 TMOD |= 0x01; //设置定时器模式 TL0 = 0xCE; //设置定时初始值 0xFF-50+1 = 206 = 0xCE TH0 = 0xFF; //设置定时初始值 TF0 = 0; //定时器溢出标志,清除TF0标志, TR0 = 1; //定时器运行控制位,定时器0开始计数 } /* *功能:定时器0中断处理函数 */ void tm0_isr() interrupt 1 using 1 { TL0 = 0xCE; /*手工重载计数值*/ TH0 = 0xFF; BUZZER = !BUZZER; }
3.3、蜂鸣器发出滴滴声
(1)蜂鸣器有声音一段时间–没声音一端时间–有声音一段时间……
(2)通过调试控制音调和发声时常,无声时常,从而达到自己想要的效果。
(3)代码
/* *功能:蜂鸣器发出滴滴声 *定时器:使用定时器0 *单片机型号:STC89C516 */ #include <reg52.h> #include <intrins.h> sbit BUZZER = P0^0; /*无源蜂鸣器驱动引脚*/ unsigned int count = 0; /*函数声明*/ void Timer0Init(void); /*定时器0初始化,50uS*/ void main() { Timer0Init(); ET0 = 1; //打开T0溢出中断 EA = 1; //打开总中断 while(1) { } } /* *功能: 定时器0初始化,50uS */ void Timer0Init(void) //50毫秒@12.000MHz { TMOD &= 0xF0; //设置定时器模式,16位定时器/计数器,TL0、TH0全用,工作在定时器模式下 TMOD |= 0x01; //设置定时器模式 TL0 = 0xCE; //设置定时初始值 0xFF-50+1 = 206 = 0xCE TH0 = 0xFF; //设置定时初始值 TF0 = 0; //定时器溢出标志,清除TF0标志, TR0 = 1; //定时器运行控制位,定时器0开始计数 } /* *功能:定时器0中断处理函数 */ void tm0_isr() interrupt 1 using 1 { TL0 = 0xCE; /*手工重载计数值*/ TH0 = 0xFF; count++; if(count <= 4000) { BUZZER = !BUZZER; } else if(count>6000 ) { /*count = 4001~6000没声音*/ count = 0; } }
3.4、让蜂鸣器唱歌
为什么蜂鸣器能够模拟唱歌
(1)发声音调可以改变
(2)发声长度可以改变
(3)声音的三个属性:响度、音调、音色。
由于本人没有音乐细胞,对长音短音音符这些不了解,也不想去了解,感兴趣自己百度乐谱和简谱吧。就给出如下示例代码。
/ *功能: 通过单片机演奏音乐(八月桂花) *MCU:STC89C516 *晶振12MHz,12T(12分频) / #include <reg52.h> sbit BUZZER = P0^0; /*无源蜂鸣器驱动引脚*/ unsigned char beat = 0; /*beat为节拍常数变量*/ /*频率常数即音乐术语中的音调,而节拍常数即音乐术语中的多少拍 *格式为:频率常数, 节拍常数, 频率常数, 节拍常数...... */ 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 delay_Hz (unsigned char t); /*控制频率延时*/ void delayms(unsigned char t); /*毫秒延时子程序*/ 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) /*如果碰到结束符,延时1秒,回到开始再来一遍*/ { i=0; delayms(1000); goto play; } else if(p==0xff) /*若碰到休止符,延时100ms,继续取下一音符*/ { i=i+1; delayms(100); TR0=0; goto a; } else /*取频率常数和节拍常数*/ { m=music_tab[i++]; beat=music_tab[i++]; } TR0=1; /*开定时器0*/ while(beat != 0) /*等待节拍完成*/ { BUZZER = !BUZZER; delay_Hz(m); /*m控制频率*/ } TR0=0; /*关定时器0*/ } } /*采用中断0 控制节拍*/ void tim0_isr() interrupt 1 { TH0=0xd8; /*手工重载计数值*/ TL0=0xef; beat--; /*控制节拍*/ } /*控制频率延时*/ void delay_Hz (unsigned char t) { unsigned i=3*t; while(--i); } /*毫秒延时子程序*/ void delayms(unsigned char t) { while(--t); /*采用while(--a) 不要采用while(a--); 各位可编译一下看看汇编结果就知道了!*/ }
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/148487.html