浅谈基于Proteus的简易音乐播放器.docx
《浅谈基于Proteus的简易音乐播放器.docx》由会员分享,可在线阅读,更多相关《浅谈基于Proteus的简易音乐播放器.docx(21页珍藏版)》请在冰点文库上搜索。
浅谈基于Proteus的简易音乐播放器
《微处理器与接口技术课程设计》
报告
——简易音乐播放器设计
专业:
通信工程
班级:
姓名:
学号:
年月
摘要
本设计是基于AT89C51单片机的简易音乐播放器。
该音乐播放器是一个依据单片机技术原理,通过PROTEUS仿真软件对硬件电路进行仿真制作以及利用KEIL软件对音乐播放器源程序进行C怨言编译,而设计出的一个音乐播放器。
该音乐播放器通过控制单片机内部的定时器来产生不同频率的方波,驱动蜂鸣器发出不同音调的声音,程序通过把乐谱转化成相应的定时常熟来驱动蜂鸣器演奏音乐。
本音乐播放器共收录了3首歌曲,同时设计了LED等的变换,随着音调进行闪烁。
可以通过按键暂停和播放歌曲,并能够切换至下一个歌曲。
并能够通过LCD1602显示出歌曲的名称。
关键词:
AT89C51;LCD1602;音乐播放器;按键
第1章课程设计目的
1.1巩固和加深对微处理器原理和接口技术知识的理解;
1.2培养根据课题需要选学参考书籍、查阅手册和文献资料的能力;
1.3学会方案论证的比较方法,拓宽知识,初步掌握工程设计的基本方法;
1.4掌握常用仪器、仪表的正确使用方法,学会软、硬件的设计和调试方法;
1.5能按课程设计的要求编写课程设计报告,能正确反映设计和实验成果,能用计算机绘制电路图和流程图。
第2章课程设计任务与要求
2.1设计任务
设计一个简单的音乐播放器,能够在系统开始模拟后自动播放音乐,并且能够在LCD屏幕上显示出正在播放的音乐的名字,LED灯随着音调的不同实现不同个数的灯亮,并且能够通过按键暂停、开始播放和切换歌曲。
2.2设计要求
1.在播放歌曲时LCD屏幕上能够正确显示出歌曲名。
2.在按下暂停按键后能够暂停播放歌曲,并且再次按下后能够继续播放歌曲。
3.在按下切换按键后能够切换歌曲,并且LCD屏幕上的歌名随之变换。
4.能够实现LED灯随着音乐音调进行相应的发光。
第3章硬件设计
3.1设计思想
本系统时由按键系统,单片机系统,屏幕显示系统以及音乐播放系统组成的。
该系统的控制核心时AT89C51单片机,便于编程,能够较好的完成音乐播放器内音乐的音调数据处理。
在播放音乐时运用LCD显示屏来直观的显示歌曲名称。
可以通过按键来完成音乐的暂停和播放,另一个按键来实现音乐之间的顺序切换。
3.2单片机及外围电路
微控制器采用AT89C51单片机。
AT89C51是一种带4K字节FLASH存储器的低电压、高性能CMOS8位微处理器,能够与MCS-51系列单片机完全兼容,MCS-51系列单片机以其推出时间早、配套资源丰富、开发手段完善、性价比高等特点而得到了广泛的应用,是单片机的主流品种。
AT89C51的主要特性包括:
4K字节可编程FLASH存储器、128×8位内部RAM、32可编程I/O线、两个16位定时器/计数器、5个中断源和片内振荡器等特性。
AT89C51的外围电路主要包括时钟电路,复位电路等。
时钟电路就是产生像时钟一样准确运动的振荡电路。
任何工作都按时间顺序。
用于产生这个时间的电路就是时钟电路。
时钟电路一般由晶体振荡器、晶震控制芯片和电容组成。
电路原理图如下图所示:
图1时钟电路
复位电路是一种用来使电路恢复到起始状态的电路设备,它的操作原理与计算器有着异曲同工之妙,只是启动原理和手段有所不同。
复位电路,就是利用它把电路恢复到起始状态。
就像计算器的清零按钮的作用一样,以便回到原始状态,重新进行计算。
电路原理图如下图所示:
图2复位电路
图3单片机外围电路
3.3显示电路
多数的应用系统都要配输出外设,有LED显示器和LCD显示器,为了达到显示目的,选用了LCD1602显示器。
LCD1602是一种工业字符型液晶,能够同时显示16×2即32个字符。
LCD1602液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,即可以显示出图形。
第1引脚:
GND为电源地
第2引脚:
VCC接5V电源正极
第3引脚:
V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4引脚:
RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5引脚:
RW为读写信号线,高电平
(1)时进行读操作,低电平(0)时进行写操作。
第6引脚:
E(或EN)端为使能(enable)端,高电平
(1)时读取信息,负跳变时执行指令。
第7~14引脚:
D0~D7为8位双向数据端。
LCD连接电路如下图所示:
图4LCD连接电路
3.4按键电路
按键控制电路中,单片机的P3口分别连接了2个按键开关,P3.2是播放和暂停按键,P3.3是播放下一首歌曲的按键,按键电路如下图所示:
图5按键电路
3.5蜂鸣器电路
蜂鸣器的正极一段连接在电源上,另一端接三极管的集电极,三极管的基极有单片机的P2.5管脚来控制,当P1.5管脚为低时,输出高电平,三极管导通,使蜂鸣器的电流形成贿赂,从而放出声音。
用户可以通过P2.5管脚的置低和置高来使蜂鸣器发出声音和关闭。
蜂鸣器电路如下图所示:
图6蜂鸣器电路
3.6发光二极管电路
在单片机一端7个引脚连接7个发光二极管,分别代表音乐中的7个音调,在音乐播放大的同时,发光二极管按照不同的音调进行闪烁,亮灯的个数代表着相应的音调,连接电路如下图所示:
图7 发光二极管电路
第4章软件设计
4.1设计思想
系统软件部分从整体上分为按键模块和显示模块,按键模块下有按键检测模块,按键检测模块又包含播放模块和切换歌曲模块,流程图如下图所示:
图8按键模块流程图
系统显示模块为LCD屏幕的显示过程,该模块包换LCD初始化、按键检测模块、显示位置设置和显示内容,流程图如下图所示:
图9系统显示模块流程图
4.2流程图
在开启模拟之后,系统对按键系统进行检测,如果未检测到按键则将音乐一直播放下去,并且具有防止按键误触而导致的暂停或切换的功能,在检测到按键后,会对相应的按键进行相对应的操作,系统软件流程图如下图所示:
图10软件流程图
4.3源程序
#include
#defineuintunsignedint
#defineucharunsignedchar
sbitsounder=P2^0;//定义音乐输出端口
sbitkey1=P3^2;//定义按键用于暂停
sbitkey2=P3^3;//定义按键用于切换
sbitrs=P2^1;
sbitrw=P2^2;
sbite=P2^3;
voiddelay1(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidlcd_wcmd(ucharcom)
{
rs=0;
rw=0;
e=0;
P0=com;
delay1
(2);
e=1;
delay1
(2);
e=0;
delay1
(2);
}
voidlcd_wdat(uchardat)
{
rs=1;
rw=0;
e=0;
P0=dat;
delay1
(2);
e=1;
delay1
(2);
e=0;
delay1
(2);
}
voidwrite_zfc(uchar*p)
{
while(*p!
=0)
lcd_wdat(*p++);
}
voidlcd_init()
{
lcd_wcmd(0x38);
lcd_wcmd(0x01);
lcd_wcmd(0x06);
lcd_wcmd(0x0c);
}
unsignedcharW=0,T;//用于选择音乐
unsignedcharTimer0_H,Timer0_L,Time;
voiddelay5ms(void)//误差0us
{
unsignedchara,b;
for(b=185;b>0;b--)
for(a=12;a>0;a--);
}
voiddelay500ms(void)//误差0us
{
unsignedchara,b,c;
for(c=205;c>0;c--)
for(b=116;b>0;b--)
for(a=9;a>0;a--);
}
//天空之城数据表音谱,高中低音,音长
codeunsignedcharMUSIC[336]={6,2,1,7,2,1,1,3,3,7,2,1,1,3,2,3,3,2,7,2,6,3,2,1,3,2,1,6,2,3,5,2,1,6,2,2,
1,3,2,5,2,6,3,2,2,4,2,3,3,2,1,4,2,2,1,3,2,3,2,5,1,3,1,1,3,1,1,3,1,7,2,3,4,2,1,4,2,2,7,2,2,7,2,6,6,2,1,7,2,1,1,3,3,7,2,1,1,3,2,
3,3,2,7,2,6,3,2,1,3,2,1,6,2,3,5,2,1,6,2,2,
1,3,2,5,2,6,2,2,1,3,2,1,4,2,2,1,3,1,7,2,2,
1,3,3,2,3,1,2,3,1,3,3,1,1,3,5,1,3,1,7,2,1,6,2,1,6,2,1,7,2,2,5,2,2,6,2,6,1,3,1,2,3,1,
3,3,3,2,3,1,3,3,2,5,3,2,2,3,6,5,2,1,5,2,1,
1,3,3,7,2,1,1,3,2,3,3,2,3,3,8,6,2,1,7,2,1,
1,3,2,7,2,2,2,3,1,2,3,1,1,3,3,5,2,5,4,3,2,
3,3,2,2,3,2,1,3,2,3,3,6,3,3,2,6,3,4,5,3,2,
5,3,2,3,3,1,2,3,1,1,3,5,1,3,1,2,3,2,1,3,1,
2,3,1,2,3,2,5,3,2,3,3,6,3,3,2,6,3,4,5,3,4,
3,3,1,2,3,1,1,3,5,1,3,1,2,3,2,1,3,1,2,3,3,7,2,2,0,0,0};
//送别数据表音谱,高中低音,音长
codeunsignedcharMUSIC1[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};
//童年数据表音谱,高中低音,音长
codeunsignedcharMUSIC2[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};
//音阶频率表高八位
codeunsignedcharFREQH[]={0xF2,0xF3,0xF5,0xF5,0xF6,0xF7,0xF8,
0xF9,0xF9,0xFA,0xFA,0xFB,0xFB,0xFC,0xFC,0xFC,0xFD,0xFD,0xFD,0xFD,0xFE,
0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFF};
//音阶频率表低八位
codeunsignedcharFREQL[]={0x42,0xC1,0x17,0xB6,0xD0,0xD1,0xB6,
0x21,0xE1,0x8C,0xD8,0x68,0xE9,0x5B,0x8F,0xEE,0x44,0x6B,0xB4,0xF4,0x2D,
0x47,0x77,0xA2,0xB6,0xDA,0xFA,0x16};
voiddelayus2x(unsignedchart)//us延时
{
while(--t);
}
voiddelayms(unsignedchart)//ms延时
{
while(t--)
{
//大致延时1mS
delayus2x(245);
delayus2x(245);
}
}
/*------------------------------------------------
节拍延时函数
各调1/4节拍时间:
调4/4125ms
调2/4250ms
调3/4187ms
------------------------------------------------*/
voiddelay(uchart)
{
uchari;
for(i=0;idelayms(250);
TR0=0;
}
voidTIM0_ISR()interrupt1//定时器0中断
{
TR0=0;
sounder=!
sounder;
TH0=Timer0_H;
TL0=Timer0_L;
TR0=1;
}
voidSong()//歌曲处理函数
{
TH0=Timer0_H;//赋值定时器时间,决定频率
TL0=Timer0_L;
TR0=1;//打开定时器
delay(Time);//延时所需要的节拍
}
voidled(unsignedchara)//频谱函数
{
switch(a)
{
case0:
P1=0xff;break;
case1:
P1=0x7f;break;
case2:
P1=0x7e;break;
case3:
P1=0x7c;break;
case4:
P1=0x78;break;
case5:
P1=0x70;break;
case6:
P1=0x60;break;
case7:
P1=0x40;break;
case8:
P1=0x00;break;
}
}
voidmain(void)
{
unsignedinti;
unsignedchark;
TMOD|=0x01;//置定时器0工作方式1
EA=1;//打开全局中断
ET0=1;//打开定时器0中断
EX0=1;//打开外部中断0中断
IT0=1;//设置为下降沿中断
EX1=1;//打开外部中断1中断
IT1=1;//设置为下降沿中断
PX1=1;//设置外部中断1为高优先级
lcd_init();
while
(1)
{if(W==0)
{
T=W;
lcd_wcmd(0x81);
write_zfc("tiankongzhi");
lcd_wcmd(0xc4);
write_zfc("cheng");
for(i=0;i<336;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];//节拍时长
Song();
if(T!
=W)
break;
}
}
if(W==1)
{
T=W;
lcd_wcmd(0x01);
lcd_wcmd(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];//节拍时长
Song();
if(T!
=W)
break;
}
}
if(W==2)
{
T=W;
lcd_wcmd(0x80);
write_zfc("tongnian");
for(i=0;i<423;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];//节拍时长
Song();
if(T!
=W)
break;
}
}
}
}
voidzhongduan0()interrupt0//外部中断0中断服务程序用于暂停
{
delay5ms();//按键去抖
if(!
key1)
{
while(!
key1);//松手检测
while(key1&&T==W);//检测按键是否按下
delay5ms();//按键去抖
while(key1&&T==W);//检测按键是否按下
while(!
key1&&T==W);//松手检测
}
}
voidzhongduan1()interrupt2//外部中断1中断服务程序
{
delay5ms();//按键去抖
if(!
key2)
{
if(W==2)W=0;
elseW++;
while(!
key2);//松手检测
delay500ms();
}
}
第5章调试运行
5.1软件仿真运行
在AT89C51中加载源程序的HEX文件,开始运行,LCD屏幕正常显示,发光二极管随着音调的不同进行闪烁。
在按下切换按键后,会自动播放下一首歌曲。
在按下暂停按键后,音乐停止播放,发光二极管停止闪烁,再次按下暂停按键,继续播放当前歌曲,发光二极管重新开始闪烁。
图11软件仿真运行
图12软件仿真运行
第6章设计心得体会
在本次的单片机课程设计中,在老师布置下任务后,经过一番思考,决定使用之前并没有过多的接触的LCD屏幕进行显示设计,在浸过多次的上网查阅有关于LCD1602的使用方法,参考了多位他人的有涉及到LCD的报告,了解了LCD1602的引脚接发后,又遇到新的问题,关于LCD显示的初始化,读取数据,写入数据等多个方面的问题,通过查阅资料和对他人报告的仔细阅读,反复尝试,终于解决了在软件仿真时LCD屏幕无法显示的问题。
在想到音乐播放器这个课设题目时,觉得对于只是简单的播放音乐略显平常,故又在查阅资料时得到了用发光二极管来随着音调发光,且较为简单实现,LCD屏幕的显示也增加了项目的难度。
因为自身的水平有限,也做不出足够让人惊艳的课程设计项目,在编程过程中也多次参考了他人的程序,在中断和LCD有关内容的编程上多为参考别人的程序加以改编,本次的音乐播放器只收录了3首歌曲,在编程时准备添加更多歌曲时,在转换成HEX文件会提示单片机内存不足,所以放弃了这个想法,同样循环播放的目的也因为这个没能实现,只能通过按键来控制歌曲的切换,也算是一个小遗憾。
在编写歌曲的音频部分程序时,耗