单片机音乐流水灯报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《单片机原理与应用》
实验报告
实验名称:音乐流水灯
系(院):控制工程学院
专业班级:自动化1401 实验日期: 2016 年6月14日5-6节
指导老师:李红波
1.组员及任务安排:
组员1:贺兴学号:10 负责任务:统筹安排,任务划分,收集查收等组员2:焦子强学号:12 负责任务:设备工具、软件准备等
2.实验目的要求:
1.编写程序,实现流水灯和音乐。
2.进一步熟悉Keil uVision4软件,proteus软件的使用。
3.学会构建简单的流水灯。
3.实验仪器设备、软件、元器件:
1.AT89C52型单片机一个。
2.按钮三个。
3.10k电阻一个。
4.22pF电容俩个,20uF电容一个。
5.晶体整荡器一个。
6.电阻一个。
7.数码管一个。
8.LED灯16个。
9.470Ω电阻16个。
10.SOUNDER型喇叭一个。
4.电路原理图
5.C语言程序代码:
#define SYSTEM_OSC 12000000 //定义晶振频率12000000HZ
#define SOUND_SPACE 4/5 //定义普通音符演奏的长度分率,//每4分音符间隔
#define MUSICNUMBER 3 //歌曲的数目
sbit BeepIO = P2^6; //定义输出管脚
extern void LEDShow(unsigned int LEDStatus);
extern unsigned char GetKey(void);
extern void KeyDispose(unsigned char Key);
extern void Delay1ms(unsigned int count);
extern unsigned char MusicIndex;
unsigned int code FreTab[12] = { 262,277,294,311,330,349,369,392,415,440,466,494 }; //原始频率表unsigned char code SignTab[7] = { 0,2,4,5,7,9,11 };
//1~7在频率表中的位置
unsigned char code LengthTab[7]= { 1,2,4,8,16,32,64 };
unsigned char Sound_Temp_TH0,Sound_Temp_TL0; //音符定时器初值暂存
unsigned char Sound_Temp_TH1,Sound_Temp_TL1; //音长定时器初值暂存
//************************************************************************ **
void InitialSound(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;
}
void BeepTimer0(void) interrupt 1 //音符发生中断
{
BeepIO = !BeepIO;
TH0 = Sound_Temp_TH0;
TL0 = Sound_Temp_TL0;
}
//************************************************************************ **
void Play(unsigned char *Sound,unsigned char Signature,unsigned Octachord,unsigned int Speed)
{
unsigned int NewFreTab[12]; //新的频率表
unsigned char i,j;
unsigned int Point,LDiv,LDiv0,LDiv1,LDiv2,LDiv4,CurrentFre,Temp_T,SoundLength;
unsigned char Tone,Length,SL,SH,SM,SLen,XG,FD,Key,LEDFlash,OFFSet;
for(i=0;i<12;i++) // 根据调号及升降八度来生成新的频率表
{
j = i + Signature;
if(j > 11)
{
j = j-12;
NewFreTab[i] = FreTab[j]*2;
}
else
NewFreTab[i] = FreTab[j];
if(Octachord == 1)
NewFreTab[i]>>=2;
else if(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(Point < SoundLength)
{
SL=Tone%10; //计算出音符
SM=Tone/10%10; //计算出高低音
SH=Tone/100; //计算出是否升半
LEDFlash = SM*((SL/2)+1)+2;
LEDShow(~(0xFFFE< OFFSet = 2; 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);//计算