基于单片机的播放音乐课程设计

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

单片机原理及应用课程设计题目:基于单片机的音乐播放器班级:电科1121姓名:蔡汉轰学号:201211911101指导老师:王淑青设计要求:1.通过晶振复位电路,重新播放歌曲2.通过中断暂停播放歌曲3.做出仿真图以及实物4.掌握单片机播放音乐的编写程序的方法所需元件:电阻1个、有极性电容一个、无极性电容2个、喇叭一个、button2个以及导线若干设计原理:一、单片机播放音乐的原理:音乐是许多不同的音符组成的,而每个音符对应着不同的频率,这样我们利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来说,产生不同的频率非常方便。我们可以利用单片机的定时器/计数器来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系设置正确即可。若要产生音频脉冲,只要算出某一音频的周期(1/频率),再将此周期除以2,即为半周期的时间。利用定时器计时半周期时间,每当计时终止后就将I/O口反相,然后重复计时再反相。就可以在该I/O口引脚上得到频率的脉冲。STC89C52RC单片机的一个计数周期需要12个时钟周期,采用12MHz晶振,一个计数周期即1us。利用单片机内部的定时器,使其工作计数器模式下,改变计数值TH0及TL0以产生不同频率的方法产生不同音阶。例如,中音DO频率为523Hz,其周期T=1/523=1912us,因此只要令计数器计时956us/1us=956,每计数956次将I/O口反相,就可得到中音DO。计数脉冲值与频率的关系式是:N=fi÷2÷fr式中,N是计数值;fi是机器频率(晶振为12MHz时,其频率为1MHz);fr是想要产生的频率。其计数初值T的求法如下:T=65536-N=65536-fi÷2÷fr单片机12MHz晶振,高中低音符与计数值对照如表31所示。表31C大调各音符频率与计数值对照表音符频率Hz周期(T值)音符频率Hz周期(T值)低音区低音DO26263628中音区#FA7400676#DO27763731中SO7840638低RE29463836#SO8310602#RE31163928中LA8800568低M33064020#LA9320536低FA34964103中SI9880506#FA37064186高音区高DO10460478低SO39264260#DO11090451#SO41564331高RE11750426低LA44064400#RE12450402#LA46664464高M13180372低SI49464524高FA13970358中音区中DO52364580#FA14800338#DO55464633高SO15680319中RE57864694#SO16610292#RE62264732高LA17600284中M65964777#LA18650268中FA69864820高SI19760253注:#代表该音符升半调。我们要为这些音符建立一个表格,让单片机通过查表的方法来获得音符的计数值。unsignedintcodenote_value[][14]={{0,63628,63835,64021,64103,64260,64400,64524,63731,63928,0,64185,64331,64463},//低音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6相对应的定时器初值{0,64580,64684,64777,64820,64898,64968,65030,64633,64732,0,64860,64934,64994},//中音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6相对应的定时器初值{0,65058,65110,65157,65178,65217,65252,65283,65085,65134,0,65198,65235,65268}//高音1,2,3,4,5,6,7,#1,#2,0(#3在此程序中无需设),#4,#5,#6相对应的定时器初值};音乐的节拍,一个节拍为一个单位。如表32所示。表32曲调值表曲调值延时(ms)曲调值延时(ms)调4/4125调4/462调3/4187调3/494调2/4250调2/4125原理图:实验程序:头文件:PLAY.H#ifndef__PLAY_H_REVISION_FIRST__#define__PLAY_H_REVISION_FIRST__//**************************************************************************#defineSYSTEM_OSC12000000//定义晶振频率12000000HZ#defineSOUND_SPACE4/5//定义普通音符演奏的长度分率,//每4分音符间隔sbitBeepIO=P3^7;//定义输出管脚unsignedintcodeFreTab[12]={262,277,294,311,330,349,369,392,415,440,466,494};//原始频率表unsignedcharcodeSignTab[7]={0,2,4,5,7,9,11};//1~7在频率表中的位置unsignedcharcodeLengthTab[7]={1,2,4,8,16,32,64};unsignedcharSound_Temp_TH0,Sound_Temp_TL0;//音符定时器初值暂存unsignedcharSound_Temp_TH1,Sound_Temp_TL1;//音长定时器初值暂存voidInitialSound(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;}voidBeepTimer0(void)interrupt1//音符发生中断{BeepIO=!BeepIO;TH0=Sound_Temp_TH0;TL0=Sound_Temp_TL0;}voidPlay(unsignedchar*Sound,unsignedcharSignature,unsignedOctachord,unsignedintSpeed){unsignedintNewFreTab[12];//新的频率表unsignedchari,j;unsignedintPoint,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;unsignedcharTone,Length,SL,SH,SM,SLen,XG,FD;for(i=0;i12;i++)//根据调号及升降八度来生成新的频率表{j=i+Signature;if(j11){j=j-12;NewFreTab[i]=FreTab[j]*2;}elseNewFreTab[i]=FreTab[j];if(Octachord==1)NewFreTab[i]=2;elseif(Octachord==3)NewFreTab[i]=2;}SoundLength=0;while(Sound[SoundLength]!=0x00)//计算歌曲长度{SoundLength+=2;}Point=0;Tone=Sound[Point];Length=Sound[Point+1];//读出第一个音符和它时时值LDiv0=12000/Speed;//算出1分音符的长度(几个10ms)LDiv4=LDiv0/4;//算出4分音符的长度LDiv4=LDiv4-LDiv4*SOUND_SPACE;//普通音最长间隔标准TR0=0;TR1=1;while(PointSoundLength){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=2;//高音Temp_T=65536-(50000/CurrentFre)*10/(12000000/SYSTEM_OSC);//计算计数器初值Sound_Temp_TH0=Temp_T/256;Sound_Temp_TL0=Temp_T%256;TH0=Sound_Temp_TH0;TL0=Sound_Temp_TL0+12;//加12是对中断延时的补偿}SLen=LengthTab[Length%10];//算出是几分音符XG=Length/10%10;//算出音符类型(0普通1连音2顿音)FD=Length/100;LDiv=LDiv0/SLen;//算出连音音符演奏的长度(多少个10ms)if(FD==1)LDiv=LDiv+LDiv/2;if(XG!=1)if(XG==0)//算出普通音符的演奏长度if(SLen=4)LDiv1=LDiv-LDiv4;elseLDiv1=LDiv*SOUND_SPACE;elseLDiv1=LDiv/2;//算出顿音的演奏长度elseLDiv1=LDiv;if(SL==0)LDiv1=0;LDiv2=LDiv-LDiv1;//算出不发音的长度if(SL!=0){TR0=1;for(i=LDiv1;i0;i--)//发规定长度的音{while(TF1==0);TH1=Sound_Temp_TH1;TL1=Sound_Temp_TL1;TF1=0;}}if(LDiv2!=0){TR0=0;BeepIO=0;for(i=LDiv2;i0;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点C文件播放音乐.c#includeREG51.H#includePlay.hvoidDelay1ms(unsignedintcount){unsignedinti,j;for(i=0;icount;i++)for(j=0;j120;j++);}//远方unsignedcharcodeMusic_Code[]={0x19,0x02,0x17,0x03,0x19,0x03,0x1F,0x01,0x1A,0x02,0x1F,0x03,0x24,0x03,0x19,0x01,0x19,0x02,0x15,0x03,0x16,0x03,0x17,0x02,0x16,0x03,0x15,0x03,0x16,0x00,0x19,0x02,0x17,0x03,0x19,0x03,0x1F,0x02,0x1B,0x03,0x1A,0x02,0x1F,0x02,0x19,0x01,0x19,0x02,0x16,0x03,0x17,0x03,0x18,0x02,0x11,0x03,0x15,0x00,0x1A,0x02,0x1F,0x02,0x1F,0x01,0x1B,0x02,0x1A,0x03,0x1B,0x03,0x1F,0x01,0x1A,0x03,0x1B,0x03,0x1F,0x03,0x1A,0x03,0x1A,0x03,0x19,0x03,0x17,0x03,0x15,0x03,0x16,0x00,0x19,0x02,0x17,0x03,0x19,0x03,0x1F,0x02,0x1B,0x03

1 / 12
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功