目录
随着最近孤勇者成为小朋友们的接头暗号之后,于是产生了利用单片机去播放孤勇者的想法,接下来我们来看看具体的实现以及效果展示吧!
首先我们使用的是51单片机的蜂鸣器来实现的,所以先来介绍一下蜂鸣器吧,如下图所示!
之前在STM32上的那个蜂鸣器是有源蜂鸣器,频率固定,就只能发声,而在我们的51单片机上的这个蜂鸣器是属于无源蜂鸣器,所以需要我们来调整频率,从而来实现发出不同频率的声音。
之前的32是使用三极管进行驱动的,起到放大信号的作用(不清楚的可以去32的笔记看看)。而51单片机使用的是集成电路进行驱动的(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 蜂鸣器发声
- * @param ms 发声的时长,范围:0~32767
- * @retval 无
- */
- void Buzzer_Time(unsigned int ms)
- {
- unsigned int i;
- for(i=0;i
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 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; // 响
- }
-
- }
蜂鸣器《孤勇者》
好了,对于蜂鸣器的知识就介绍到这了,如有错误还望及时指出。