基于STC89C52的电子时钟设计Word格式.docx
《基于STC89C52的电子时钟设计Word格式.docx》由会员分享,可在线阅读,更多相关《基于STC89C52的电子时钟设计Word格式.docx(23页珍藏版)》请在冰点文库上搜索。
当人为按下按钮时,则Vcc的+5V电平就会直接加到RST端。
手动按钮复位的电路如图所示。
由于人的动作再快也会使按钮保持接通达数十毫秒,所以,完全能够满足复位的时间要求。
图2复位电路
3.2晶振电路
51单片机最小系统晶振Y1也可以采用6MHz或者11.0592MHz,在正常工作的情况下可以采用更高频率的晶振,51单片机最小系统晶振的振荡频率直接影响单片机的处理速度,频率越大处理速度越快。
单片机系统里都有晶振,在单片机系统里晶振作用非常大,全程叫晶体振荡器,他结合单片机内部电路产生单片机所需的时钟频率,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。
单片机晶振的作用是为系统提供基本的时钟信号。
通常一个系统共用一个晶振,便于各部分保持同步。
有些通讯系统的基频和射频使用不同的晶振,而通过电子调整频率的方法保持同步。
图3晶振电路
3.3LED显示电路
LED显示器工作方式有两种:
静态显示方式和动态显示方式。
静态显示的特点是每个数码管的段选必须接一个8位数据线来保持显示的字形码。
当送入一次字形码后,显示字形可一直保持,直到送入新字形码为止。
这种方法的优点是占用CPU时间少,显示便于监测和控制。
缺点是硬件电路比较复杂,成本较高。
动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。
选亮数码管采用动态扫描显示。
所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
一个八段数码管称为一位,多个数码管并列在一起可构成多位数码管,它们的段选线连在一起,而各自的公共端称为位选线。
显示时,都从段选线送入字符编码,而选中哪个位选线,那个数码管便会被点亮。
图4LED显示电路
3.4按键输入电路
独立式按键采用每个按键单独占有一个I/O口的结构,这是最简单的键盘输入设计。
当按下和释放按键时,输入到I/O口端的电平是不一样的,单片机程序根据不同端口的电平变化判断是否有键按下以及是哪一个键被按下。
独立式键盘的原理简单,每个按键的电路是独立的,占用一条数据线。
这种接法占用硬盘资源大,适合该课程设计的电子时钟电路。
图5独立按键
3.5蜂鸣器电路
蜂鸣器是一种一体化结构的电子讯响器,采用直流电压供电,广泛应用于计算机、打印机、复印机、报警器、电子玩具、汽车电子设备、电话机、定时器等电子产品中作发声器件。
蜂鸣器主要分为压电式蜂鸣器和电磁式蜂鸣器两种类型。
压电式蜂鸣器压电式蜂鸣器主要由多谐振荡器、压电蜂鸣片、阻抗匹配器及共鸣箱、外壳等组成。
有的压电式蜂鸣器外壳上还装有发光二极管。
多谐振荡器由晶体管或集成电路构成。
当接通电源后(1.5~15V直流工作电压),多谐振荡器起振,输出1.5~2.5kHZ的音频信号,阻抗匹配器推动压电蜂鸣片发声。
压电蜂鸣片由锆钛酸铅或铌镁酸铅压电陶瓷材料制成。
在陶瓷片的两面镀上银电极,经极化和老化处理后,再与黄铜片或不锈钢片粘在一起。
电磁式蜂鸣器由振荡器、电磁线圈、磁铁、振动膜片及外壳等组成。
接通电源后,振荡器产生的音频信号电流通过电磁线圈,使电磁线圈产生磁场。
振动膜片在电磁线圈和磁铁的相互作用下,周期性地振动发声。
图6蜂鸣器电路
4.软件设计方案
4.1软件设计方法
系统的软件设计也是工具系统功能的设计。
单片机软件的设计主要包括执行软件的设计和监控软件的设计。
单片机的软件设计通常要考虑以下几个方面的问题:
●根据软件功能要求,将系统软件划分为若干个相对独立的部分,设计出合理的总体结构,使软件开发清晰、简洁和流程合理;
●培养良好的编程风格,如考虑结构化程序设计、实行模块化、子程序化。
既便于调试、链接,又便于移植和修改;
●建立正确的数学模型,通过仿真提高系统的性能,并选取合适的参数;
●绘制程序流程图;
●合理分配系统资源;
●为程序加入注释,提高可读性,实施软件工程;
●注意软件的抗干扰设计,提高系统的可靠性。
4.2系统软件设计思想
本系软件设计中,利用单片机定时器设计时间计时处理,采用单片机内部的T0定时器溢出中断来实现,工作在T0方式下,定时250微妙,则连续中断4000次即为一秒,得到了我们所需时间的最小单位
该设计用C51编写程序,由于汇编语言的移植性比较差,而C语言则比较灵活。
许多子函数都可以直接移植过去。
在程序中除了有主函数外还包含许多子函数,如延时函数、按键扫描函数、初始化函数、时间显示函数、设定闹钟显示函数、调时、分、秒函数、功能切换函数、秒表功能函数。
4.3系统主程序
在主控程序循环中主要工作为扫描是否有按键,若有按健则做相应的功能处理,同时也扫描显示器显示时间数据,并检查所设置的时间是否到了。
时间计时处理程序是等过了1s后,则更新时间数据,将最新的时、分、秒的数据转换为数字数据并显示在八段数码管上。
图7系统主程序流程图
4.4中断子程序
中断子程序的主要功能:
提供时间基准和快速按键调时功能。
4.4.1定时器T0的中断程序设计
定时器T0中断提供时间基准。
当T0连续中断4000次时,即为一秒,此时秒加一;
当秒值为60时,分钟加一,同时秒清零;
当分钟值为60时,小时加一,同时分钟值清零;
当小时为24时,小时清零。
图8T0中断程序流程图
4.4.2定时器T1的中断程序设计
当T1中断500次时,检测一次选择按键S3,如果按键按下,检测时间加减按键,对应按键按下则执行对应的操作,选择按键可选择调时、调分、调秒以及让时间加减按键失效这四种功能,这样可以达到迅速校准时间的作用。
图9T1中断程序流程图
4.5按键扫描子程序
按键扫描子程序是程序计中相当重要的一部分。
按键扫描子程序的功能是:
扫描S4键是否按下,若S4键按下,则执行相应功能。
标志变量flag的初值设为1,当按下S4键时,标志变量flag值加1,对应切换至所设置的功能。
具体切换任务:
flag值为1时可以显示时钟并对时间进行校准,当flag值为2时,切换至秒表功能;
当flag值为3时,切换至闹钟设置功能;
当flag值为4时,flag值返回1,回到时钟显示并可以调时。
图10按键扫描程序流程图
4.6调时、分、秒子程序
当选择按键状态选择到调秒时,相应的按下S2即对秒进行加1运算,当秒到加到60时,秒清零;
按下S1即对秒进行减1运算,当减到零时,秒等于59。
选择按键切换时,对应的键可以调分和小时。
调分和调时子程序和调秒子程序类似。
图11调秒程序流程图
4.7调节闹钟子程序
当标志变量flag值为3时,切换至调节闹钟功能。
检测调节选择按键S3是否按下,如果按下则状态变量n加1,然后根据状态变量的值调用相应的调时、分、秒子程序来实现对闹钟的调节。
图12调节闹钟程序流程图
5.调试与功能说明
单片机应用系统的调试包括硬件和软件两部分,但是他们并不能完全分开。
一般的方法是排除明显的硬件故障,再进行综合调试,排除可能的软/硬件故障。
5.1硬盘调试
拿到电路板后,首先要检查加工质量,并确保没有任何方面的错误,如短路和断路,尤其要避免电源短路;
元器件在安装前要逐一检查,用万用表测其数值,看是否与所用相同;
完成焊接后,应先空载上电(芯片座上不插芯片),并检查各引脚的电位是否正确。
若一切正常,方可在断电的情况下将芯片插入,再次检查各引脚的电位及其逻辑关系。
将万用表的探针放到单片机接电源的引脚上检测一下,看是否符合要求。
5.2系统性能测试与功能说明
走时:
默认为走时状态,按24小时制分别显示“时时-分分-秒秒”,有2个“-”动态显示,时间会按实际时间以秒为最少单位变化。
走时调整:
检测一次选择按键S3,如果按键按下,检测时间加减按键,对应按键按下则执行对应的操作,选择按键可选择调时、调分、调秒以及让时间加减按键失效这四种功能,这样可以达到迅速校准时间的作用。
5.3系统时钟误差分析
时间是一个基本物理量,具有连续、自动流逝、不重复等特性。
我国时间基准来自国家授时中心,人们日常使用的时钟就是以一定的精度与该基准保持同步的。
结合时间概念和误差理论,可以定义电子钟的走时误差S=S1-S2,S1表示程序实际运行计算所得的秒;
S2表示客观时间的标准秒。
S>
0时表示电子钟秒单元数值刷新滞后,即走时误差为“慢”;
反之,S<
0表示秒单元数值的刷新超前,即走时误差为“快”。
本次设计的单片机电子钟系统中,其误差主要来源包括晶体频率误差,定时器溢出误差,延迟误差。
晶体频率产生震荡,容易产生走时误差;
定时器溢出的时间误差,本应这一秒溢出,但却在下一秒溢出,造成走时误差;
延迟时间过长或过短,都会造成与基准时间产生偏差,造成走时误差。
5.4软件调试问题及解决
软件程序的调试一般可以将重点放在分模块调试上,统调是最后一环。
软件调试可以采取离线调试和在线调试两种方式。
本次课题,Keil软件来调试程序,通过各个模块程序的单步或跟踪调试,使程序逐渐趋于正确,最后统调程序。
6.设计总结
我在这一次单片机最小系统的设计过程中,很是受益匪浅。
通过对自己在大学二年时间里所学的知识的回顾,并充分发挥对所学知识的理解和对课程设计的思考及书面表达能力。
这为自己今后进一步深化学习,积累了一定宝贵的经验。
撰写报告的过程也是专业知识的学习过程,它使我运用已有的专业基础知识,对其进行设计,分析和解决一个理论问题或实际问题,把知识转化为能力的实际训练。
培养了我运用所学知识解决实际问题的能力。
通过这次课程设计我发现,只有理论水平提高了;
才能够将课本知识与实践相整合,理论知识服务于教学实践,以增强自己的动手能力。
这个实验十分有意义我获得很深刻的经验。
通过这次课程设计,我们知道了理论和实际的距离,也知道了理论和实际想结合的重要性,,也从中得知了很多书本上无法得知的知识。
我们的学习不但要立足于书本,以解决理论和实际教学中的实际问题为目的,还要以实践相结合,理论问题即实践课题,解决问题即课程研究,学生自己就是一个专家,通过自己的手来解决问题比用脑子解决问题更加深刻。
学习就应该采取理论与实践结合的方式,理论的问题,也就是实践性的课题。
这种做法既有助于完成理论知识的巩固,又有助于带动实践,解决实际问题,加强我们的动手能力和解决问题的能力。
参考文献
[1]李群芳,肖看,张士军.单片机微型计算机与技术接口.电子工业出版社,1997.12.125-133
[2]彭为,黄科,雷道仲.单片机典型系统设计实例讲解.电子工业出版社,2002.125-133
[3]何立民.MCS-51单片机应用系统设计.北京航空航天大学出版社,1995.99-112
[4]杨刚,周群.电子系统设计与实践.电子工业出版社,1998.79-102
[5]张毅刚.单片机原理及应用.高等教育出版社,1999.125-143
[6]张毅刚.MCS-51单片机应用设计.哈尔滨工业大学出版社,1994.125-133
[7]张富.C及C++程序设计(第3版).人民邮电出版社,1998.79-112
[8]李华.MCS-51系列单片机使用接口技术.北京航空航天大学出版社,2005.7.115-123
[9]李广弟.单片机基础.北京航空航天大学出版社,1998.95-123
附录1:
多功能电子时钟原理图
附录2:
C语言源程序
#include<
regx52.h>
#defineucharunsignedchar
#defineuintunsignedint
#definekeyP3
ucharcodewei[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
ucharcodeduan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
ucharnum1[]={0,0,10,0,0,10,0,0};
ucharnum2[]={0,0,0,0,0,0,0,0};
ucharsec=55,min=59,hou=23;
ucharsec_1=0,min_1=1,hou_1=0;
uintsec1=0,sec2=0;
intcount1=0,count2=0,cnt=0,cnt2=0;
ucharflag=1,flag2=0;
ucharm;
voiddelay(uintx)
{uinta,b;
for(a=0;
a<
x;
a++)
for(b=0;
b<
113;
b++);
}
voiddisplay1(char_hou,char_min,char_sec)
{num1[0]=_sec%10;
num1[1]=_sec/10;
num1[3]=_min%10;
num1[4]=_min/10;
num1[6]=_hou%10;
num1[7]=_hou/10;
}
voiddisplay2(uintx,uinty)
{num2[0]=((x%1000)%100)%10;
num2[1]=((x%1000)%100)/10;
num2[2]=(x%1000)/100;
num2[3]=x/1000;
num2[4]=((y%1000)%100)%10;
num2[5]=((y%1000)%100)/10;
num2[6]=(y%1000)/100;
num2[7]=y/1000;
voidswitch_(void)
{switch(flag)
{case1:
display1(hou,min,sec);
break;
case2:
display2(sec1,sec2);
case3:
display1(hou_1,min_1,sec_1);
case4:
flag=1;
default:
}}
voidkey_scan1()
{if((key==0xfb)&
&
(flag==1)){m++;
if(m==1)
{if(key==0xfd)
{sec++;
if(sec>
=60)
{sec=0;
}}
if(key==0xfe)
{if(sec==0)
{sec=60;
}sec--;
}}
if(m==2)
{if(key==0xfd)
{min++;
if(min>
{min=0;
hou++;
if(hou>
=24)
{hou=0;
}}}
if(key==0xfe)
{if(min==0)
{min=60;
}min--;
if(m==3)
{hou++;
if(hou>
=24)
{hou=0;
}}
{if(hou==0)
{hou=24;
}hou--;
if(m==4)
{m=0;
voidkey_scan2()
{ucharx;
if(P3_3==0)
{delay(10);
if(P3_3==0)
{flag++;
TR1=0;
sec1=0;
sec2=0;
while(P3_3==0)
{for(x=0;
x<
8;
x++)
{switch_();
P0=0xff;
P2=wei[x];
if((flag==1)||(flag==3))
{P0=duan[num1[x]];
else{P0=duan[num2[x]];
}delay
(1);
voidkey_tran2()
{if(flag==1){TR1=1;
if((key==0xfb)&
(flag==2))
{delay(10);
if(key==0xfb)
{cnt2++;
}while(key==0xfb);
switch(cnt2)
{case1:
TR1=1;
case2:
case3:
cnt2=0;
sec1=0,sec2=0;
default:
voidkey_scan3()
(flag==3))
{flag2++;
}while((key==0xfb)&
(flag==3));
if(flag2==1)
{if(key==0xfd)
{sec_1++;
if(sec_1>
{sec_1=0;
}while(key==0xfd);
{if(sec_1==0)
{sec_1=60;
}sec_1--;
}while(key==0xfe);
if(flag2==2)
{min_1++;
if(min_1>
{min_1=0;
hou_1++;
if(hou_1>
{hou_1=0;
}}}while(key==0xfd);
{if(min_1==0)
{min_1=60;
min_1--;
if(flag2==3)
{if(key==0xfd)
{hou_1++;
if(hou_1>
{hou_1=0;
}}
while(key==0xfd);
if(key==0xfe)
{if(hou_1==0)
{hou_1=24;
hou_1--;
while(key==0xfe);
if(flag2==4)
{flag2=0;
}}
voidfmq()
{if((sec==sec_1)&
(min==min_1)&
(hou==hou_1))
{P1_0=0;
delay(5000);
P1_0=1;
if((min==0)&
(sec==0))
{P1_0=0;
delay(1000);
voidmain()
P1_0=1;
P0=0xff;
P2=0xff;
P3=0xff;
TMOD=0x22;
TL0=6;
TH0=TL0;
TL1=6;
TH1=TL1;
EA=1;
ET0=1;
ET1=1;
TR0=1;
TR1=1;
while
(1)
{for(x=0;
else
{P0