使用51单片机演奏《孤勇者》:蜂鸣器给出的成果展示

目录

硬件部分

蜂鸣器介绍

驱动电路 

ULN2003

乐理部分

音符

音符与频率对照

代码部分

运行结果


        随着最近孤勇者成为小朋友们的接头暗号之后,于是产生了利用单片机去播放孤勇者的想法,接下来我们来看看具体的实现以及效果展示吧!

硬件部分

蜂鸣器介绍

        首先我们使用的是51单片机的蜂鸣器来实现的,所以先来介绍一下蜂鸣器吧,如下图所示!

  • 蜂鸣器是一种将电信号转换为声音信号的器件,常用来产生设备的按键音、报警音等提示信号
  • 蜂鸣器按驱动方式可分为有源蜂鸣器和无源蜂鸣器
  • 有源蜂鸣器:内部自带振荡源,将正负极接上直流电压即可持续发声,频率固定
  • 无源蜂鸣器:内部不带振荡源,需要控制器提供振荡脉冲才可发声,调整提供振荡脉冲的频率,可发出不同频率的声音
  •  

            之前在STM32上的那个蜂鸣器是有源蜂鸣器,频率固定,就只能发声,而在我们的51单片机上的这个蜂鸣器是属于无源蜂鸣器,所以需要我们来调整频率,从而来实现发出不同频率的声音。

    驱动电路 

            之前的32是使用三极管进行驱动的,起到放大信号的作用(不清楚的可以去32的笔记看看)。而51单片机使用的是集成电路进行驱动的(ULN2003),接下来我们来简单介绍一下吧!

    ULN2003

            确实可以简单理解为一个放大电路,因为内部有一个非门,导致给1就有驱动能力(输出0,蜂鸣器才导通,所以才会响),但给0却无驱动能力(高阻态)。

    乐理部分

            接下来就到了单片机最难的部分了,乐理部分,这部分我不是特别清楚,如有错误还望指出。

            首先,每8个一组(C~B),也就是哆唻咪发嗦啦西,分为4组,每一组比上一组高8度。黑键与白键相差半个音调,白色与白色相差一个音调。简谱对应相应的音调也在图中有对应关系,就不一一举出了。但是要介绍一下升音符号(#)以及降音符号(b),比如“#1”就是中央C升高半音,就是右上角的黑键。

    音符

            音符是用来记录不同长短的音的进行符号。全音符二分音符四分音符八分音符十六分音符是最常见的音符,具体的内容大家可以点击超链接去康康。其中四分音符一般是一个时间基准(500毫秒),后面加一个横线就是二分音符,下面加一个横线就是八分音符,以此类推。

    音符与频率对照

    计算周期以及重装载值 

    周期:12/11.0592/B2*1000000(因为我是11.0592HZ的晶振,所以是这样)

    重装载值:65536-D2(65536-周期一半)

    如下图所示:

     

    代码部分

            接下来就是按照我们计算之后的重装载值来进行编码了,在此过程中,还需要我们去了解音乐的简谱,在此我就给出一份简谱,感兴趣的同学可以自己去找相应的简谱来编写代码。


    // Buzzer.c
    #include <REGX52.H>
    #include <INTRINS.H>
    
    //蜂鸣器端口:
    sbit Buzzer=P1^5;
    
    /**
      * @brief  蜂鸣器私有延时函数,延时500us
      * @param  无
      * @retval 无
      */
    void Buzzer_Delay500us()		//@11.0592MHz
    {
    	unsigned char i;
    
    	_nop_();
    	i = 227;
    	while (--i);
    }
    
    
    /**
      * @brief  蜂鸣器发声
      * @param  ms 发声的时长,范围:0~32767
      * @retval 无
      */
    void Buzzer_Time(unsigned int ms)
    {
    	unsigned int i;
    	for(i=0;i<ms*2;i++)
    	{
    		Buzzer=!Buzzer;
    		Buzzer_Delay500us();
    	}
    }
    // main.c
    #include <REGX52.H>
    #include "Delay.h"
    #include "Time0.h"
    #include "Buzzer.h"
    
    //蜂鸣器端口:
    sbit Buzzer=P1^5;
    
    #define SPEED 460
    //音符与索引对应表,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,
    	64303 ,63577 ,63691 ,63792 ,63892 ,63981 ,64070 ,64152 ,64229 ,64303 ,64372 ,64437 ,
    	64499 ,64557 ,64612 ,64664 ,64713 ,64759 ,64803 ,64844 ,64883 ,64919 ,64954 ,64987 ,
    	65018 ,65047 ,65074 ,65100 ,65125 ,65148 ,65169 ,65190 ,65209 ,65228 ,65245 ,65261
    };
    
    
    // 第一个H2意思是频率;第二个4,代表一个4分音符;code是把代码放到Flash里面。
    unsigned char code Music[]={
    	H2,4,
    	M7,4,
    	H1,4,
    	M6,4,
    	
    	H2,4,
    	M7,4,
    	H1,4,
    	M6,4,
    //	// 注释部分是高潮的前面部分
    //	M3,4+4+4+4,
    //	P,4+4,	
    //	P,2,	
    //	M1,2,
    //	M2,2,
    //	M1,2,
    //	M3,4+4+4+4,
    //	P,4+2,
    //	M1,2,
    //	M2,2,
    //	M1,2,
    //	M2,2,
    //	M3,2,
    //	//
    //	L6,4+2,
    //	M1,2,
    //	L6,4+2,
    //	M1,2,
    //	
    //	L6,4+2,
    //	M1,2,
    //	M2,4,
    //	M1,4,
    //	
    //	L7,4+4+4+4,
    //	P,4+4+4+4,
    //	
    //	//
    //	M3,4+4+4+4,
    //	P,4+4,	
    //	P,2,	
    //	M1,2,
    //	M2,2,
    //	M1,2,
    //	M3,4+4+4+4,
    //	P,4+2,
    //	M1,2,
    //	M2,2,
    //	M1,2,
    //	M2,2,
    //	M3,2,
    //	//
    //	L6,4+2,
    //	M1,2,
    //	L6,4+2,
    //	M1,2,
    //	
    //	L6,4+2,
    //	M1,2,
    //	M3,4,
    //	M1,2,
    //	M2,2,
    //	
    //	L7,4+4+4+4,
    //	P,4+4+4+4,
    	//
    //	H6,2,
    //	M1,2,
    //	M6,4+2+2+2,
    //	M5, 2,
    //	
    //	M6,4+2,
    //	M5,2,
    //	M6,2,
    //	M5,2,
    //	M6,2,
    //	
    //	M5,2+2,
    //	M3,2+2+4+4,
    //	P,4+4+4,
    //	H6,2,
    //	M1,2,
    	//
    //	M6,4+2+2,
    //	M5,2,
    //	M6,2,
    //	M5,2,
    
    //	M7,4+2+2,
    //	M6,2,
    //	M7,2+2,
    //	M6,4,
    //	M3,2+2+4,
    //	
    //	P,4+4+2,
    //	M3,2,
    //	M5,2,
    //	M3,2,
    	//
    //	M2,4+2,
    //	M3,2,
    //	M2,4+2,
    //	M3,2,
    
    //	M2,4+2,
    //	M3,2,
    //	M5,2,
    //	M3,2,
    //	M5,2,
    //	M3,2,
    //	
    //	M2,4+2,
    //	M3,2,
    //	M2,4+2,
    //	M3,2,
    //	
    //	M2,4+4+4,
    //	M1,2,
    //	M2,2,
    //	//
    //	M3,4,
    //	M6,4,
    //	M1,4,
    //	M3,2,
    
    //	M2,4+2,
    //	M3,2,
    //	M2,4,
    //	M1,4,
    	
    //	M6,4+4+4+4,
    
    
    
    
    
    // 高潮部分
    	P,4+4+4,
    	M6,2,
    	M7,2,
    	//
    	M1,2,
    	M2,2,
    	M7,2,
    	M1,2+4+2,
    	M7,2,
    	
    	M1,2,
    	M2,2,
    	M7,2,
    	M1,2+4+2,
    	M2,2,
    	
    	M3,2,
    	M2,2,
    	M3,2,
    	M2,2,
    	M3,4+2,
    	M2,2,
    	
    	M3,4,
    	M5,4,
    	M3,4,
    	M6,2,
    	M7,2,
    	//
    	M1,2,
    	M2,2,
    	M7,2,
    	M1,2+4+2,
    	M7,2,
    	
    	M1,2,
    	M2,2,
    	M7,2,
    	M1,2+4+2,
    	M2,2,
    	
    	M3,2,
    	M2,2,
    	M3,2,
    	M2,2,
    	M3,4+2,
    	M2,2,
    	
    	M3,4,
    	M5,4,
    	M3,4,
    	M5,4,
    	//
    	M3,2+4,
    	M5,2,
    	M3,2+4,
    	M5,2,
    	
    	M3,2,
    	M5,2,
    	M6,2,
    	M3,2,
    	M5,4,
    	M5,4,
    	
    	M3,2+4,
    	M5,2,
    	M3,2+4,
    	M5,2,
    //	
    	M3,2,
    	M5,2,
    	M6,2,
    	M3,2,
    	M5,4,
    	M5,2+2,
    //
    	M3,4,
    	M2,4,
    	M2,4,
    	M1,2,
    	M3,2,
    	
    	M3,4,
    	M2,4,
    	M2,4,
    	M1,2,
    	M1,2,
    	
    	L6,4+4+4+4,
    	P,4+4+4,
    	M5,2+2,
    
    	//
    	M3,4,
    	M2,4,
    	M2,4,
    	M1,2,
    	M3,2,
    	
    	M3,4,
    	M2,4,
    	M2,4,
    	M1,2,
    	M1,2,
    	
    	L6,4+4+4+4,
    	P,4+4+4+4,
    	
    	0xFF
    };
    	
    
    
    
    unsigned char 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; // 响
    }
    		
    	}

    运行结果

    蜂鸣器《孤勇者》

            好了,对于蜂鸣器的知识就介绍到这了,如有错误还望及时指出。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用51单片机演奏《孤勇者》:蜂鸣器给出的成果展示

    发表评论