单片机音乐倒数定时器的设计.docx
《单片机音乐倒数定时器的设计.docx》由会员分享,可在线阅读,更多相关《单片机音乐倒数定时器的设计.docx(23页珍藏版)》请在冰豆网上搜索。
单片机音乐倒数定时器的设计
课程设计Ⅲ
题目基于单片机的定时器设计
学生姓名袁伟学号0813014094
所在院(系)物理与电信工程学院
专业班级电子083
指导教师王文洋
完成地点501
2011年12月16日
基于单片机音乐倒数定时器的设计报告
袁伟
陕西理工学院物电学院电子信息工程,2008级,3班,陕西汉中723003
指导老师:
王文洋
【摘要】计时器在单片机模块中是比较常见的模块,计时器是一种用数字电路技术实现的计时装置,与机械师中相比具有更高的准确性与直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用。
本设计采用AT89C51单片机对定时器的设计来实现一个简单的多功能的音乐倒计时报警器,通过三个按键可设定任意时间的倒计时报警器来满足用户的简单要求,如烧开水,煮面等简单问题。
【关键词】定时计数器;音乐代码;1602液晶显示
目录
引言1
一、设计要求2
二、设计目的2
三、设计的具体实现2
1.系统概述2
1.1总体方案论证2
1.2单片机选择方案3
2.单元电路设计4
2.1控制电路6
2.2控制程序8
3.软件程设计和调试7
3.1延时时间的计算7
3.2工作方式设计8
3.3有定时器产生各种频率的声音8
3.4程序说明8
四、结论和展望14
五、心得和体会14
六、参考文献15
引言
随着电子技术的飞速发展,各类分立电子元件及其所构成的相关功能单元,已逐步被功能更强大、性能更稳定、使用更方便的集成芯片所取代。
由集成芯片和一些外围电路构成的各种自动控制、自动报警、自动显示电路遍及各种电子产品和设备。
数字系统和数字设备已广泛应用于各个领域,更新换代速度可谓日新月异。
计时器在单片机模块中是比较常见的模块,计时器是一种用数字电路技术实现的计时装置,与机械师中相比具有更高的准确性与直观性,且无机械装置,具有更长的使用寿命,因此得到了广泛的使用,本次设计的任意时间倒计时器,是基于单片机的基础,日常生活中相关的设备是很多的,诸如定时报警、报时自动打铃、时间程序自动控制、定时广播、自动闭路灯等都是以计时器为基础的。
通过对基于单片机控制的倒数计时器的设计过程中,让自己对单片机有进一步的了解,激发兴趣,做到主动探索和学习。
一、设计要求
利用单片机结合LCD显示器设计一个倒数计时器,可以放在家中使用,例如煮方便面、煮开水或小睡片刻等,做一小段时间计时。
当倒数计时为0时,则发出一段音乐,通知倒数终了,该做重要的事情了。
具体要求:
文字型LCD(16*2)显示目前倒数的时间;显示格式为“COUNTDOWN时时:
分分:
秒秒”;具有3个按键操作来设置现在想要倒数的时间;一旦按键后则开始倒数计时,当计时为零则发出一阵音乐声响,
程序开始执行,显示器显示“0009”,按下操作键S1~S3动作如下:
操作键S1,可调整倒数时间时分秒;操作键S2,设置倒数计时时间为上升,显示“增加”;操作键S3,设置倒数计时时间为下降,显示“减少”;
RESET按下后显示如下:
COUNTDOWN
00:
00:
09倒数时间
操作键S2:
增加倒数计时,操作键S3,减少倒数计时,操作键S1按第四下设置完成。
一旦按键后则开始倒数计时,当计时为0时则发出一段音乐。
二、设计目的
1、通过该设计能提高学生分析解决问题的能力。
2、了解模拟电路及数字电路的相关知识。
3、学习单片机定时器时间计时处理、按键扫描、LCD显示及音乐旋律演奏的设计方法。
三、设计的具体实现
1.系统概述
1.1总体方案论证
要实现音乐倒数定时器可以用两种方案实现。
方案一:
利用PROG-110可编程控制器
PROG-110可编程器,是一种用《数字简码》控制的产品,它的特点是:
自带一套用于输入数码的按键和显示程序的数码管,只要我们现场输入一列2位数码,编制的程序即能完成,即编,即用。
每一种《数字简码》控制器,它都自带一套系统软件,每一套系统软件都有一套相对应的指令表,配套的指令表表明,只要输入什么样的数,程序将去做什么事,输入一列数,它就会按次序去完成你要求它做的所有的事。
但是首先PROG-110模块总共只有6个I/O端口,这就必须扩展模块端口,用两部以上模块串联,但花钱要多;其次是程序过长,PROG-110模块的E2PROM存储器24C01只可输入128步程序;第三是受PROG-110模块跳转指令步数的限制。
方案二:
利用单片机、LCD显示器和压电喇叭
单片机具有性能高、速度快、体积小、价格低、稳定可靠、应用广泛、通用性强等突出优点。
它在硬件结构、指令系统、I/O端口、功率消耗及可靠性等方面均有其独特之处,其最显著的特点之一就是具有非常有效的控制功能。
而LCD显示器具有体积小、重量轻、工作电压低、功耗极低、显示内容丰富、稳定可靠、成本低、控制驱动方便、接口简单易用、模块化结构紧凑等特点。
综上所述,按照设计要求我选择第二种方案,即利用单片机和LCD显示器来实现定时倒数,通过压电喇叭来发出音乐。
1.2单片机选择方案
采用8051单片机
8051单片机内部包含一个8位CPU、一个片内振荡器及时钟电路、ROM程序存储器、RAM数据存储器、两个16位定时器/计数器、可分别寻址64KB的程序存储器空间和64KB的数据存储器空间、32条可编程的I/O口线(4个8位并行I/O端口)、一个可编程全双工串行口、具有5个中断源和2个优先级的中断结构。
可以有效实现本次设计中要求的各项功能。
具体的设计流程可见图1:
图1设计流程图
2.单元电路设计
2.1控制电路
倒数计数器的控制电路可以见附图,其中主要分为以下几部分
(1)单片机8051
8051基本资料如下:
图28051引脚图
8051主要使用引脚功能说明如下:
●8051的引脚40接+5V电源,引脚20接电源地线。
●传统8051工作时钟的最高为12MHz。
●EA引脚低电平动作用来存取外部程序ROM控制。
●EA接地,由外部程序ROM来执行程序。
●EA接高电平,由内部ROM来执行程序。
●开机时必须加入芯片重置信号。
(RESET)
●RESET信号高电平动作,高电平时产生芯片重置。
●RESET信号低电平时,由程序ROM地址0开始执行程序。
在本次设计中采用的8051外接电路如图3所示:
图38051外接电路图
8051系列的单片机的时钟方式分为内部方式和外部方式。
内部方式就是在单片机的引脚18、19外接晶振,就够成了自激振荡器在单片机内部产生时钟脉冲信号。
外部时钟方式是把外部已经有的时钟信号引入到单片机内部。
时钟电路在计算机系统中起着非常重要的作用,是保证系统正常工作的基础。
在一个单片机应用系统中,时钟有两方面的含义:
一是指为保障系统正常工作的基准振荡定时信号,主要由晶振和外围电路组成,晶振频率的大小决定了单片机系统工作的快慢;二是指系统的标准定时时钟,即定时时间。
用一个12MHz晶振和两个30Pf瓷片电容组成,为单片机提供标准时钟,其中两个瓷片电容可以增加电路的稳定性,可以抗噪声增加稳定性,不容易死机。
在8051中之所以采用高性能的振荡电路,因为:
1.单片机电子钟的计时脉冲基准是由外部晶振的频率经过12分频后提供,采用内部的定时/计数器来实现计时功能。
所以,外接晶振频率精确度直接影响电子钟计时的准确性。
2.单片机电子钟利用内部定时/计数器溢出产生中断(12M晶振一般为50ms)再乘以相应的倍率来实现秒、分、时的转换。
大家都知道从定时/计数器产生中断请求到响应中断需要3-8个机器周期,定时中断子程序中的数据入栈和重装定时/计数器的初值还需要占用数个机器周期,还有从中断入口转到中断子程序也要占用一定的机器周期。
(2)复位电路
图4单片机复位电路
本次设计使用的倒数计时LCD控制,使用的是16字*2行设计。
图4中为4位控制电路,以8051P0的6调输出控制线来实现控制,P0还有提升电阻以增强其驱动能力,控制信号如下:
R/W=0,LCD执行写入的动作,RS寄存器选择控制线。
EN启用控制线。
VO亮度调整控制引脚。
D0~D7双向的数据总线。
必须在有亮度照明的地方,才能看见时间,若使用LCD,选择有背光显示的模块,则在夜晚或黑暗的场合也可以使用,有背光显示的LCD模块在引脚上,与无背光显示的模块兼容,指示价格较贵,一般显示的背光颜色为黄光,与手机的背光颜色相似。
(3)按键控制
按键控制室控制程序执行时数据的输入或是特殊功能的设置及操作,使用8051端口2的4条输入口,由程序来控制,平时输入端为高电平,当有按键按下则相对位会呈现低电平,进过轮流扫描判断输入端是否为低电平,便可知道按下的是哪一个按钮。
(4)音乐喇叭
8051端口1的第3位是压电喇叭的驱动位,持续送出工作脉冲可以推动喇叭发出哔的声响,当工作频率越高时,声音越清脆,工作频率低时,声音则较低沉。
(5)电源输入
J1为+5V电源输入,当电源加入时电源指示灯LED将亮起,用哪个以指示电源供给正常,定时器在倒数时间到后压电喇叭会发出音乐旋律,并启动继电器使其状态为ON,控制继电器的ON/OFF状态,可以直接控制家电开关。
2.2控制程序
本课程设计中,可以学习利用单片机定时器设计时间计时处理,其时分秒控制,定时器0计时中断程序每个5ms中断一次当做一个计数,每中断一次则计数加1,当计数200次时,表示1s到了,秒变量加1,同理再判断是否1min钟到了,再判断是否1h到了,若计数到了则将相关变量清除为0。
单片机定时器负责定时的技术,不会因为案件处理而中断时间描述的增加,时,分,秒数据是存在变量内并写入LCD而显示相关时间的。
在主控程序循环中主要工作为扫描是否有按键,若有按键则做相应的功能处理,同时也检查所倒数的时间是否为0,若为0表示倒数的时间终了,应该执行想对应的工作了,图为主程序控制工作流程。
时间计时处理程序时等过了1s后,则更新时间数据,将最新剩余倒数的分秒的时间数据转换为数字数据,并显示在LCD上。
程序中如何判断是否已过了1s?
可以设一旧秒数变量,当新旧秒数变量不一样时,则表示已过了1s,要做相关程序处理了。
倒数计时闹铃的动作利用时间计时处理来做秒数倒数,当所设置的时间为0,压电喇叭则不断发出音乐声,LED持续闪动,启动继电器,有继电器可以控制家电开启或关闭。
音乐声的产生也是有定时器来产生固定频率的方波信号推动压电喇叭,发出旋律。
而定时器原先已利用设计时间计时处理了,怎么能在设计来做音乐旋律的控制?
在此设计定义一个音乐演奏标志,若音乐演奏标志为0则执行中断程序中计时程序的部分程序,若音乐演奏标志为1则执行音乐发生控制程序。
因此只要适当的运用程序设计技巧,计时中断程序中可以做许多种不同的工作,而这些工作是需要特定一段时间久必须要被触发而被执行的程序。
倒数计数器控制程序文件名为DSDS.ASM。
注意:
在程序中128行有以下的指令:
SINCLUDE(DSDS1.ASM);加载程序一起来汇编及编译
表示在主程序DSDS.ASM中还会自动加载另一程序DSDS1.ASM程序一起进来汇编及编译,只是为了方便程序编译用,一些测试正确的程序代码可以分别存档好方便管理,此外整个程序源代码长度也不至于太长,不方便编辑。
DSDS1.ASM主要的程序代码功能为以定时器演奏歌曲旋律的控制。
3.软件程设计和调试
3.1延时时间的计算
若我们想设计程序执行55ms时间延时,程序可以设计如下
//延时
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
如果执行18次此子程序,则延时时间约为1s
3.2工作方式设计
本次设计中采用的定时器模式0来设计,在此方式中T0、T0可以进行13位的计时,其值保存在两个8位的定时寄存器中。
对于其中任一定时器,工作时钟可以由内部或是外部来提供,由C/T位来决定做定时器还是计数器。
定时器的时钟为系统工作时钟除以12.此次试验中采用12MHz石英震荡器则产生55ms的计数时间脉冲宽度。
本次实验的定时器计时时间为1s,因此定时器0需计数5000次,其定时器初值的加载可以计算如下:
TH0=(65536-5000)/256
TL1=(65536-5000)%256
执行后的结果为,产生的脉冲宽度为
T=55ms
3.3有定时器产生各种频率的声音
我们可以设定发音的频率来改变声音产生音乐,计时时间长短也是按照发音的频率而定的。
由频率值推得定时器计数初值由下关系式得到:
T=1/f(us);方波宽度
Co=(int)t/2;定时器所得计数的次数
TH0=(65536-5000)/256;计数初值底字节
TL1=(65536-5000)%256;计数初值高字节
软件的编译和调试使用的是KEIL软件,文件格式是C。
3.4程序说明
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitlcde=P1^0;
sbitlcdrs=P1^1;
sbitlcdw=P1^2;
sbitspeaker=P1^3;
sbits1=P3^0;
sbits2=P3^1;
sbits3=P3^2;
sbitrd=P3^7;
ucharcodetable[]="countdown!
";
ucharcodetable1[]="00:
00:
09";
ucharcount,s1num;
staticcharmiao=9,shi=0,fen=0;
//生日快乐歌的音符频率表,不同频率由不同的延时来决定
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_TONE[]={212,212,190,212,159,169,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};
//ucharcodeSONG_LONG[]={9,3,12,12,12,24,0};
//延时
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidwrite_com(ucharx)
{P2=x;
lcdrs=0;
lcdw=0;
lcde=1;
delay
(2);
lcde=0;
lcdw=0;
}
voidwrite_date(ucharx)
{
lcdrs=1;
lcdw=0;
P2=x;
//delay(5);
lcde=1;
delay
(2);
lcde=0;
}
voidwrite_sfm(ucharadd,uchardate)
{
ucharshi,ge;
shi=date/10;
ge=date%10;
write_com(0x80+0x40+add);
write_date(0x30+shi);
write_date(0x30+ge);
}
//播放函数
voidPlayMusic()
{uinti=0,j,k;
while(SONG_LONG[i]!
=0||SONG_TONE[i]!
=0)
{//播放各个音符,SONG_LONG为拍子长度
for(j=0;j{
speaker=~speaker;
//SONG_TONE延时表决定了每个音符的频率
for(k=0;k}
delay(10);
i++;
}
}
voidinit()
{
ucharnum;
write_com(0x38);
write_com(0x0c);
write_com(0x06);
write_com(0x01);
write_com(0x80);
for(num=0;num<15;num++)
{
write_date(table[num]);
delay(5);
}
write_com(0x80+0x40);
for(num=0;num<12;num++)
{
write_date(table1[num]);
delay(5);
}
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
EA=1;
ET0=1;
TR0=1;
}
voidkeyscan()
{
//rd=0;
if(s1==0)
{
delay(5);
if(s1==0)
{s1num++;
while(!
s1);
if(s1num==1)
{
TR0=0;
write_com(0x80+0x40+10);
write_com(0x0f);
}
}
if(s1num==2)
{
write_com(0x80+0x40+7);
}
if(s1num==3)
{
write_com(0x80+0x40+4);
}
if(s1num==4)
{
s1num=0;
write_com(0x0c);
TR0=1;
}
}
if(s1num!
=0)
{
if(s2==0)
{
delay(5);
if(s2==0)
{
while(!
s2);
if(s1num==1)
{
miao++;
if(miao==60)
miao=0;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen++;
if(fen==60)
fen=0;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi++;
if(shi==24)
shi=0;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
if(s3==0)
{
delay(5);
if(s3==0)
{
while(!
s3);
if(s1num==1)
{
/*if(miao==0)
{
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}*/
miao--;
if(miao==-1)
miao=59;
write_sfm(10,miao);
write_com(0x80+0x40+10);
}
if(s1num==2)
{
fen--;
if(fen==-1)
fen=59;
write_sfm(7,fen);
write_com(0x80+0x40+7);
}
if(s1num==3)
{
shi--;
if(shi==-1)
shi=23;
write_sfm(4,shi);
write_com(0x80+0x40+4);
}
}
}
}
}
voidmain()
{
init();
while
(1)
{
keyscan();
if(miao==0&&fen==0&&shi==0)
{TR0=0;
PlayMusic();
}
}
}
voidtimer0()interrupt1
{
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
count++;
if(count==18)
{
count=0;
miao--;
if(miao==-1)
{
miao=59;
fen--;
if(fen==-1)
{
fen=59;
shi--;
if(shi==-1)
{
shi=23;
}
write_sfm(4,shi);
}
write_sfm(7,fen);
}
write_sfm(10,miao);
}
}
四、结论和展望
本次设计比较复杂,而且设计的基础知识很多,也很重要,对我们未来的工作和学习有着一定的奠基作用,是对单片机、数电、模电等知识的总结很归纳。
本次设计参考资料较多,而且由于没有设计完成电路制版,所以对设计的程序没有办法验证其正确性,只能说明理论上的程度可以实现。
如何实现各方面的知识相结合,怎么样合理利用器件管脚,对于单片机汇编语言的掌握,以及各个指令相互之间的配合都是在这个课程设计中有所体现的,也是我以后需要加强的。
在8051单片机本身须加上系统工作时钟,在此使用12MHz的石英振荡晶体,此与串行传输接口波特率时钟设计有关,在此利用RC线路产生RESET信号用于系统重置,另外接有手动开关按键,只要按下此按键就可以重新设计程序。
如果是以ROM模拟器来测试程序,可以有模拟器送进高电平脉冲而达到程序下载时,系统自动重置而执行程序。
在本电路中可以使用的I/O引脚数少,可是可以做很多的功能扩充。
在本次设计的基础上还可以扩展:
增加时钟及闹钟功能
增加码表计数功能
增加万年历显示“年月日”
增加多组计时倒数功能
五、心得和体会
我在设计期翻阅了大量参考书籍和论文,弄通了软件Protel99SE的功能及使用方法。
在老师的指导