目录

硬件部分

蜂鸣器介绍

驱动电路 

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 #include //蜂鸣器端口:sbit Buzzer=P1^5;/*** @brief蜂鸣器私有延时函数,延时500us* @param无* @retval 无*/void Buzzer_Delay500us()//@11.0592MHz{unsigned char i;_nop_();i = 227;while (--i);}/*** @brief蜂鸣器发声* @paramms 发声的时长,范围: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 #include "Delay.h"#include "Time0.h"#include "Buzzer.h"//蜂鸣器端口:sbit Buzzer=P1^5;#define SPEED 460//音符与索引对应表,P:休止符,L:低音,M:中音,H:高音,下划线:升半音符号##define P0#define L11#define L1_2#define L23#define L2_4#define L35#define L46#define L4_7#define L58#define L5_9#define L610#define L6_11#define L712#define M113#define M1_14#define M215#define M2_16#define M317#define M418#define M4_19#define M520#define M5_21#define M622#define M6_23#define M724#define H125#define H1_26#define H227#define H2_28#define H329#define H430#define H4_31#define H532#define H5_33#define H634#define H6_35#define H736unsigned 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; // 响}}

运行结果

蜂鸣器《孤勇者》

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