蜂鸣器
蜂鸣器介绍
蜂鸣器将电信号转换为声音信号,是一种一体化结构器件,采用直流电压供电,广泛应用于电子产品中作为发声器件。51单片机上使用的是无源蜂鸣器。
-
两种类型:
无源蜂鸣器(压电式):不带振荡源,需要提供一定频率的脉冲信号
有源蜂鸣器(电磁式):自带振荡源,只需提供电源,正负极接上直流电压即可持续发声,频率固定
“源”是指蜂鸣器内部是否自带"振荡源"
-
改变音调——脉冲信号频率一定时,周期一定,改变高电平输出所占的周期时间——改变“占空比”(增加高电平时长,音调高;缩短高电平时长,音调低)
-
改变音色——改变周期
-
无源蜂鸣器发出声音的频率(可变约1.5~5KHz)
有源蜂鸣器通常频率固定,周期、占空比不变
占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例
驱动电路
51单片机I/O口驱动能力较弱,不能够直接驱动蜂鸣器,所以不直接使用对应引脚直接控制,而需要利用一些放大电路。所以单片机起到控制作用,控制“驱动电路”来运行设备。
-
三极管驱动:
利用三极管饱和和截止的两个状态,从而构成三极管开关
NPN:高电平导通
PNP:低电平导通 -
集成电路驱动:
利用ULN2003D驱动芯片,可以实现驱动蜂鸣器的操作
芯片内部有“非门”结构(在达林顿管中,具有很强的驱动能力),输入高电平,则输出低电平,蜂鸣器另一端接VCC,从而实现驱动
乐理知识
-
C调音符与频率对照表
-
频率与周期
-
正推
根据一设定好的定时器函数,直接引用头文件到此工程主函数中
定时器每1ms执行中断程序一次,即反转1次;反转两次为1个周期,为2ms。T=2ms,频率=1/0.002=500Hz
已知周期
即当定时器为1ms(1000us)时,补码为64535,TH=0xFC,TL=0x18,蜂鸣器以500Hz响 -
反推
已知各音符的频率时,周期=1/频率
还要计算半周期:一个周期高电平反转两次,所以半个周期改变一次(周期取整/2)
由于定时器计数溢出后才能进入中断使蜂鸣器响应,提前赋值好中断服务程序中的TH、TL即可实现演奏音乐
TH=补码/256;
TL=补码%256;
十六位二进制数,用2^8取整为高8位,取余为低8位。类似于两位十进制数,用10取整为高位,取余为低位
代码实现
#include <REGX52.H>
#include "Delay.h"
#include "time0_init.h"
#include "LCD1602.h"
//注意头文件引用,因为用了LCD显示字符串,所以外加了LCD1602的头文件
sbit Buzzer=P2^5;
//sbit P0_0=P0^0;//即定义P0_0为P0口的第1位
//根据蜂鸣器、ULN2003D原理图定义 sbit Buzzer=P2^5;
#define SPEED 60
//定义了反转的时间变量(改变播放音乐速度)
//宏定义(各个音符的频率放在数组中,定义音符的数组索引号)
#define P 0
//休止符
#define L1 1
#define L1_ 2
#define L2 3
#define L2_ 4
#define L3 5
#define L4 6
#define L4_ 7
#define L5 8
#define L5_ 9
#define L6 10
#define L6_ 11
#define L7 12
//LOW低音
#define M1 13
#define M1_ 14
#define M2 15
#define M2_ 16
#define M3 17
#define M4 18
#define M4_ 19
#define M5 20
#define M5_ 21
#define M6 22
#define M6_ 23
#define M7 24
//MIDDLE中音
#define H1 25
#define H1_ 26
#define H2 27
#define H2_ 28
#define H3 29
#define H4 30
#define H4_ 31
#define H5 32
#define H5_ 33
#define H6 34
#define H6_ 35
#define H7 36
//HIGH高音
unsigned int FreqTable[]={
0,
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,65216,65235,65252,65268,65283
};
//音符频率数组,为改变TH、TL
//加"code"是因为51单片机中RAM:512字节(内存太小);ROM:8K(Flash)
unsigned char code Music[]={
//曲目:春节序曲
H3,2,
H3,1,
H2,1,
H1,4,
H3,2,
H3,1,
H2,1,
H1,4,
H3,2,
H3,1,
H2,1,
H1,2,
M5,2,
M3,2,
M6,2,
M5,3,
M6,1,
M5,2,
M6,2,
M5,3,
M6,1,
M5,2,
M6,2,
M5,2,
M7,1,
M6,1,
M5,2,
M7,1,
M6,1,
M5,2,
M7,1,
M6,1,
M5,2,
M7,1,
M6,1,
M5,1,
M6,1,
M5,1,
M6,1,
M5,1,
M6,1,
M7,1,
M6,1,
M5,4,
M5,4,
M5,8,
M5,2,
M5,1,
M6,1,
M5,2,
M5,1,
M6,1,
H1,2,
H1,1,
M6,1,
H1,2,
H1,1,
H2,1,
H3,2,
H3,1,
H2,1,
H3,2,
H3,1,
H2,1,
H3,2,
H3,1,
H2,1,
H1,2,
H1,1,
M6,1,
M5,2,
M5,1,
M6,1,
M5,2,
M5,1,
M6,1,
H1,2,
H1,1,
M6,1,
H1,2,
H1,1,
H2,1,
H3,2,
H3,1,
H2,1,
H3,2,
H3,1,
H2,1,
H3,2,
H3,1,
H2,1,
H1,2,
H1,1,
M6,1,
M5,2,
M5,1,
M6,1,
H1,2,
H1,1,
H2,1,
H3,2,
H3,1,
H2,1,
H1,2,
P,2,
H1,3,
M6,1,
H1,2,
M6,2,
M5,2,
H1,2,
M6,2,
M5,2,
M3,2,
M5,2,
M2,2,
M3,2,
M5,2,
M6,2,
M3,2,
M3,1,
M2,1,
M1,2,
H3,2,
H3,1,
H2,1,
H1,8,
0xFF
};
void main()
{
LCD_Init();
LCD_ShowString(1,3,"2 0 2 3");
LCD_ShowString(2,2,"HAPPY NEW YEAR");
time0_init();
while(1)
{
//判断是否终止,如果终止就关闭定时器
if(Music[MusicSelect]!=0xFF)
{
FreqSelect=Music[MusicSelect];
MusicSelect++;
//曲子中,4为4分音符即一拍,2为8分音符即半拍,1为16分音符
//SPEED变量使速度可控
Delay(SPEED/4*Music[MusicSelect]);
MusicSelect++;
//为了使两个音有断开的效果:定时器一开一关
TR0=0;
Delay(5);
TR0=1;
}
else
{
TR0=0;
while(1);
}
}
}
void time() interrupt 1 //中断服务函数
{
if(FreqTable[FreqSelect]!=0)
{
TH0=FreqTable[FreqSelect]/256;
TL0=FreqTable[FreqSelect]%256;
Buzzer=!Buzzer; //蜂鸣器发声
}
}