• 1.21 MB
  • 31页

数字时钟设计开发项目报告

  • 31页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'常州工程职业技术学院计算机技术系项目工作报告课程名称单片机与接II技术(C51)班级计算机1213学号姓名项目序号项目一项目名称数字时钟设计开发实训日期/时间2014.2〜2014.5地点指导教师同组成员仪器设备(参考资料)计算机、KeiluVision2、ProteusISIS实训内容(任务安排)1-1需求分析、硬件设计方案确定1-2软件开发与实现1-3软硬件联调1-4项目验收总结一、项目概述 以单片机STC89C52RC作为主控芯片,利用按键、数码管显示模块,结合中断、定吋器功能,构成一个数字时钟,通过项目实训掌握单片机基木输入输出系统的设计与应用。二、项H要求针对每个项目,教师给出所需背景知识、参考资料、师生交流平台、项目要求、相关案例、开发流程、注意事项等指导学生。根据项0开发流程组成学生开发团队,创建协作学习环境。每个团队由6-8人组成,分别担当不同角色。这种模拟教学法的做法模拟了企业中真实开发情景,使学生在学习过程中感受到公司工作的气氛。具体要求如下:1、能够简单分析实际项目的功能需求;2、能够进行10接口电路设计与元器件选型;3、能够使用Proteus绘制电路原理图并仿真;4、能用C51设计应用程序;5、能够对系统进行测试与优化;6、能够编制规范的技术文档;7、能对系统软硬故障进行检测与排除;8、培养自主学习能力、收集分析、处理信息能力、团队协作能力;9、培养职业道德素质、心理素质、沟通、组织和执行任务的能力;10、培养汇报发言时,条理清晰,表达清楚,体现出认真细致、全而的思维习惯。11、培养学生良好的工作设计习惯。12、培养实事求是、客观公正的评价自己,体现在社会交往中的承受挫折与迎接挑战的意识。 三、系统设计1、框图设计2、知识点1)单片机型号的选择89C51是最理想的电子时钟开发芯片。89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CM0S8位微处理器,器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的89C51是一种高效微控制器,而且它与MCS-51兼容,且具有4K字节可编程闪烁存储器和1000写/擦循环,数据保留时间为10年等特点,是最好的选择。2)数码管显示工作原理数码管是一种把多个LED显示段集成在一起的显示设备。有两种类型,一种是共阳型,一种是共阴型。共阳型就是把多个LED显示段的阳极接在一起,乂称为公共端。共阴型就是把多个LED显示段的阴极接在一起。阳极即为二极管的正极,又称为正极,阴极即为二极管的负极,又称为负极。通常的数码管又分为8段,即8个LED显示段,这是为工程应用方便 如设计的,分别为A、B、C、D、E、F、G、DP,其中DP是小数点位段。而多位数码管,除某一位的公共端会连接在一起,不同位的数码管的相同端也会连接在一起。数码管显示方法可分为静态显示和动态显示两种。静态显示就是数码管的8段输入及其公共端电平一直有效。动态显示的原理是,各个数码管的相同段连接在一起,共冋占用8位段引管线;每位数码管的阳极连在一起组成公共端。利用人眼的视觉暂留性,依次给出各个数码管公共端加有效信号,在此同时给出该数码管加有效的数据信号,当全段扫描速度大于视觉暂留速度时,显示就会清晰显示出来3)键盘电路设计该设计用到了个键盘,实现的功能比较完善,减少了硬件资源的损耗,该键盘可以实现小时和分钟的调节以及复位的控制。直接按下不松开,则可以通过按键实现分钟的累加,每按一次分钟加一;而连续两次按下按键不放松,则可实现小时的调节,同样每按一次小时加一。达到时间调节的目的。4)晶振振荡器电路单片机系统里都有晶振,在单片机系统里晶振作用非常大,全程叫晶体振荡器,他结合单片机内部电路产生单片机所需的时钟频率,单片机晶振提供的时钟频率越高,那么单片机运行速度就越快,单片接的一切指令的执行都是建立在单片机晶振提供的时钟频率。在通常工作条件下,普通的晶振频率绝对精度可达百万分之五十。高级的精度更高。有些晶振还可以由外加电压在一定范围内调整频率,称为压控振荡器(VCO)。晶振用一种能把电能和机械能相互转化的晶体在共振的状态下工作,以提供稳定,精确的单频振荡。单片机晶振的作用是为系统提供基木的时钟信号。通常一个系统共用一个晶振,便于各部分保持同步。有些通讯系统的基频和射频使用不同的晶振,而通过电子调整频率的方法保持同步。晶振通常与锁相环电路配合使用,以提供系统所需的吋钟频率。如果不同子系统需要不同频率的时钟信号,可以用与同一个晶振相连的不同锁相环来提供。下面我就具体的介绍一下晶振的作用以及原理,晶振一般采用如图la的电容三端式(考毕兹)交流等效振荡电路;实际的晶振交流等效电路如图lb,其中Cv是用来调节振荡频率,一般用变容二极管加上不同的反偏电压来实现,这也是压控作用的机理;把晶体的等效电路代替晶体后如图lc。其中Co,Cl,Ll,RR是晶体的等效电路。 分析整个振荡槽路可知,利用Cv来改变频率是有限的:决定振荡频率的整个槽路电容 C=Cbe,Cce,Cv三个电容串联后和Co并联再和Cl串联。可以看出:C1越小,Co越大,Cv变化时对整个槽路电容的作用就越小。因而能“压控”的频率范围也越小。实际上,由于C1很小(1E-15量级),Co不能忽略(1E-12量级,几PF)。所以,Cv变大时,降低槽路频率的作用越来越小,Cv变小吋,升高槽路频率的作用却越来越大。这一方面引起压控特性的非线性,压控范围越大,非线性就越厉害;另一方面,分给振荡的反馈电压(Cbe上的电压)却越来越小,最后导致停振。通过晶振的原理图你应该大致了解了晶振的作用以及工作过程了吧。采用泛音次数越高的晶振,其等效电容C1就越小;因此频率的变化范围也就越小。微控制器的时钟源可以分为两类:基于机械谐振器件的时钟源,如晶振、陶瓷谐振槽路;RC(电阻、电容)振荡器。一种是皮尔斯振荡器配置,适用于晶振和陶瓷谐振槽路。另一种为简单的分立RC振荡器。用万用表测量晶体振荡器是否工作的方法:测量两个引脚电压是否是芯片工作电压的一半,比如工作电压是51单片机的+5V则是否是2.5V左右。另外如果用镊子碰晶体另外一个脚,这个电压有明显变化,证明是起振了的。晶振的类型有SMD和DTP型,即贴片和插脚型。5)单片机的复位电路在上电或复位过程中,控制CPU的复位状态:这段时间内让CPU保持复位状态,而不是一上电或刚复位完毕就工作,防止CPU发出错误的指令、执行错误操作,也可以提高电磁兼容性能。无论用户使用哪种类型的单片机,总要涉及到单片机复位电路的设计。而单片机复位电路设计的好坏,直接影响到整个系统工作的可靠性。许多用户在设计完单片机系统,并在实验室调试成功后,在现场却出现了“死机”、“程序走飞”等现象,这主要是单片机的复位电路设计不可靠引起的。基本的复位方式单片机在启动吋都需要复位,以使CPU及系统各部件处于确定的初始状态,并从初态开始工作。89系列单片机的复位信号是从RST引脚输入到芯片内的施密特触发器中的。当系统处于正常工作状态时,且振荡器稳定后,如果RST引脚上有一个高电平并维持2个机器周期(24个振荡周期)以上,贝UCPU就可以响应并将系统复位。单片机系统的复位方式有:手动按钮复位和上电复位6)中断中断就是一个资源面对多项任务的处理方式,由于资源有限,面对多项任务同时要处理 时,就会出现资源竞争的现象。中断技术就是为了解决资源竞争的一个可行的方法,采用中断技术可使多项任务共享一个资源。CPU正在执行原程序,突然,被意外事情打断,转去执行新程序。CPU执行新程序结束后,又回到原程序屮继续执行。这样的过程就叫屮断。首先来了解程序的格式:void函数名0interruptm[usingn]{}关键字interruptm[usingn]表示这是一个中断函数m为中断源的编号,有五个屮断源,取值为0,1,2,3,4,屮断编号会告诉编译器屮断程序的入U地址,执行该程序吋,这个地址会传个程序计数器PC,于是CPU开始从这里一条一条的执行程序指令。n为单片机工作寄存器组(又称通用寄存器组)编号,共四组,取值为0,1,2,3中断号中断源0外部中断01定吋器02外部中断13定时器1中断4串行口中断这5个屮断源的屮断入口地址为:(在上一篇文章屮讲到的ROM前43个存储单元就是他们,这40个地址用来存放中断处理程序的地址单元,每一个类中断的存储单元只有8B,显然不是中断处理的程序,而是存放着中断处理程序的真正地址)INTO:0003H0TO:000BII1INTI:0013H2Tl:001BH3串□:0023H4中断向量(中断入口地址)=中断号x8+3前面m意思很清楚,不同的m值表示这个函数是针对不同的屮断源,比如m为1是表示它是定时器0的中断函数,如voidtimeO()interrupt1{} 那么后面的usingn又是什么意思呢?在正在执行一个特定任务时,有更紧急的事情需要CPU来处理,涉及到中断优先权。高优先权中断低优先权正在处理的程序,所以最好给每个优先程序分配不同的寄存器组。CPU正在处理某个事件,突然另外一个事件需要处理,于是进入中断后,而你不想将现在执行的程序的各寄存器状态入栈,那么可以把这个中断程序放入另一个寄存器组,如切换到1组,然后退出中断时,再切回到0组(原来的程序在0组)。为了更好的了解这里意思,你可以看看工作寄存器组的作用是什么。下面的注意事项(1)中断函数不能进行参数传递(2)中断函数没有返回值(3)在任何情况下都不能直接调用中断函数(4)中断函数使用浮点运算要保存浮点寄存器的状态。(5)如果在屮断函数屮调用丫其它函数,则被调用函数所使用的寄存器必须与屮断函数相同,被调函数最好设置为可重入的。(6)C51编译器对中断函数编译时会自动在程序开始和结束处加上相应的内容,只体如下:在程序开始处对ACC、B、DPH、DPL和PSW入栈,结束时出栈。中断函数未加usingn修饰符的,开始时还要将RO~R1入桟,结束时出栈。如中断函数加usingn修饰符,则在开始将PSW入栈后还要修改PSW屮的工作寄存器组选择位。(7)C51编译器从绝对地址8m+3处产生一个中断向量,其中m为中断号,也即interrupt后面的数字。该向量含一个到中断函数入口地址的绝对跳转。(8)中断函数最好写在文件的尾部,并且禁止使用extern存储类型说明。防止其它程序调用。(9)在设计中断吋,要注意的是哪些功能应该放在中断程序中,哪些功能应该放在主程序中。一般来说中断服务程序应该做最少量的工作,这样做有很多好处。首先系统对中断的反应面更宽了,有些系统如果丢失中断或对中断反应太慢将产生十分严重的后果,这时有充足的时间等待中断是十分重要的。其次它可使中断服务程序的结构简单,不容易出错。中断程序中放入的东西越多,他们之间越容易起冲突。简化屮断服务程序意味着软件屮将有更多的代码段,但可把这些都放入主程序中。中断服务程序的设计对系统的成败有至关重要的作用,要仔细考虑各中断之间的关系和每个中断执行的时间,特别要注意那些对同一个数据进行操作 的ISR.7)定时器实质是计数器,脉冲每一次K降沿,计数寄存器数值将加1。计数的脉冲如果来源于单片机内部的晶振,由于其周期极为准确,这时称为定吋器。计数的脉冲如果来源于单片机外部的引脚,由于其周期一般不准确,这时称为计数器。定时器/计数器的结构定时器/计数器的实质是加1计数器(16位),由高8位和低8位两个寄存器组成。TMOD是定时器/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制TO、T1的启动和停止及设置溢出标志。定时器/计数器的工作原理计数器输入的计数脉冲源系统的时钟振荡器输出脉冲经12分频后产生;TO或T1引脚输入的外部脉冲源。计数过程每来一个脉冲计数器加1,当加到计数器为全1(即FFFFH)时,再输入一个脉冲就使计数器回零,且计数器的溢出使TCON中TFO或TF1置1,向CPU发出中断请求(定时器/计数器中断允许时)。如果定时器/计数器工作于定时模式,则表示定时时间己到;如果工作于计数模式, 则表示计数值己满。 定时应用用作定时器:此时设置为定时器模式,加1计数器是对内部机器周期计数(1个机器周期等于12个振荡周期,即计数频率为晶振频率的1/12)。计数值N乘以机器周期Tcy就是定时时间t。计数运用用作计数器:此时设置为计数器模式,外部事件计数脉冲由TO或T1引脚输入到计数器。每来一个外部脉冲,计数器加1。但单片机对外部脉冲有基本要求:脉冲的高低电平持续时间都必须大于1个机器周期。工作方式寄存器(TMOD)D7D6D5D4D3D2DIDOGATEC/TMlMOGATEC/TMlMO定时器T1定时器TOGATE:门控位。GATE=O吋,只要用软件使TCON中的TRO或TR1为1,就可以启动定吋器/计数器工作;(即需要一个启动条件)GATE=1时,要用软件使TRO或TR1为1,同时外部中断引脚也为高电平时,j能启动定时器/计数器工作,即需要两个启动条件。C/T:定时/计数模式选择位。C/T=0为定吋模式;C/T=1为计数模式。M1M0:工作方式设置位。计数器工作方式选择MlM0工作方式功能说明00方式013位计数器01方式116位计数器10方式2自动重装8位计数器11方式3定时器0:分成两个8位定时器1:停止计数定时器/计数器的控制控制寄存器TCON TCON的低4位用于控制外部中断,己在前面介绍。TCON的高4位用于控制定时器/计数器的启动和中断申请。其格式如下:位。7^&4^3^2^(k字节地址:88H,TFbTRLTFOTRoJ嗜TCON.,TF1(TCON.7):T1溢出中断请求标志位。T1计数溢出吋由硬件自动置TF1为1。CPU响应中断后TF1由硬件自动清0。TRI(TCON.6):T1起/停控制位。1:启动0:停止TFO(TCON.5):T0溢出中断请求标志位,其功能与TF1类同。TRO(TCON.4):T0起/停控制位。1:启动0:停止定时器/计数器的工作方式方式0方式0为13位计数,由TLO的低5位(高3位未用)和THO的8位组成TLO的低5位溢出时向方式1方式1的计数位数是16位,由TLO(TLl)作为低8位、THO(THl)作为高8位,组成了16位加1计数器。方式2方式2为自动重装初值的8位计数方式。 TON而)8醐器1H1重装单元TO引脚―>[6]复合运算符:+=>>=%=&=等[7]指针和地址运算符:*&九、C51库函数: 需包含intrins.hn);n);n);[1]本征函数注意:调用这些函数时,crol(X,n);cror(x,iror(x,n);irol(x,Irol(x,n);Iror(x,_nop_();testbit(bitbar);chkfloat(fltbar);[2]非本征函数reg51.h或reg52.h,其中包括了所有SFR的定义。absacc.h该文件中定义了儿个宏,以确定各存储空间的绝对地址。string,h包括复制、比较、移动等函数如:memccpy,memchr,memcmp,memcpy,memmove,memset等。stdio.h通过51单片机的串口或用户定义的1/0口读写数据,默认为串口,如需修改,可以修改LIB目录中的getkey.c及putchar.c源文件。maths,h各种数学函数如:sqrt、exp等。十、C51语法结构[1]单分支结构:if(条件)else[2]多分支结构:switch(变量)case值1:case值2: case值n: default:}[1]for循环:for(起始条件;循环条件;变量递增){}[2]while循环:while(条件){}[3]dowhile循环:do{}while(条件);[4]goto标号[5]死循环:while(1);here:gotohere;forH^一、C51应用技巧[1]灵活选择变量的存储器类型。由于单片机系统的存储器资源有限,为了提高执行效率,对存储器类型的设定应该根据以下原则:只要条件满足,尽量先使用内部直接寻址存储器(data),其次设定变量为间接寻址存储器(idata),在内部存储器数量不够的情况下,冰使用外部存储器,而且在外部存储器,优先选择pdata,最后方是xdata,而且,在内部和外部存储器共同使用的情况下,要合理分配存储器,对经常使用和计算频繁的数据,应该使用内部存储器,其他的则使用外部存储器。[2]另一个提高代码效率的方法就是减小变量的长度,51单片机是8位的,若使用int型的无簸是空间上的极大浪费。应尽可能选择的char、unsignedchar、或bit,它们只占用IB或1位。[3]再一个提高代码效率的方法是使用无符号类型,原因是51单片机指令不支持符号运算。若使用有符号类型的变量,C51编译器将耍增加相应的库函数去处理符号运算。[4]尽量避免使用浮点变量。浮点数占用4个字节,对单片机的存储器资源来说就是极大的浪费。浮点运算应尽量通过提高数值数量级或使用整型运算代替浮点运算。尽量减少乘除法运算,如*2或/2,可以使用移位操作代替,这样不仅可以减少代码量,同时还能大大提高程片;执行效率。[5]尽量使用库函数。C51的库函数提供的许多调令,尤其是本征函数,直接对应着汇编指令,编译效率较高。[6]使用宏替换。宏替换可以使程序具有更好的可读性,且当需要修改宏时,只要修改宏定义处即可。 [1]灵活设置变量,高效利用存储器。对于标志位要使用bit或sbit定义,而不耍使用unsignedchar。这样可以大量节省内存,编写C51程序时,不是特别必要的地方一般不要使用全局变量,尽量使用局部变量。四、硬件设计1、电路原理图1电路原理图采用定吋器0的工作方式1定吋500ms,等待20次定时Is进行吋钟计数。通过定吋器1的工作方式1定时500ms,用来调整数码管闪烁的时间。K1是用来选中时分秒,按一下选中时,再按一下选中分,再按一下选中秒,再按一下退出选中状态。K2按一下数加一,K3按一下数减一。在调整时间时,时钟停走。 2、元件清单表1元件清单元件清单名称型号数量芯片AT89C511数码管7SEG-MPX6-CA1锁存器74HC3731电容CERAMC33P2晶振CRYSTAL12MHZ1电容GEN-ELEC1二极管LED-BLUE1电阻MIN-RES2排阻RESPACK-8IK1BUTTON3 五、软件设计1.程序流程2主程序流程E 开始sec++sec〉=60sec=Osec=O;min++;一秒单元清零分单元加一分单元清零时单元加一min>=60min=O;hour++时单元清零hour=0hour>=24、中断返冋y3调整时间流程display(tablefhour/101,table[hour%10],table[min/l0],table[min%l0],table[sec/l0],ta blelsec%10],0xff) 开始秒个位计算显示1秒十位计算挝示1分个位计算显示1分十位计算显示i时个位计算显示4时间显示流程|时十位计算显示 1、程序清单总程序实现数字时钟的计时,功能是数码管通过动态扫描显示时间,时间可设定,调整时间吋吋钟不走.(1)主程序voidniain(){P2=0xff;hour=12;min=0;sec=0;TM0D=0xll;//工作方式THO=(65536-50000)/256;//定时器初始值TLO=(65536-50000)%256;TH1=(65536-50000)/256;TL1=(65536-50000)%256;EA=1;ETO=1;ET1=1;//允许定时器1中断TRO=1;//启动定时器TR1=1;aa=0xff;while(1){time_change();//显示时,分,秒的各位和十display(table[hour/10],table[hour%10],table[min/10],table[min%10],table[sec/10],table[sec%10],Oxff);}}(2)定时器中断程序voidtimerO()interrupt1{//控制次数//秒计时THO=(65536-50000)/256;//定时器重新赋初值//TLO=(65536-50000)%256;temp++;voidtimerl()interrupt3{TH1=(65536-50000)/256;TL1=(65536-50000)%256;count++;if(count>=20)count=0; (1)时间控制voidtimechange(){read_key():if(temp〉=20)//等待大于等于20次//{temp=0;sec+十;if(sec〉=60)//直到大于60秒//{sec=0;min++;//分开始加////Wl"aJiSaif(min〉=60)//直到大于等于60分//{min=0;hour++;//小时开始加//if(hour>=24)//小时大于24//{hour=0;//小吋清零//(2)显示函数voiddisplay(uchara,ucharb,ucharc,uchard,uchare,ucharf,ucharaa){if(num==l){Pl=0x01&aa;P0=a;delay(2);}else{Pl=0x01;P0=a;delay(2);}//hourif(num==l){Pl=0x02&aa;P0=b;delay(2);}else{Pl=0x02;P0=b;delay(2);}//hourif(num==2){Pl=0x04&aa;P0=c;delay(2);}else{Pl=0x04;P0=c;delay(2);}//minif(nura==2){Pl=0x08&aa;P0=d;delay(2);}else{Pl=0x08;P0=d;delay(2):}//minif(num==3){Pl=0xl0&aa;P0=e;delay(2);}else{Pl=0xl0;P0=e;delay(2);}//secif(num==3){Pl=0x20&aa;P0=f;delay(2);}else{Pl=0x20;P0=f;delay(2);}//sec} (1)按键控制voidread_key(){if(keyl==0){led=0;delay(100);if(keyl==0){delay(100);_led=l;num++;if(num>3){num=0;}while(1){if(keyl==0){_led=0;delay(10);if(keyl==0){num++;if(num>3){num=0;break;}}while(!keyl);delay(10);while(!keyl);jed=l;}if(key2==0){led=0;delay(80);if(key2==0){if(num二二1){hour++;if(hour==24)hour=0;}if(num~2){min++;if(min~60)min=0;}if(num=3){sec++;if(sec==60)sec=0;}}whi1e(!keyl);delay(10);while(!keyl);jed=l;}if(key3==0){led=0;delay(80);if(key3==0){if(num~l){hour—;if(hour==0)hour=23:}if(num~2){min—;if(min~0)min=59;}if(num~3){sec—;if(sec~59)sec=59;}}while(!keyl);delay(10);while(!keyl);_led=l;if(count<=15)display(table[hour/10],table[hour%10],table[niin/10],table[min%10],table[sec/10],tablo[sec%10],Oxff);if(count〉15)display(table[hour/10],table[hour%10],table[min/10],table[min%10],table[sec/10],table[sec%10],0x00);}}vhile(!keyl);delay(10);vhile(!keyl);_led=l;}} //kcyl时钟的时、分、秒三个时段来回切换////key2key2分别加减num表示时分秒三个时段假如num大于3就清零////num=l吋表示小吋num=2分钟num=3秒钟分别使用按键key2key3加减来冋切换等于246060时自动清零//六、系统仿真及调试1、源程序调试(1)现象:为什么我的显示吋乱跳的?而且中断响应后,数码管无变化(2)原因:程序有问题(3)解决方法:voiddelay(ucharz)改成voiddelay(uintz)2、正确结果显zK出来C2RP1RBBPACK-B«TEXI>*;U1■oo—131-OMPI?ngr?XTAL1PDITADDPQ.1/AD1P0^AD2XTA12P□崖D*P0S/AD5POJ&ADSR8Tpn?/An?VW«llr>ir1P2XWSP2.1WSP22/M0P23A11ALEP2