利用51单片机演奏《猪猪侠》 您所在的位置:网站首页 万疆电子琴乐谱 利用51单片机演奏《猪猪侠》

利用51单片机演奏《猪猪侠》

2024-07-10 04:38| 来源: 网络整理| 查看: 265

今天的目标很明确,那就是我们如何使用51单片机演奏一首音乐。 先听一下演奏效果:

51单片机播放《猪猪侠》音乐(音频)

1.有一个很重要的问题,那就是如何将乐谱转换51单片机的16进制或十进制呢?

然而我们不可能为了编一首乐谱再去学音乐知识,这样太费劲了 但是我们有一个编辑软件,直接将乐谱转换51单片机的16进制或十进制。 https://pan.baidu.com/s/1X_3bESwv831psG2tBL7yJw 提取码:sr7i

2.但是有了乐谱编辑软件,你会用吗?

下面我以《猪猪侠》乐谱 为例,简单的教大家如何使用这个软件 由于本人较懒只编了这么一段

我们打开软件: 在这里插入图片描述 其实灰常简单,只需要将乐谱中对应的数字或符号一一对应我们软件中的符号就行了 我们以该乐谱第一行为例编写一段: 在这里插入图片描述在这里插入图片描述 这一行有数字:3 1 3_ 4 4_ 2_ 6 2.

符号:| ~ 注:‘~’ 就代表:在这里插入图片描述

那么这一行的十六进制就是: 在这里插入图片描述 注意:我们在用该软件编写乐谱时,最好不要将乐谱的前奏也写进去,因为前奏哪一部分演奏效果不是太好。

3.下面就是我们的代码了:

自定义头文件代码:

曲谱存贮格式 unsigned char code MusicName{音高,音长,音高,音长...., 0,0}; 末尾:0,0 表示结束(Important) 音高由三位数字组成: 个位是表示 1~7 这七个音符 十位是表示音符所在的音区:1-低音,2-中音,3-高音; 百位表示这个音符是否要升半音: 0-不升,1-升半音。 音长最多由三位数字组成: 个位表示音符的时值,其对应关系是: |数值(n): |0 |1 |2 |3 | 4 | 5 | 6 |几分音符: |1 |2 |4 |8 |16 |32 |64 音符=2^n 十位表示音符的演奏效果(0-2): 0-普通,1-连音,2-顿音 百位是符点位: 0-无符点,1-有符点 调用演奏子程序的格式 Play(乐曲名,调号,升降八度,演奏速度); |乐曲名 : 要播放的乐曲指针,结尾以(0,0)结束; |调号(0-11) : 是指乐曲升多少个半音演奏; |升降八度(1-3) : 1:降八度, 2:不升不降, 3:升八度; |演奏速度(1-12000): 值越大速度越快; ***************************************************************************/ #ifndef __SOUNDPLAY_H_REVISION_FIRST__ #define __SOUNDPLAY_H_REVISION_FIRST__ //************************************************************************** #define SYSTEM_OSC 24000000 //定义晶振频率12000000HZ #define SOUND_SPACE 4/6 //定义普通音符演奏的长度分率,//每4分音符间隔 sbit BeepIO = P3^7; //定义输出管脚 unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表 unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 }; //1~7在频率表中的位置 unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 }; unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存 unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存 //************************************************************************** void InitialSound(void) { BeepIO = 0; Sound_Temp_TH1 = (65535-(1/1200)*SYSTEM_OSC)/256; // 计算TL1应装入的初值 (10ms的初装值) Sound_Temp_TL1 = (65535-(1/1200)*SYSTEM_OSC)%256; // 计算TH1应装入的初值 TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TMOD |= 0x11; ET0 = 1; ET1 = 0; TR0 = 0; TR1 = 0; EA = 1; } void BeepTimer0(void) interrupt 1 //音符发生中断 { BeepIO = !BeepIO; TH0 = Sound_Temp_TH0; TL0 = Sound_Temp_TL0; } //************************************************************************** void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed) { unsigned int NewFreTab[12]; //新的频率表 unsigned char i,j; unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength; unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD; for(i=0;i j = j-12; NewFreTab[i] = FreTab[j]*2; } else NewFreTab[i] = FreTab[j]; if(Octachord == 1) NewFreTab[i]>>=2; else if(Octachord == 3) NewFreTab[i] SL=Tone%10; //计算出音符 SM=Tone/10%10; //计算出高低音 SH=Tone/100; //计算出是否升半 CurrentFre = NewFreTab[SignTab[SL-1]+SH]; //查出对应音符的频率 if(SL!=0) { if (SM==1) CurrentFre >>= 2; //低音 if (SM==3) CurrentFre while(TF1==0); TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TF1=0; } } if(LDiv2!=0) { TR0=0; BeepIO=0; for(i=LDiv2;i>0;i--) //音符间的间隔 { while(TF1==0); TH1 = Sound_Temp_TH1; TL1 = Sound_Temp_TL1; TF1=0; } } Point+=2; Tone=Sound[Point]; Length=Sound[Point+1]; } BeepIO = 0; } #endif

主函数代码:

#include #include "SoundPlay.h" void Delay1ms(unsigned int count) { unsigned int i,j; for(i=0;i InitialSound(); while(1) { Play(Music,0,3,360); Delay1ms(500); } } 4.proteus仿真图:

在这里插入图片描述 大家将HEX文件写入AT89C51就可以了

以上就是利用51单片机演奏《猪猪侠》音乐了,你学废了吗?as哈哈 哈哈哈 笑



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有