基于51单片机设计的音乐跑马灯课程设计.docx
《基于51单片机设计的音乐跑马灯课程设计.docx》由会员分享,可在线阅读,更多相关《基于51单片机设计的音乐跑马灯课程设计.docx(39页珍藏版)》请在冰点文库上搜索。
基于51单片机设计的音乐跑马灯课程设计
学号:
0121118700107
课程设计
题目
基于AT89C52单片机的音乐跑马灯
学院
物流工程学院
专业
物流工程
班级
物流zy1101班
姓名
申聚鹏
同组者
指导教师
袁兵
2013
年
12
月
28
日
课程设计任务书
学生姓名:
申聚鹏专业班级:
物流zy1101班
指导教师:
袁兵工作单位:
物流工程学院
题目:
基于AT89C52单片机的音乐跑马灯
初始条件:
1.Protues7professional的ISIS7professional和ARES7professional软件
2.Keiluvision4软件
3.单片机的相关资料指导书
要求完成的主要任务:
(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)
基于AT89C52单片机的音乐跑马灯的设计要求如下:
a.有16个发光二极管做跑马灯,其中跑马灯有16种灯亮模式。
b.有专门的按键用以切换跑马灯的模式,并且对于任何一种跑马灯模式都可以对灯亮速度进行控制。
c.每一种跑马灯模式用LED数码管进行显示(0~E)。
d.当跑马灯处于E模式时,音乐响起,音乐可以进行切换。
时间安排:
十八周到十九周设计,十九周答辩
指导教师签名:
年月日
系主任(或责任教师)签名:
年月日
本科生课程设计成绩评定表
姓名
申聚鹏
性别
男
专业、班级
物流zy1101班
课程设计题目:
基于AT89C52单片机的音乐跑马灯
课程设计答辩或质疑记录:
成绩评定依据:
1.选题合理、目的明确10分
2.设计方案正确,具有可行性、创新性20分
3.设计结果20分
4.态度认真、学习刻苦、遵守纪律15分
5.设计报告的规范化、参考文献充分(不少于5篇)10分
6.答辩25分
最终评定成绩(以优、良、中、及格、不及格评定)
指导教师签字:
年月日
摘要
单片机技术是一门不可或缺的技术,对我们将来的工作以及生活和学习都有很密切的联系。
近年来,随着电子技术和微机计算机的迅速发展,单片机的档次不断提高,其应用领域也在不断的扩大,已在工业控制、尖端科学、智能仪器仪表、日用家电、汽车电子系统、办公自动化设备、个人信息终端及通信产品中得到了广泛的应用,成为现代电子系统中最重要的智能化的核心部件。
本设计使用AT89C52芯片,利用P0的8个端口连接8个发光二极管,P1的8个端口连接8个发光二极管,通过P0.0到P0.7的值和P1.0到P1.7的值控制“跑马灯”的亮灭,以达到显示效果。
设计的中断程序要对多个按键动作进行响应,灯光变换的花样有15种,用模式按钮切换。
按下模式按钮键,程序将按十五种模式切换,每按一次模式按钮键,切换一次跑马灯模式,而加速按钮和减速按钮可以改变闪烁速度;最后一种模式为音乐模式,加速按钮可切换音乐。
在单片机运行时,可以在不同状态下让跑马灯显示不同的组合,作为单片机系统正常的指示。
当单片机系统出现故障时,可以利用跑马灯显示当前的故障码,对故障做出诊断。
此外,跑马灯在单片机的调试过程中也非常有用,可以在不同时候将需要的寄存器或关键变量的值显示在跑马灯上,提供需要的调试信息。
关键词:
音乐跑马灯;AT89C52单片机;74LS245驱动芯片;LED发光二极管
1设计概述
1.1设计目的
利用所学单片机的理论知识进行软硬件整体设计,培养学生分析、解决问题的能力,锻炼学生理论联系实际、综合应用的能力。
通过实践动手制作硬件和软件,综合应用本学期所学的单片机知识,达到加深学习该专业知识的目的。
1.2设计作用
跑马灯是一种能像马儿一样跑的灯,就是利用单片机控制LED灯的闪烁方式使其就像马儿奔跑时马蹄的起落。
音乐跑马灯,就是在普通跑马灯的基础上加入了音乐,并通过喇叭将其在适当的时刻播放出来。
单片机的音乐跑马灯由16个LED发光二极管组成,在单片机系统中一般用来指示和显示单片机的运行状态。
通过程序控制使得单片机不同状态下的16个LED发光二级管显示不同的组合,以此显示单片机的工作状态,也可检查单片机是否发生故障。
当然,在实际生活中音乐跑马灯还有许多用处,其可以应用于各种建筑物、大楼、酒吧、KTV和夜总会等娱乐场所,可以制作出各种各样的炫目多彩的霓虹灯,为夜晚带来不一样的光彩。
1.3设计要求
有16个发光二极管做跑马灯,其中跑马灯有16种灯亮模式。
有专门的键盘用以切换跑马灯的模式,并且对于任何一种跑马灯模式都可以对亮灯速度进行控制。
每一种跑马灯模式用LED数码管进行显示。
当跑马灯处于一种模式时,伴随的音乐响起,音乐有3首,并可以对其进行切换。
1.4系统设计框图
基于AT89C52单片机的多模式带音乐的跑马灯控制系统由电路电源、单片机主控电路、模式切换以及调速按键控制电路、LED数码管显示电路和十六个发光二极管的跑马的电路几部分组成,系统框图如图1.1所示。
图1.1系统设计框图
2元器件介绍
2.1AT89C52单片机
AT89C52是51系列单片机的一个型号,它是ATMEL公司生产的。
AT89C52是一个低电压,高性能CMOS8位单片机,片内含8kbytes的可反复擦写的Flash只读程序存储器和256bytes的随机存取数据存储器(RAM),器件采用ATMEL公司的高密度、非易失性存储技术生产,兼容标准MCS-51指令系统,片内置通用8位中央处理器和Flash存储单元,功能强大的AT89C52单片机可为您提供许多较复杂系统控制应用场合。
AT89C52有40个引脚,32个外部双向输入/输出(I/O)端口,同时内含2个外中断口,3个16位可编程定时计数器,2个全双工串行通信口,2个读写口线,AT89C52可以按照常规方法进行编程,也可以在线编程。
其将通用的微处理器和Flash存储器结合在一起,特别是可反复擦写的Flash存储器可有效地降低开发成本。
AT89C52单片机如图2.1所示。
图2.1AT89C52单片机
2.2驱动芯片74LS245
74LS245是我们常用的芯片,用来驱动LED或者其他的设备,它是8路同相三态双向总线收发器,可双向传输数据。
74LS245还具有双向三态功能,既可以输出,也可以输入数据。
当AT89C52单片机的P0口总线负载达到或超过P0最大负载能力时,必须接入74LS245等总线驱动器。
当片选端
低电平有效时,
=“0”,信号由B向A传输;AB=“1”,信号由A向B传输;(发送)当CE为高电平时,A、B均为高阻态。
由于P2口始终输出地址的高8位,接口时74LS245的三态控制端1G和2G接地,P2口与驱动器输入线对应相连。
P0口与74LS245输入端相连,
端接地,保证数据线畅通。
8051的
和
相与后接AB/
,使得RD和PSEN有效时,74LS245输入(P0.1←D1),其它时间处于输出(P0.1→D1)。
74LS245驱动芯片如图2.2所示。
图2.274LS245驱动芯片
2.3其他元件及功能
LED发光二极管:
指示和显单片机状态。
扬声器:
播放歌曲。
按钮:
模式按钮用于切换单片机工作模式,加速按钮用于加快LED灯的闪烁频率,减速按钮用于减缓LED灯的闪烁频率,复位按钮用于人工复位。
数码管:
用于显示单片机当前处于何种模式。
晶体振荡器:
用于构成单片机的复位电路。
电容:
用于构成单片机的复位电路。
电阻:
限流分压作用,是电路正常工作并保护电路。
元件清单如表2.1所示。
表2.1元件清单
元件
数量
元件
数量
AT89C52
1
电容20µF
1
74LS245
3
电阻470Ω
16
LED发光二极管
16
电阻100Ω
7
扬声器
1
电阻480Ω
1
按钮
4
电源+5V
8
数码管
1
晶体振荡器
1
电容30pF
2
3硬件电路设计
3.1单片机最小系统
单片机最小系统或者称为最小应用系统,素质用最少的元件组成的单片机可以工作的系统,对51系列单片机来说,最小系统一般应该包括:
单片机、复位电路、晶振电路。
复位电路:
该复位电路采用手动复位和按键复位,所谓手动复位,是指通过接通一按钮开关,使单片机进入复位状态,使RST获得高电平,该方法可实现比较快速的复位。
当然,若不按下按钮,需等待电容充完电后使得RST获得高电平复位,复位电路如图3.1所示。
图3.1复位电路
晶振电路:
8051单片机的时钟信号通常用两种电路形式电路得到:
内部震荡方式和外部中断方式。
在引脚XTAL1和XTAL2外部接晶振电路器(简称晶振)或陶瓷晶振器,就构成了内部晶振方式。
由于单片机内部有一个高增益反相放大器,当外接晶振后,就构成了自激振荡器并产生振荡时钟脉冲。
内部振荡方式的外部电路如下图所示。
其电容值一般在5~30pF,晶振频率的典型值为12MHz,采用6MHz的情况也比较多。
内部振荡方式所得的时钟信号比较稳定,实用电路使用较多。
晶振电路图如图3.2所示。
图3.2晶振电路
3.2LED显示部分
显示部分,用十六个发光二极管通过总线和74LS245驱动芯片分别接到了AT89C52单片机的P0和P1口。
通过程序控制P0和P1的十六个端口按一定方式一次为低电平点亮端口LED。
若把P0口当作了通用的I/O口,则需要加上拉电阻,可是我们所采用的是使用总线方式输出因此不需要上拉电阻。
本设计采用的是发光二极管阳极接电源,因此要求P0口P1口输出低电平时,二极管才会发光。
LED显示部分如图3.3所示。
图3.3LED显示部分
3.3按钮控制部分
用一个按钮进行模式的切换,即用该按钮控制多种不同的亮灯模式,分别有16种模式,从模式“0”至模式“F”,开启模式“F”是有音乐放出。
用一个按钮(加速按钮)进行发光二极管亮灯加速的调节,在第“F”模式时该按钮则可进行歌曲的切换。
用一个按钮(减速按钮)进行发光二极管亮灯减速的调节,在第9模式时该按钮则可进行歌曲的切换。
按钮控制部分如图3.4所示。
图3.4按钮控制部分
3.4数码管显示电路
数码管上分别显示0~F十六个数字,分别代表十六种模式。
采用共阳极连接,即数码管的a~f端要输入低电平时内部二极管才导通。
在数码管每个端口与74LS245驱动芯片与数码管之间连上100Ω的电阻。
数码管显示电路的具体硬件设计如图3.5所示。
图3.5数码管显示电路
3.5蜂鸣器部分
蜂鸣器是一种将电信号转换成声音信号的电声元件。
确切的说,蜂鸣器工作实际上是把一定范围内的音频电功率讯号通过换能方式转变失真小并且有足够声压级的可听声音。
本课程设计直接将蜂鸣器街道单片机的P2.6端口,蜂鸣器具体电路如图3.6所示。
图3.6蜂鸣器电路
3.6系统总电路图
音乐跑马灯的总电路图如3.7所示。
图3.7音乐跑马灯总电路
3.7操作说明
在仿真软件中,按下屏幕左下角开始按键时,数码管显示为“0”,发光二极管以一定方式开始闪烁,此时按下模式按钮使得数码管显示为“1”时,发光二极管以一另种方式开始闪烁。
此时,若按加速按钮,则加快了发光二极管的闪烁速度,有4种不同的速度。
当加速到最大速度时,再按加速按钮则无法继续加速,此时可以按减速按钮进行减速。
以此类推,模式“1”到模式“E”,每种模式都给有一种闪烁方式。
当继续按模式按钮使的模式转换为模式“F”时,蜂鸣器开始放歌,发光二极管按照音乐音调变动闪烁。
此时的加速按钮可以进行歌曲的切换,按一次按钮换一首歌。
4软件设计
4.1程序流程图
该程序采用两个程序编写:
第一个位单片机主程序,作用是使单片机完成相应上电功能;第二个是音乐产生程序,在第一个程序中包含第二个程序的头文件即可。
程序流程图如图4.1及4.2所示。
图4.1主程序图4.2音乐程序流程图
4.2程序设计
#include//包括一个52标准的内核头文件
//#include
unsignedcharRunMode;
voidDelay1ms(unsignedintCount)//延时子程序
{
unsignedinti,j;
for(i=0;ifor(j=0;j<1200;j++);
}
unsignedcharcodeLEDDisplayCode[]={
0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};//LED数码管
voidDisplay(unsignedcharValue)
{
P3=LEDDisplayCode[Value];
}//数值输出至LED
voidLEDFlash(unsignedcharCount)
{
unsignedchari;
bitFlag;
for(i=0;i{
Flag=!
Flag;
if(Flag)
Display(RunMode);
else
Display(0x10);
Delay1ms(100);
}
Display(RunMode);
}
unsignedcharGetKey(void)//判断按键是否按下
{
unsignedcharKeyTemp,CheckValue,Key=0x00;
CheckValue=P2&0x32;
if(CheckValue==0x32)
return0x00;
Delay1ms(10);//调用延时
KeyTemp=P2&0x32;
if(KeyTemp==CheckValue)return0x00;
if(!
(CheckValue&0x02))Key|=0x01;
if(!
(CheckValue&0x10))Key|=0x02;
if(!
(CheckValue&0x20))Key|=0x04;
returnKey;
}
unsignedintTimer0Count,SystemSpeed,SystemSpeedIndex;
voidInitialTimer2(void)
{
T2CON=0x00;
TH2=RCAP2H=0xfc;
ET2=1;//定时器2中断允许
TR2=1;//定时器2启动
EA=1;
}
unsignedintcodeSpeedCode[]={1,100,500,1000};
voidSetSpeed(unsignedcharSpeed)//跑马灯速度控制
{
SystemSpeed=SpeedCode[Speed];
}
voidLEDShow(unsignedintLEDStatus)//跑马灯的输出
{
P1=~(LEDStatus&0x00ff);
P0=~((LEDStatus>>8)&0x00ff);
}
voidInitialCPU(void)
{
RunMode=0x00;
Timer0Count=0;
SystemSpeedIndex=4;
P1=0x00;
P0=0x00;
P2=0xff;
P3=0x00;
Delay1ms(500);
P1=0xff;
P0=0xff;
P2=0xff;
P3=0xff;
SetSpeed(SystemSpeedIndex);
Display(RunMode);
}
unsignedintLEDIndex=0;
bitLEDDirection=1,LEDFlag=1;
voidMode_0(void)
{
LEDShow(0x0001<LEDIndex=(LEDIndex+1)%16;
}
voidMode_1(void)
{
LEDShow(0x8000>>LEDIndex);
LEDIndex=(LEDIndex+1)%16;
}
voidMode_2(void)
{
if(LEDDirection)
LEDShow(0x0001<else
LEDShow(0x8000>>LEDIndex);
if(LEDIndex==15)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%16;
}
voidMode_3(void)
{
if(LEDDirection)
LEDShow(~(0x0001<else
LEDShow(~(0x8000>>LEDIndex));
if(LEDIndex==15)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%16;
}
voidMode_4(void)
{
if(LEDDirection)
{
if(LEDFlag)
LEDShow(0xfffe<else
LEDShow(~(0x7fff>>LEDIndex));
}
else
{
if(LEDFlag)
LEDShow(0x7fff>>LEDIndex);
else
LEDShow(~(0xfffe<}
if(LEDIndex==15)
{
LEDDirection=!
LEDDirection;
if(LEDDirection)
LEDFlag=!
LEDFlag;
}
LEDIndex=(LEDIndex+1)%16;
}
voidMode_5(void)
{
if(LEDDirection)
LEDShow(0x000f<else
LEDShow(~(0xf000>>LEDIndex));
if(LEDIndex==15)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%16;
}
voidMode_6(void)
{
if(LEDDirection)
LEDShow(~(0x000f<else
LEDShow(~(0xf000>>LEDIndex));
if(LEDIndex==15)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%16;
}
voidMode_7(void)
{
if(LEDDirection)
LEDShow(0x003f<else
LEDShow(0xfc00>>LEDIndex);
if(LEDIndex==9)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%10;
}
voidMode_8(void)
{
LEDShow(++LEDIndex);
}
voidMode_9(void)
{
LEDShow(0x0003<LEDIndex=(LEDIndex+1)%16;
}
voidMode_A(void)
{
LEDShow(0xc000>>LEDIndex);
LEDIndex=(LEDIndex+1)%16;
}
voidMode_b(void)
{
if(LEDDirection)
LEDShow(0x0003<else
LEDShow(0xc000>>LEDIndex);
if(LEDIndex==15)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%16;
}
voidMode_C(void)
{
if(LEDDirection)
LEDShow(0x8080>>LEDIndex);
else
LEDShow(0x0101<if(LEDIndex==7)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%8;
}
voidMode_d(void)
{
if(LEDDirection)
LEDShow(0x1111<else
LEDShow(0x8888>>LEDIndex);
if(LEDIndex==3)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%4;
}
voidMode_E(void)
{
if(LEDDirection)
LEDShow(0x5555<else
LEDShow(0xaaaa>>LEDIndex);
if(LEDIndex==3)
LEDDirection=!
LEDDirection;
LEDIndex=(LEDIndex+1)%4;
}
voidtimer0eventrun(void)//模式选择
{
if(RunMode==0x00){Mode_0();}
elseif(RunMode==0x01){Mode_1();}
elseif(RunMode==0x02){Mode_2();}
elseif(RunMode==0x03){Mode_3();}
elseif(RunMode==0x04){Mode_4();}
elseif(RunMode==0x05){Mode_5();}
elseif(RunMode==0x06){Mode_6();}
elseif(RunMode==0x07){Mode_7();}
elseif(RunMode==0x08){Mode_8();}
elseif(RunMode==0x09){Mode_9();}
elseif(RunMode==0x0a){Mode_A();}
elseif(RunMode==0x0b){Mode_b();}
elseif(RunMode==0x0c){Mode_C();}
elseif(RunMode==0x0d){Mode_d();}
elseif(RunM