十一、蜂鸣器
1、蜂鸣器的原理
a、无源蜂鸣器
(1)早期蜂鸣器都是无源的
(2)内部构造和材料:材料为两个金属片。其平行放置,距离很近
(3)发声原理:方波信号输入谐振装置转换为声音信号输出从而发出声音。
(4)控制信号:高低电平相间的信号
(5)电路图:蜂鸣器一段接电阻接地,另一端接一个NPN三极管的N级,三极管另一个N级接电源VCC,
单片机引脚接三极管的P级,控制两个N级的导通与否。
(6)音调如何控制,音调受震动频率控制,就等于控制信号的频率。频率越高音调越高,听起来就越刺
耳。频率越低音调越低,声音听起来就越厚重。
(7)声音大小如何控制,受硬件决定的,不受软件控制,无法写代码来控制声音大小的控制。
b、有源蜂鸣器
(1)无源蜂鸣器的缺陷:控制较为麻烦
(2)内置振荡电路后形成有源蜂鸣器
(3)有源蜂鸣器也可以用频率信号驱动
2、让蜂鸣器响起来
a、确定接线:J7链接到P0。0引脚上(这部分依照开发板集体情况和个人喜好而定)
b、最简单:使用delay让蜂鸣器响起来
代码:
while(1)
{
buzzer = 1;
delay_ms();
buzzer = 0;
}
c、调节delay时间感受音调的变化
不同时间的delay蜂鸣器的音调不同,要有比较明显的声音需要微妙级别的延时。毫秒级别声音不明显。
3、用定时器控制蜂鸣器音调
a、上节课驱动方法的问题
(1)不容易精准控制时间
(2)CPU控制蜂鸣器的时候不可以做其他事情
b、定时器控制蜂鸣器响
(1)10KHz => (1/10000)s = 0.1ms = 100μs => 高电平加低电平的时间是100μs。所以要定的
时间就是50μs。
(2)外部晶振12MHz + 12T设置 => 内部时钟频率1MHz => 1μs => TL0 = (65536 - 50)%256
THO = (65536 - 50) / 256[此处是加法定时器,如果是减法定时器,那么TL0 = 50,TH0 = 0]
c、音调改变
(1)代码:
#include <REGX51.H>
#include <intrins.h>
#define smg P2
#define xhz 20
#define count (1000000/(2*xhz))
#define low ((65536-count)%256)
#define high ((65536-count)/256)
sbit buzzer = P0^0; //buzzer的驱动引脚
unsigned char duan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void delay(unsigned int t);
void tim0_buzzer() interrupt 1 using 1
{
TL0 = low;
TH0 = high;
buzzer = ~buzzer;
}
void main(void)
{
unsigned char i;
TMOD = 0x01;
TL0 = low;
TH0 = high;
TR0 = 1;
ET0 = 1;
EA = 1;
while(1)
{
for (i=0; i<16; i++)
{
smg = duan[i];
delay(150);
}
}
}
void delay(unsigned int t)
{
while(t--)
{
unsigned char i = 2;
unsigned char j = 239;
do
{
while(--j);
}while(--i);
}
}
(2)结论:通过该xhz这个宏的值就修改蜂鸣器的音调。总的来说xhz越大声音越尖锐,xhz越小声音越
低沉。
4、蜂鸣器发出滴滴声
代码:
#include <REGX51.H>
#define smg P2
#define xhz 1000
#define count (1000000/(2*xhz))
#define low ((65536-count)%256)
#define high ((65536-count)/256)
#define num (xhz/2)
sbit buzzer = P0^0; //buzzer的驱动引脚
unsigned int j;
unsigned char flag = 0;
unsigned char duan[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e};
void delay(unsigned int t);
void tim0_buzzer() interrupt 1 using 1
{
TL0 = low;
TH0 = high;
if(j-- == 0)
{
if(flag == 0)
{
j = num*10;
flag = 1;
}else
{
j = num;
flag = 0;
buzzer = !buzzer;
}
}
else
{
if(flag == 0)
{
buzzer = !buzzer;
}else
{
}
}
}
void main(void)
{
unsigned char i;
TMOD = 0x01;
TL0 = low;
TH0 = high;
TR0 = 1;
ET0 = 1;
EA = 1;
j = num;
flag = 0;
buzzer = 1;
while(1)
{
for (i=0; i<16; i++)
{
smg = duan[i];
delay(150);
}
}
}
void delay(unsigned int t)
{
while(t--)
{
unsigned char i = 2;
unsigned char j = 239;
do
{
while(--j);
}while(--i);
}
}
5、让蜂鸣器唱歌1
a、为什么蜂鸣器可以唱歌?
(1)发声音调可变
(2)发声长度可变
b、体验已经写好的唱歌程序
(1)复制代码
(2)修改蜂鸣器的IO引脚定义
c、理解代码
(1)按照习惯调好代码风格再去看。
6、让蜂鸣器唱歌2
a、简单的学习如何看简谱
简谱:(数字下方有两点)1 2 3 4 5 6 7
唱名: do re mi fa sol la si(大字组)
简谱:(数字下方有一点)1 2 3 4 5 6 7
唱名: do re mi fa sol la si(小字组)
简谱:(数字下方没有点)1 2 3 4 5 6 7
唱名: do re mi fa sol la si(小字一组)
简谱:(数字上方有一点)1 2 3 4 5 6 7
唱名: do re mi fa sol la si(小字二组)
(1)1 = D4/4:“4/4”从上往下看其代表以四分音符为一拍,每小节为四拍
(2)简谱中数字下方有横线:音值减半,譬如一个四份音符时长是500ms,加了下划线则变成250ms
(3)简谱数字右边有一个点,那个点被称为附点音符。附点音符代表这个数字代表的音符时长延长二分
之一。譬如一个四分音符时长为500ms,加了附点音符后时长变为500+250 = 750ms。
(4)每个小节的时长是一定的,一般来说一小节的时长都是四个四分音符。
(5)简谱数字后面跟着一个横线代表这个这个音符占据俩拍的时长。譬如一个四分音符时长是500Ms,
那么加了这个符号后时长变为500+500=1000ms。
(6)数字左上角加了一个“#“,代表将这个音符提高半个音级;而相对的左上角加“b”代表降低这个音符
半个音级。
(7)在两个数字上方有一道弧线相连,那么这个弧线被称为延音线,一般连在两个相同的音符之间,代
表在演奏或者播放的时候这两个音符是连续播放的,不是断开的。
(8)下一个音符的频率 = 上一个音符的频率 * 2^(1/12)。譬如在c调中低音1的频率为262Hz,那么
低音1#的频率为262*2^(1/12) = 277.579,与对照表基本相同。
b、代码:
#include <REGX51.H>
#include <intrins.h>
#define SMG P0
#define KEY P1
#define SPEED 500
#define LOW(RNUM) (RNUM%256)
#define HIGH(RNUM) (RNUM/256)
sbit buzzer = P2^7; //buzzer的驱动引脚
unsigned char code duan[16]=
{
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,
0xf8,0x80,0x98,0x88,0x83,0xc6,0xa1,0x86,0x8e
};
unsigned int code FreqTable [38] =
{
63628, 63731, 63835, 63928, 64021, 64103, 64185, 64260, 64331,
64400, 64463, 64524, 64580, 64633, 64684, 64732, 64777, 64820,
64860, 64898, 64934, 64968, 65000, 65030, 65058, 65085, 65110,
65134, 65157, 65178, 65198, 65217, 65235, 65252, 65268, 65283,
0, 0xff
};
unsigned char code music []=
{
12, 12, 19, 19, 21, 21, 19, 17, 17, 16, 16, 14, 14, 12,
19, 19, 17, 17, 16, 16, 14, 19, 19, 17, 17, 16, 16, 14,
12, 12, 19, 19, 21, 21, 19, 17, 17, 16, 16, 14, 14, 12,
36,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2,
};
unsigned char freqselect, musicselect;
void delay(unsigned int t);
void tim0_buzzer() interrupt 1 using 1
{
TL0 = LOW(FreqTable[freqselect]);
TH0 = HIGH(FreqTable[freqselect]);
buzzer = !buzzer;
}
void main(void)
{
unsigned char num = 0;
TMOD = 0x01;
TL0 = LOW(FreqTable[36]);
TH0 = HIGH(FreqTable[36]);
TR0 = 1;
ET0 = 1;
EA = 1;
while(1)
{
if(music[musicselect] != 36)
{
freqselect = (music[musicselect]);
delay(SPEED*(music[musicselect+43]));
musicselect++;
TR0 = 0;
delay(5);
TR0 = 1;
}
else
{
TR0 = 0;
}
}
}
void delay(unsigned int t)
{
while(t--)
{
unsigned char i = 2;
unsigned char j = 239;
do
{
while(--j);
}while(--i);
}
}