基于Proteus的音乐播放器仿真实现精编版Word格式.docx
《基于Proteus的音乐播放器仿真实现精编版Word格式.docx》由会员分享,可在线阅读,更多相关《基于Proteus的音乐播放器仿真实现精编版Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
89C51单片机拥有4KB的片内ROM和128B的片内RAM。
ROM和RAM的片外寻址范围都为64KB。
单片机拥有32个并行口和1个串行口。
在89C51单片机中存在5个中断源,其中有两个外部中断源、两个内部中断源和一个串行中断源。
图289C51单片机
3.2.2显示电路
显示电路是一个1602液晶也叫1602字符型液晶它是一种专门用来显示字母、数字、符号等的点阵型液晶模块它有若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符。
每位之间有一个点距的间隔每行之间也有间隔起到了字符间距和行间距的作用,正因为如此所以他不能显示图形(用自定义CGRAM,显示效果也不好) 1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
图31602字符液晶
3.2.3晶振电路
晶振电路由两个10pF的电容和一个12MHZ的晶体振荡器组成。
节点1与单片机的XTAL2相连接。
节点2与单片机的XTAL1相连接。
图4晶振电路
3.2.4复位电路
复位电路由复位键、22uF的电容C3、1KΩ的电阻R9、200Ω的电阻R10组成。
节点1与单片机的RST相连接。
图5复位电路
3.2.5发声电路
发声电路由数字扬声器组成。
扬声器一端接地另一端接单片机的P3.7。
图6发声电路
3.3总体电路图
图7总体电路图
四.系统软件设计
4.1数码音乐产生原理
音调的高低用音阶表示,不同的音阶对应不同的频率。
因此,不同频率的方波就可以产生音阶,音阶与频率的关系见表1。
由于频率的倒数是周期,因此可由单片机中的定时控制方波周期,当定时器计数溢出时产生中断。
将与扬声器连接的P1.7取反后就可得到方波的周期,从而达到了控制频率,即音阶的目的。
表1音阶与频率的关系及方式1下定时器的初值
音阶
频率(Hz)
定时器初值
1
2
3
4
5
6
7
131
147
165
175
196
220
247
0F85EH
0F933H
0F9F0H
0FA49H
0FAE6H
0FB74H,
0FBF4H
0100H
262
294
330
349
392
440
494
0FC2FH
0FC99H
0FCF8H
0FD22H
0FD73H
0FDBAH
0FDFAH
523
587
659
698
784
880
988
0FE17H
0FE4CH
0FE7CH
0FE91H
0FEB9H
0FEDDH
0FEFDH
低八度音
中音
高八度音
注:
0表示简谱中的空拍
当晶体振荡频率为6.144MHz,定时器工作在方式1下时,若各音阶相对应的定时器计数初值为X,则可根据下式计算X:
音调的长短用节拍数表示(例如1/4拍、2/4拍、……),不同节拍数的不同音符的组合形成乐谱。
程序中,音的节拍可由延时子程序实现。
延时子程序设定为四分之一拍,节拍值只能是它的整数倍。
4.2总体流程图
主程序实现对单片机进行初始化后,进入曲目识别子程序,进行歌曲曲目判断。
确定歌曲曲目后,LCD再进行显示。
执行播放后,LCD显示并播放音乐。
在播放音乐。
图8总体流程图
图
4.3仿真测试
图11LCD结果显示图
4.4测试总结
音乐播放器很好的实现了播放,但是在实现播放长度方面还有不足,因为对外接存储器的使用还不是很熟悉,扩充四片EEPROM,可实现更长时间的播放,本次试验使用的是较为简单的循环播放模式。
附录一
仿真结果
附录二
代码
/********************************************************************
*文件名:
液晶1602显示.c
***********************************************************************/
#include<
reg52.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
//这三个引脚参考资料
sbitE=P2^7;
//1602使能引脚
sbitRW=P2^6;
//1602读写引脚
sbitRS=P2^5;
//1602数据/命令选择引脚
sbitBEEP=P3^7;
ucharcodeSONG_TONE[]={212,212,190,212,159,169,212,212,190,212,
142,159,212,212,106,126,159,169,190,119,119,126,159,142,159,0};
ucharcodeSONG_LONG[]={9,3,12,12,12,24,9,3,12,12,12,24,9,3,12,
12,12,12,12,9,3,12,12,12,24,0};
*名称:
delay()
*功能:
延时,延时时间大概为5US。
voiddelay()
{
_nop_();
}
bitBusy(void)
这个是一个读状态函数,读出函数是否处在忙状态
*输入:
输入的命令值
bitBusy(void)
bitbusy_flag=0;
RS=0;
RW=1;
E=1;
delay();
busy_flag=(bit)(P0&
0x80);
E=0;
returnbusy_flag;
wcmd(uchardel)
1602命令函数
voidwcmd(uchardel)
while(Busy());
RW=0;
P0=del;
wdata(uchardel)
1602写数据函数
需要写入1602的数据
voidwdata(uchardel)
RS=1;
voidDelayMS(uintms)
uchart;
while(ms--)for(t=0;
t<
120;
t++);
voidPlayMusic()
uinti=0,j,k;
while(SONG_LONG[i]!
=SONG_TONE[i]!
=0)
//播放各个音符,SONG_LONG为拍子长度
for(j=0;
j<
SONG_LONG[i]*20;
j++)
BEEP=~BEEP;
//SONG_TONE延时表决定了每个音符的频率
for(k=0;
k<
SONG_TONE[i]/3;
k++);
DelayMS(10);
//下一个音符索引
i++;
L1602_init()
1602初始化
voidL1602_init(void)
wcmd(0x38);
wcmd(0x0c);
wcmd(0x06);
wcmd(0x01);
L1602_char(ucharhang,ucharlie,charsign)
voidL1602_char(ucharhang,ucharlie,charsign)
uchara;
if(hang==1)a=0x80;
if(hang==2)a=0xc0;
a=a+lie-1;
wcmd(a);
wdata(sign);
L1602_string(ucharhang,ucharlie,uchar*p)
voidL1602_string(ucharhang,ucharlie,uchar*p)
uchara,b=0;
while
(1)
{
wcmd(a++);
b++;
if((*p=='
\0'
)||(b==16))break;
wdata(*p);
p++;
}
Main()
voidmain()
L1602_init();
L1602_string(1,1,"
HAPPYBIRTHDAY"
);
L1602_string(2,1,"
TOYOU"
//播放生日快乐
PlayMusic();
DelayMS(500);
//播完循环
}
参考文献:
[1]郭文川.单片机原理与接口技术[M].中国农业出版社.2007.8
[2]阎石.数字电子技术基础(第五版)[M].北京:
高等教育出版社.2005
[3]李泉溪.单片机原理与实例仿真[M].北京:
北京航空航天大学出版社,2009