【51单片机】蜂鸣器演奏音乐《海阔天空》

一.  蜂鸣器的介绍 

1.蜂鸣器介绍 
  蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计 算机、 打印机、 复印机、 报警器、 电子玩具、 汽车电子设备、 电话机、 定 时器等电子产品中作发声器件。蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。 

2.压电式蜂鸣器 (无源蜂鸣器)
  压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳 等组成。多谐振荡器由晶体管或集成电路构成,当接通电源后(1.5~15V 直流工 作电压),多谐振荡器起振,输出 1.5~5kHZ 的音频信号,阻抗匹配器推动压电 蜂鸣片发声。 

3.电磁式蜂鸣器 (有源蜂鸣器)
  电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。接通电 源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场,振动膜 片在电磁线圈和磁铁的相互作用下,周期性地振动发声。

4.区别 
  对于无源蜂鸣器,如果改变频率就可以调节蜂鸣器音调,产生各种不同音色、 音调的声音。如果改变输出电平的高低电平占空比,则可以改变蜂鸣器的声音大小。

  对于有源蜂鸣器,通常内部已经固定了频率,对于调节频率或占空比可能改 变不了蜂鸣器的音调和音量,当然也有的有源蜂鸣器可以实现和无源蜂鸣器一样的效果。

  其实一句话就可概括它们之间的区别,想要压电式蜂鸣器发声,需提供一定 频率的脉冲信号;想要电磁式蜂鸣器发声,只需提供电源即可。

注意:有源与无源指的是内部有无LCD振荡电路。

5. 51单片机所使用的蜂鸣器 
  我们开发板上使用的蜂鸣器是无源蜂鸣器,属于压电式蜂鸣器类型。这里说 的有源和无源,并不是指电源的意思,而是指蜂鸣器内部是否含有振荡电路,有源蜂鸣器内部自带振荡电路,只需提供电源即可发声,而无源蜂鸣器则需提供一 定频率的脉冲信号才能发声,频率大小通常在 1.5-5KHz 之间。

二.  蜂鸣器放大电路原理  


  由于单片机内直接产生的电流过小无法使蜂鸣器正常工作,因此我们需要运用放大电路进行电流放大,下面是两种不同的放大方式:

1. 三极管放大电路

(1)三极管介绍 
 1.半导体三极管也称为晶体三极管,可以说它是电子电路中最重要的器件。三极管顾名思义具有三个电极。二极管是由一个PN结构成的,而三极管由两个PN结构成,共用的一个电极成为三极管的基极(用字母b表示)。其他的两个电极成为集电极(用字母c表示)和发射极(用字母e表示)。由于不同的组合方式,形成了一种是NPN型的三极管,另一种是PNP型的三极管。

2. 晶体三极管

是半导体基本元器件之一,具有电流放大作用,是电子电路的核心元件。它最主要的功能是电流放大和开关作用。三极管是在一块半导体基片上制作两个相距很近的PN结,两个PN结把正块半导体分成三部分,中间部分是基区,两侧部分是发射区和集电区,排列方式有PNP和NPN两种。 

两种不同的三极管内部电流:

2)三极管放大电路 

左图为共阳极,右图为共阴极,且图中Buzzer指蜂鸣器。

3.蜂鸣器模块图

 三、基本乐理知识

一、乐理知识

1、键盘与音符对照

 2、音符时值

3、索引与频率对照表

 二、乐谱

四.  程序设计 

代码部分:

Delay.c

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

Delay.h

#ifndef __DELAY_H__
#define __DELAY_H__

void Delay(unsigned int xms);

#endif

Timer0.c

#include <REGX52.H>

/**
  * @brief  定时器0初始化,1毫秒@12.000MHz
  * @param  无
  * @retval 无
  */
void Timer0Init(void)
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0=1;
	EA=1;
	PT0=0;
}

/*定时器中断函数模板
void Timer0_Routine() interrupt 1
{
	static unsigned int T0Count;
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=1000)
	{
		T0Count=0;
		
	}
}
*/

Timer0.h

#ifndef __TIMER0_H__
#define __TIMER0_H__

void Timer0Init(void);

#endif

main.c

#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"

//蜂鸣器端口定义
sbit Buzzer=P2^5;

//播放速度,值为四分音符的时长(ms)
#define SPEED	700

//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号#
#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
#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
#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

//索引与频率对照表
unsigned int FreqTable[]={
	0,
	63776,63871,63968,64053,64139,64215,64290,64359,64425,64488,64546,64602,
	64654,64703,64750,64794,64836,64875,64912,64947,64980,65011,65041,65069,
	65095,65119,65143,65165,65186,65205,65224,65241,65258,65273,65288,65302,
};

//乐谱
unsigned char code Music[]={
	//音符,时值,
	M7,4,
	H4,4,
	H3,8,
	
	H2,2,
	H1,2,
	M7,2,
	M6,4,
	M4,2,
	M5,2,
	H1,2,
	M4,2,
	P,2,
	M3,4,
	
	
	P,2,
	M4,2,
	M5,2,
	H1,2,
	M4,2,
	P,2,
	M3,4,
	//
	P,2,
	M4,2,
	M5,2,
	H2,2,
	
	H1,6,
	M4,6,
	M7,4,
	M6,6,
	
	P,3,
	//今天我
	M3,2,
	M2,2,
	M1,8,
	P,4,
	M2,1,
	M3,1,
	
	M5,2,
	M5,1,
	M5,1+2,
	M6,2,
	M5,4,
	P,2,
	M6,1,
	M7,1,
	
	H1,2,
	H1,1,
	H1,1+2,
	H1,2,
	H1,2,
	M7,2,
	M6,1,
	M5,2,
	M6,9,
	
	P,4,
	
	M6,2,
	M5,2,
	
	M5,6,
	M5,2,
	M3,1,
	M2,1,
	M1,2,
	M3,2,
	M4,2,
	
	
	M3,2,
	M2,2,
	M2,2,
	M3,1,
	M2,1+4,
	M3,2,
	M2,1,
	M2,3,
	
	
	M1,2,
	M1,2,
	M1,1,
	M1,5,
	M2,2,
	M1,2,
	
	M1,6,
	
	P,6,
	M6,1,
	M7,1,
	
	H1,2,
	H1,1,
	H1,3,
	H1,2,
	M7,2,
	M6,2,
	M5,1,
	M5,3,
	
	M5,4,
	M3,2,
	M2,2,
	M1,4,
	
	//也会怕有一天会跌倒
	P,2,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,1,
	H2,2,
	H2,2,
	H1,1,
	H2,2,
	H3,6,
	P,2,
	H3,3,
	H2,2,
	H1,1,

	
	P,6,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,3,
	P,2,
	M5,1,
	M5,1,
	
	
	
	H3,4,
	H2,4,
	H1,8,
	
	P,2,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,3,
	H2,1,
	H2,1,
	H1,1,
	M7,2,
	H1,9,
	
	
	//仍然自由自我
	P,4,
	M6,2,
	M6,2,
	M7,2,
	M6,2,
	M7,2,
	H1,8,
	
	//永远高唱我歌
	H1,1,
	H1,1,
	H2,2,
	H1,2,
	H2,2,
	H3,8,
	
	//走遍千里
	H3,2,
	H2,6,
	H3,2,
	H1,8,
	
	
	//原谅我
	P,2,
	M6,1,
	M7,1,
	
	H1,2,
	H1,1,
	H1,3,
	H1,2,
	M7,2,
	M6,2,
	M5,1,
	M5,3,
	
	M5,4,
	M3,2,
	M2,2,
	M1,4,
	
	P,4,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,1,
	H2,2,
	H2,2,
	H1,1,
	H2,2,
	H3,9,
	
	
	H3,3,
	H2,2,
	H1,1,
	
	P,2,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,3,
	P,2,
	M5,1,
	M5,1,
	
	H3,4,
	H2,4,
	H1,8,
	
	P,2,
	H1,1,
	H1,1,
	H1,2,
	H1,1,
	H2,3,
	H2,1,
	H2,1,
	H1,1,
	M7,2,
	H1,9,
	
	0xFF	//终止标志
};

unsigned int FreqSelect,MusicSelect;

void main()
{
	Timer0Init();
	while(1)
	{
		if(Music[MusicSelect]!=0xFF)	//如果不是停止标志位
		{
			FreqSelect=Music[MusicSelect];	//选择音符对应的频率
			MusicSelect++;
			Delay(SPEED/4*Music[MusicSelect]);	//选择音符对应的时值
			MusicSelect++;
			TR0=0;
			Delay(5);	//音符间短暂停顿
			TR0=1;
		}
		else	//如果是停止标志位
		{
			TR0=0;
			while(1);
		}
	}
}

void Timer0_Routine() interrupt 1
{
	if(FreqTable[FreqSelect])	//如果不是休止符
	{
		/*取对应频率值的重装载值到定时器*/
		TL0 = FreqTable[FreqSelect]%256;		//设置定时初值
		TH0 = FreqTable[FreqSelect]/256;		//设置定时初值
		Buzzer=!Buzzer;	//翻转蜂鸣器IO口
	}
}

最终项目结构是这样的

实验结果

《海阔天空》Beyond

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值