音乐盒设计Word格式.docx
《音乐盒设计Word格式.docx》由会员分享,可在线阅读,更多相关《音乐盒设计Word格式.docx(22页珍藏版)》请在冰豆网上搜索。
#defineuintunsignedint
#defineulongunsignedlong
#definemax5//最大曲目数
unsignedcharcodestring[]={"
playingNo."
};
unsignedcharcodestring0[]={"
Pause"
unsignedcharcodestring1[]={"
1Music_Girl"
unsignedcharcodestring2[]={"
2Music_Same"
unsignedcharcodestring3[]={"
3Music_Two"
unsignedcharcodestring4[]={"
4..."
unsignedcharcodestring5[]={"
5..."
sbitBEEP=P2^7;
//喇叭输出脚
sbitK2=P1^5;
//下一首
sbitK3=P1^6;
//上一首
sbitK4=P1^7;
//暂停、播放
sbitP32=P3^2;
intm=1,n=1,k=1,p=0,mod=0;
//INT0的中断编号为1,当有按键按下时启动中断,查询所按下的按键
voidINT0XX(void)interrupt0
{TR0=0;
if(K2==0){n++;
if(n==max+1)n=1;
}
elseif(K3==0){n--;
if(n==0)n=max;
else{k++;
if(k%2==0){p=n;
n=max+1;
}elsen=p;
}
}
voidmain(void)//主程序
{
unsignedchari=0,j=0;
IT0=1;
//INT0低电平触发
IE=0X81;
P1=0Xff;
P3=0Xff;
LcdInt();
//LCD初始化函数
delay(10);
InitialSound();
//初始化定时器便用于输出各种频率的声音
while
(1)
{
i=0;
Write_com(0x01);
//清显示:
清屏幕指令
delay(5);
WriteAddress(0x01);
while(string1[i]!
='
\0'
)
{//显示字符playingNo.
WriteData(string[i]);
i++;
delay(100);
delay(5);
WriteAddress(0x41);
//设置显示位置
m=n;
switch(n)
{
case1:
while(string1[i]!
)//'
是数组结束标志
{
WriteData(string1[i]);
i++;
delay(100);
Play(Music_Girl,0,3,360);
break;
case2:
while(string2[i]!
){
WriteData(string2[i]);
Play(Music_Same,0,3,360);
case3:
while(string3[i]!
{//显示歌名字符
WriteData(string3[i]);
Play(Music_Two,0,3,360);
case4:
while(string4[i]!
WriteData(string4[i]);
i++;
delay(2000);
case5:
while(string5[i]!
{
WriteData(string5[i]);
default:
while(n==max+1){
WriteAddress(0x06);
//设置显示位置为第一行的第5个字
i=0;
while(string0[i]!
{
WriteData(string0[i]);
delay(200);
}while(n==max+1);
break;
}
}
/*******************************************************************************************/
1602.h
intrins.h>
//包含_nop_()函数定义的头文件
sbitRS=P2^0;
//寄存器选择位,将RS位定义为P2.0引脚
sbitRW=P2^1;
//读写选择位,将RW位定义为P2.1引脚
sbitE=P2^2;
//使能信号位,将E位定义为P2.2引脚
sbitBF=P0^7;
//忙碌标志位,,将BF位定义为P0.7引脚
/******************************
函数功能:
延时1ms
******************************/
voiddelay1ms()
unsignedchari,j;
for(i=0;
i<
10;
i++)
for(j=0;
j<
33;
j++)
;
/*****************************************************
延时若干毫秒入口参数:
n
***************************************************/
voiddelay(unsignedintn)
unsignedinti;
for(i=0;
n;
delay1ms();
/*****************************************************
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;
result=0,不忙
bitBusyTest(void)
bitresult;
RS=0;
//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;
//E=1,才允许读写
_nop_();
//空操作
_nop_();
//空操作四个机器周期,给硬件反应时间
result=BF;
//将忙碌标志电平赋给result
E=0;
returnresult;
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
voidWrite_com(unsignedchardictate)
{
while(BusyTest()==1);
//如果忙就等待
RS=0;
//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;
//E置低电平(写指令时,
//就是让E从0到1发生正跳变,所以应先置"
0"
_nop_();
//空操作两个机器周期,给硬件反应时间
P0=dictate;
//将数据送入P0口,即写入指令或地址
//空操作四个机器周期,给硬件反应时间
E=1;
//E置高电平
//当E由高电平跳变成低电平时,液晶模块开始执行命令
指定字符显示的实际地址
x
voidWriteAddress(unsignedcharx)
Write_com(x|0x80);
//显示位置的确定方法规定为"
80H+地址码x"
将数据(字符的标准ASCII码)写入液晶模块
y(为字符常量)
********************/
voidWriteData(unsignedchary)
RS=1;
//RS为高电平,RW为低电平时,可以写入数据
//E置低电平(写指令时,,
P0=y;
//将数据送入P0口,即将数据写入液晶模块
对LCD的显示模式进行初始化设置
voidLcdInt(void)
delay(15);
//延时15ms,首次写指令时应给LCD一段较长的反应时间
Write_com(0x38);
//显示模式设置:
16×
2显示,5×
7点阵,8位数据接口
delay(5);
//延时5ms
Write_com(0x38);
//3次写设置模式
Write_com(0x0F);
显示开,有光标,光标闪烁
Write_com(0x06);
光标右移,字符不移
Write_com(0x01);
//清屏幕指令,将以前的显示内容清除
/********************************************************************
******************************************************************/
Intrins.h
/*--------------------------------------------------------------------------
INTRINS.H
IntrinsicfunctionsforC51.
Copyright(c)1988-2004KeilElektronikGmbHandKeilSoftware,Inc.
Allrightsreserved.
--------------------------------------------------------------------------*/
#ifndef__INTRINS_H__
#define__INTRINS_H__
externvoid_nop_(void);
externbit_testbit_(bit);
externunsignedchar_cror_(unsignedchar,unsignedchar);
externunsignedint_iror_(unsignedint,unsignedchar);
externunsignedlong_lror_(unsignedlong,unsignedchar);
externunsignedchar_crol_(unsignedchar,unsignedchar);
externunsignedint_irol_(unsignedint,unsignedchar);
externunsignedlong_lrol_(unsignedlong,unsignedchar);
externunsignedchar_chkfloat_(float);
externvoid_push_(unsignedchar_sfr);
externvoid_pop_(unsignedchar_sfr);
#endif
/**************************************************************************
SOUNDPLAYFOR51MCU
COPYRIGHT(c)2005BYJJJ.
--ALLRIGHTSRESERVED--
FileName:
SoundPlay.h
Author:
JiangJianJun
Created:
2005/5/16
Modified:
NO
Revision:
1.0
*******************************************************************************/
/*说明**************************************************************************
曲谱存贮格式unsignedcharcodeMusicName{音高,音长,音高,音长....,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__
//**************************************************************************
#defineSYSTEM_OSC12000000//定义晶振频率12000000HZ
#defineSOUND_SPACE4/5//定义普通音符演奏的长度分率,//每4分音符间隔
sbitBeepIO=P2^7;
//定义输出管脚
externintm,n,b;
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;
12;
i++)//根据调号及升降八度来生成新的频率表
if(m!
=n){m=n;
gotoloop;
}//当有按键按下时m!
=n,立即跳出本函数
j=i+Signature;
if(j>
11)
j=j-12;
NewFreTab[i]=FreTab[j]*2;
}
else
NewFreTab[i]=Fre