当前位置:文档之家› 基于单片机的音乐播放器

基于单片机的音乐播放器

综合课程设计(二)Integrated Curriculum Design(2)1音乐播放器设计内容 (2)2音乐播放器设计目的 (2)3设计思路 (2)4方案设计 (2)5设计过程 (3)(1)单片机控制模块 (3)(2)晶振电路 (4)(3)复位电路 (4)(4)显示部分设计 (5)(5)液晶显示模块: (5)(6)发声控制模块: (6)(7)矩阵按键模块: (7)6单片机音乐的产生 (8)7.电路仿真与结果分析 (10)7.1电路仿真 (10)6.2结果分析 (11)7.不足之处 (11)8设计体会 (11)9.参考文献 (11)10.附件 (12)电路图 (12)源程序 (12)1音乐播放器设计内容本设计是关于一个设计运用单片机,,在原来的基础上,我们经过改进,又添加了以下几个功能:液晶显示模块、彩灯控制模块、,矩阵按键模块,本设计音乐播放,而且能通过lcd显示屏显示并通过矩阵按键选取功能。

2音乐播放器设计目的(1)掌握单片机芯片AT89C51的基本功能和使用。

(2)熟悉Proteus仿真软件的使用,了解各元件的功能及作用。

(3)了解音乐的基本知识。

(4)提高数字电子电路的综合应用能力。

(5)掌握Keil软件的使用方法,以及如何创建文件和编写程序。

(6)提高焊接能力以及实际问题分析能力。

(7)培养团体合作,培养合作共事协同工作的能力。

3设计思路音乐是由不同的音阶组成的,而不同的音阶又是由不同的频率发出的,那么产生不同的频率,就可以发出不同的音乐了,而利用单片机就可以产生不同频率的方波,因此选择单片机作为主要设计,通过程序编写实现单片机输出的频率,输出的信号接上蜂鸣器,让其发声,同时加入led来显示。

并且,在最初的设计上加入了液晶显示模块,显示歌曲名字,另外两个开关用来暂停和播放下一曲。

4方案设计本方案主要采用AT89C51单片机作为主控芯片,设置键盘、蜂鸣器等外围器件,另外还用到一些简单的器件,不同颜色的LED灯和NPN型三极管及电阻等,用NPN 型三极管8050实现低音频功率放大,用彩灯来实现音符转换的视觉感,最后用蜂鸣器发音。

5设计过程单片微型计算机是大规模集成电路技术发展的产物,属第四代电子计算机,它具有高性能、高速度、体积小、价格低廉、稳定可靠、应用广泛的特点。

音乐播放器是现代电子技术与音乐结合的产物,是一种新型的键盘乐器。

它在现代音乐扮演着重要的角色,单片机具有强大的控制功能和灵活的编程实现特性,它已经融入现代人们的生活中,成为不可替代的一部分。

本设计是以AT89C51单片机为核心控制元件,以单片机作为主控核心,采用液晶显示模块,彩灯控制模块等模块组成核心主控制模块。

可细分为单片机控制模块,按键模块,彩灯灯显示模块和发声模块共4个模块。

具体框图如图1所示。

(1)单片机控制模块硬件电路要以单片机作为主芯片,液晶的显示以及低音频功率放大和蜂鸣器发音,具体电路如图2所示。

图2 单片机控制模块(2)晶振电路单片机内部具有一个高增益反相放大器,用于构成振荡器。

通常在引脚XTALl和XTAL2跨接石英晶体和两个补偿电容构成自激振荡器,结构图3中X2、C3、C4可以根据情况选择6MHz、12MHz或24MH等频率的石英晶体,本设计采用12MHz的晶振补偿电容通常选择20pF左右的瓷片电容。

图3 晶振电路(3)复位电路在电路图中,电容的大小是10uf,电阻的大小是10k。

所以根据公式,可以算出电容充电到电源电压的0.7倍(单片机的电源是5v,所以充电到0.7倍即为3.5v),需要的时间是10k*10uf=0.1S。

也就是说在单片机启动的0.1s 内,电容两端的电压是在0~3.5v增加。

这个时候10k电阻两端的电压为5~1.5v 减少。

所以在0.1s内,RST引脚所接收到的电压是1.5v~5v。

在5v正常工作的51单片机中小于1.5v的电压信号为低电平信号,而大于1.5v的电压信号为高电平信号。

所以在开机0.1s内,单片机系统自动复位。

图4 复位电路(4)显示部分设计七个不同颜色的LED代表按键的音符DO、RE、MI...分别接到P0口的各个I 端口,音符DO时,一个LED亮,音符MI时,2个LED亮...同时为了区分高中低音,三个八度LED显示不同,当低音音符播放时,LED闪亮,当是中音时,LED 也闪亮,但是闪亮的频率更快,当是高音时,LED全亮,这是通过调节LED亮灭时间来实现。

彩灯控制模块(5)液晶显示模块:读状态输入:RS=L,R/W=H,E=H 输出: D0~D7=状态字读数据输入:RS=H,R/W=H,E=H 输出:无写指令输入:RS=L,R/W=L,D0~D7= 指令码 E =高脉冲输出: D0~D7 =数据写数据输入:RS=H,R/W=L,D0~D7= 数据 E=高脉冲输出:无(6)发声控制模块:此模块通过三级管来放大信号,再通过扬声器发出声音。

(7)矩阵按键模块:可以实现选取、播放、暂停、等功能。

音乐播放界面6单片机音乐的产生一首音乐是许多不同的音阶组成的,而每个音阶对应着不同的频率,这样我们就可以利用不同的频率的组合,即可构成我们所想要的音乐了,当然对于单片机来产生不同的频率非常方便,我们可以利用单片机的定时/计数器T0来产生这样方波频率信号,因此,我们只要把一首歌曲的音阶对应频率关系弄正确即可。

若要产生音频脉冲,只要算出某一音频的周期(1/频率),再将此周期除以2,即为半周期的时间。

利用定时器计时半周期时间,每当计时终止后就将P1.0反相,然后重复计时再反相。

就可在P1.0引脚上得到此频率的脉冲。

利用AT89C51的内部定时器使其工作计数器模式(MODE1)下,改变计数值TH0及TL0以产生不同频率的方法产生不同音阶。

例如,频率为523Hz,其周期T=1/523=1912μs,,则半周期为1912/2=956μs,因此只要令计数器计时956μs,每计数956次时将I/O反相,就可得到中音DO(523Hz)则初始值为65535-956 = 64579 = 0xFC43。

计数脉冲值与频率的关系式(如式4-2所示)是:N=fi÷2÷fr(4-2)式中,N是计数值;fi是机器频率(晶体振荡器为12MHz时,其频率为1MHz);fr是想要产生的频率。

其计数初值T的求法如下:T=65536-N=65536-fi÷2÷fr例如:设K=65536,fi=1MHz,求低音DO(261Hz)、中音DO(523Hz)、高音DO(1046Hz)的计数值。

T=65536-N=65536-fi÷2÷fr=65536-1000000÷2÷fr=65536-500000/fr低音DO的T=65536-500000/262=63627中音DO的T=65536-500000/523=64580高音DO的T=65536-500000/1046=65059单片机12MHZ晶振,高中低音符与计数T0相关的计数值如表4-1所示表 4-1 音符频率表7.电路仿真与结果分析7.1电路仿真这是第一首歌,led灯会根据不同的音调来闪烁通过按键选取下一首歌6.2结果分析根据仿真结果可知,本次课程设计能够比较完整的完成设计。

利用单片机产生不同频率来获得我们要求的音阶,通过按键来控制播放和暂停音乐,和选择下一首音乐。

同时还可以通过流水灯观察到音阶的变化。

7.不足之处这次课程设计我们为做音乐播放器准备的还不够充分,对于音乐方面的知识怎么转换到程序里面也是查阅了很多资料,了解的还不够充分,实物做出来的音乐效果不是很好,而且液晶显示部分的亮度调节效果不是很好,另外我们的实际焊电路的能力还有待提高。

8设计体会此次设计是在已经掌握相关的专业理论知识的基础上,进行的一次综合应用的实践性教学环节,是提高我们实践技能和增强动手能力的有效措施。

它不仅巩固所学知识、增强开发能力、提高专业素质,促进全面发展,而且,通过音乐播放器的设计这一环节,培养团队思考,团队合作解决问题的能力,培养合作共事,协同工作的能力,为今后的团体合作能力打好扎实的基础。

另外此次设计过程中也遇到了很多问题,比如第一次焊电路时,检查了电路都没有问题,但是就是没有效果,我们就又重新焊了一遍才成功。

总的说来,我们还是收获很多,不仅再一次巩固了我们所学习的知识,对keil软件编程序的进一步学习巩固,对protues软件仿真的进一步应用,还有实际焊电路能力的进一步提升,也培养了我们团队合作能力,还有让我们知道在处理问题过程中,一定要细心,有耐心才能真正把事情做好。

9.参考文献[1]余发山、王福忠. 单片机原理及应用技术. 中国矿业大学出版社.2008年6月第1 版。

[2]郭天祥.51单片机c语言教程.电子工业出版社.2009年1月第一版。

[3]康华光.电子技术基础数字部分,高等教育出版社.第六版。

[4]于丽娜.电工电子实验教程.东北师范大学出版社.2011年3月第一版。

10.附件电路图源程序#include<reg52.h>#define uint unsigned int#define uchar unsigned char/*------------------------------------------------硬件端口定义------------------------------------------------*/sbit SPK=P2^0; //定义音乐输出端口sbit key1=P3^2; //定义按键用于暂停sbit key2=P3^3; //定义按键用于切换sbit rs=P2^1;sbit rw=P2^2;sbit ep=P2^3;void delay1(uint z){uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com) {rs=0;rw=0;ep=0;P0=com;delay1(2);ep=1;delay1(2);ep=0;delay1(2);}void write_dat(uchar dat) {rs=1;rw=0;ep=0;P0=dat;delay1(2);ep=1;delay1(2);ep=0;delay1(2);}void write_zfc(uchar *p) {while(*p!=0)write_dat(*p++);}void init_1602(){write_com(0x38); //设置16*2显示,5*7点阵,八位数据接口write_com(0x01); //显示清零,数据指针清零write_com(0x06); //写一个字符后,地址指针加一write_com(0x0c); //设置开显示,不显示光标}unsigned char W=0,T; //用于选择音乐unsigned char Timer0_H,Timer0_L,Time;void delay5ms(void){unsigned char a,b;for(b=185;b>0;b--)for(a=12;a>0;a--);}void delay500ms(void){unsigned char a,b,c;for(c=205;c>0;c--)for(b=116;b>0;b--)for(a=9;a>0;a--);}//世上只有妈妈好数据表音谱,高中低音,音长code unsigned char MUSIC[102]={ 6,2,3, 5,2,1, 3,2,2, 5,2,2, 1,3,2, 6,2,1, 5,2,1,6,2,4, 3,2,2, 5,2,1, 6,2,1, 5,2,2, 3,2,2, 1,2,1,6,1,1, 5,2,1, 3,2,1, 2,2,4, 2,2,3, 3,2,1, 5,2,2,5,2,1, 6,2,1, 3,2,2, 2,2,2, 1,2,4, 5,2,3, 3,2,1,2,2,1, 1,2,1, 6,1,1, 1,2,1, 5,1,6, 0,0,0};//送别数据表音谱,高中低音,音长code unsigned char MUSIC1[174]={ 5,2,2, 3,2,1, 5,2,1, 1,3,4,6,2,2, 1,3,2, 5,2,4,5,2,2, 1,2,1, 2,2,1, 3,2,2, 2,2,1, 1,2,1,2,2,8,5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1,6,2,2, 1,3,2, 5,2,4,5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1,1,2,8,6,2,2, 1,3,2, 1,3,4,7,2,2, 6,2,1, 7,2,1, 1,3,4,6,2,1, 7,2,1, 1,3,1, 6,2,1, 6,2,1, 5,2,1, 3,2,1, 1,2,1,2,2,8,5,2,2, 3,2,1, 5,2,1, 1,3,3, 7,2,1,6,2,2, 1,3,2, 5,2,4,5,2,2, 2,2,1, 3,2,1, 4,2,3, 7,1,1,1,2,8};//新年好数据表音谱,高中低音,音长code unsigned char MUSIC2[90]={ 1,2,1, 1,2,1, 1,2,2, 5,1,2,3,2,1, 3,2,1, 3,2,2, 1,2,2,1,2,1, 3,2,1, 5,2,2, 5,2,2,4,2,1, 3,2,1, 2,2,4,2,2,1, 3,2,1, 4,2,2, 4,2,2,3,2,1, 2,2,1, 3,2,2, 1,2,2,1,2,1, 3,2,1, 2,2,2, 5,1,2,7,1,1, 2,2,1, 1,2,4};//童年数据表音谱,高中低音,音长code unsigned char MUSIC3[423]={ 5,1,1, 5,1,1, 3,1,1,5,1,2, 3,1,1, 5,1,2,6,1,1, 6,1,1, 1,2,1, 6,1,2, 6,1,1, 1,2,2,2,2,1, 2,2,1, 3,2,1, 2,2,2, 5,1,1, 6,1,1, 5,1,1,1,2,1, 1,2,1, 5,1,1, 1,2,1, 1,2,1, 1,2,2, 1,2,1,1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1,1,1,2, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1,6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1,1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 1,2,1, 6,1,1,5,1,2, 0,2,1, 3,1,1, 6,1,1, 1,2,1, 6,1,1, 5,1,1,3,1,1, 2,1,1, 3,1,1, 5,1,1, 5,1,2, 5,1,1, 3,1,1,6,1,1, 6,1,1, 1,2,1, 6,1,1, 6,1,1, 6,1,1, 6,1,1, 5,1,1,1,2,2, 1,2,1, 1,2,1, 1,2,1, 6,1,1, 6,1,1, 1,2,1,2,2,2, 0,2,1, 5,1,1, 2,2,1, 5,2,1, 2,2,2,5,2,1, 5,2,2, 5,2,1, 5,2,1, 5,2,1, 3,2,1, 2,2,1,1,2,1, 1,2,2, 6,1,1, 6,1,1, 1,2,1, 6,1,1, 1,2,1,2,2,1, 2,2,1, 2,2,1, 2,2,1, 2,2,1, 1,2,1, 3,2,1, 2,2,1,2,2,8,3,2,1, 3,2,2, 3,2,1, 3,2,2, 2,2,2,1,2,1, 1,2,2, 1,2,1, 2,2,1, 1,2,1, 6,1,1, 5,1,1,5,1,1, 5,1,2, 5,1,1, 6,1,1, 5,1,1, 2,2,1, 3,2,1,1,2,8,1,2,1, 5,1,2, 1,2,1, 6,1,1, 5,1,1, 3,1,1, 2,1,1,1,2,6, 0,2,2};// 音阶频率表高八位code unsigned char FREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC, //1,2,3,4,5,6,7,8,i0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF, } ;// 音阶频率表低八位code unsigned char FREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F, //1,2,3,4,5,6,7,8,i0xEE,0x44, 0x6B,0xB4,0xF4,0x2D,0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16, };/*------------------------------------------------uS延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,大致延时长度如下 T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}void DelayMs(unsigned char t){while(t--){//大致延时1mSDelayUs2x(245);DelayUs2x(245);}}/*------------------------------------------------节拍延时函数各调1/4节拍时间:调4/4 125ms调2/4 250ms调3/4 187ms------------------------------------------------*/void delay(uchar t){uchar i;for(i=0;i<t;i++)DelayMs(250);TR0=0;}/*------------------------------------------------定时器0中断------------------------------------------------*/ void TIM0_ISR() interrupt 1{TR0=0;SPK=!SPK;TH0=Timer0_H;TL0=Timer0_L;TR0=1;}/*------------------------------------------------歌曲处理函数------------------------------------------------*/ void Song(){TH0=Timer0_H;//赋值定时器时间,决定频率TL0=Timer0_L;TR0=1; //打开定时器delay(Time); //延时所需要的节拍}/*------------------------------------------------主函数------------------------------------------------*/ void led(unsigned char a);void main(void){unsigned int i;unsigned char k;TMOD=0x01; //置定时器0工作方式1EA=1; //打开全局中断ET0=1; //打开定时器0 中断EX0=1; //打开外部中断0 中断IT0=1; //设置为下降沿中断EX1=1; //打开外部中断1 中断IT1=1; //设置为下降沿中断PX1=1; //设置外部中断1 为高优先级init_1602();while(1){//i=0;if(W==0){T=W;write_com(0x81);write_zfc("shishangzhiyou");write_com(0xc4);write_zfc("mamahao");for(i=0;i<100;i=i+3){ //音乐数组长度,唱完从头再来led(MUSIC[i]);k=MUSIC[i]+7*MUSIC[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k];Timer0_L=FREQL[k];Time=MUSIC[i+2]; //节拍时长// i=i+3;Song();if(T!=W)break;}}if(W==1){T=W;write_com(0x01);write_com(0x80);write_zfc(" songbie ");for(i=0;i<174;i=i+3){ //音乐数组长度,唱完从头再来led(MUSIC1[i]);k=MUSIC1[i]+7*MUSIC1[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k];Timer0_L=FREQL[k];Time=MUSIC1[i+2]; //节拍时长// i=i+3;Song();if(T!=W)break;}}if(W==2){T=W;write_com(0x80);write_zfc(" xinnianhao ");for(i=0;i<90;i=i+3){ //音乐数组长度,唱完从头再来led(MUSIC2[i]);k=MUSIC2[i]+7*MUSIC2[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k];Timer0_L=FREQL[k];Time=MUSIC2[i+2]; //节拍时长// i=i+3;Song();if(T!=W)break;}}if(W==3){T=W;write_com(0x80);write_zfc(" tongnian ");for(i=0;i<423;i=i+3){ //音乐数组长度,唱完从头再来led(MUSIC3[i]);k=MUSIC3[i]+7*MUSIC3[i+1]-1;//去音符振荡频率所需数据 Timer0_H=FREQH[k];Timer0_L=FREQL[k];Time=MUSIC3[i+2]; //节拍时长// i=i+3;Song();if(T!=W)break;}}}}// 频谱函数void led(unsigned char a){switch(a){case 0:P1=0xff;break;case 1:P1=0x7f;break;case 2:P1=0x7e;break;case 3:P1=0x7c;break;case 4:P1=0x78;break;case 5:P1=0x70;break;case 6:P1=0x60;break;case 7:P1=0x40;break;case 8:P1=0x00;break;}}// 外部中断0 中断服务程序用于暂停void zhongduan0() interrupt 0{delay5ms(); //按键去抖if(!key1){while(!key1); //松手检测while(key1&&T==W); //检测按键是否按下delay5ms(); //按键去抖while(key1&&T==W); //检测按键是否按下while(!key1&&T==W); //松手检测}}// 外部中断1 中断服务程序void zhongduan1() interrupt 2 {delay5ms(); //按键去抖if(!key2){if(W==3)W=0;elseW++;while(!key2); //松手检测delay500ms();}}。

相关主题