1-99秒倒计时器
****************
院 (系): 电气工程系
年 级: 10机电十班
*****************
二〇一二年九月
第一章 概论.......................................................1
2.1 ATC51的芯片概述..............................................3
2.2 硬件电路的设计...............................................4
2.3 LED数码管显示器概述............................................5
第四章 调试与仿真 ...................................................10
附件二 元件清单..............................................14
附件三 程序代码...............................................15
摘要
今年来随着计算机在社会领域的渗透,单片机的应用正在不断地走向深入,同时带动传统控制检测日新月益更新。在实时检测和自动控制的单片机应用系统中,单片机往往是作为一个核心部件来使用,仅单片机方面知识是不够的,还应根据具体硬件结构,以及针对具体应用对象特点的软件结合,以作完善。
单片机具有体积小、成本低、抗干扰能力强、面向控制、可以实现分机各分布式控制等优点。设计就是利用单片机的上述优点,采用目前市场上性能价格比较高的ATC51单片机设计而成的最小系统。它在实际生活中具有广泛的应用。例如:工业生产中的定时启停自动化设备、学校中上下课铃定时控制、农村广播站每天早中晚广播的自动定时控制均可采用本仪器。
模拟多通道压力系统是利用压力传感器采集当前压力并放映在显示器上,它可以分析压力过量程,并发出报警。并采用电子秤原理可根据输入单价准确的计算出物体的金额。本篇论文讨论了简单的倒计时器的设计与制作,对于倒计时器中的LED数码显示器来说,我为了简化线路、降低成本,采用以软件为主的接口方法,即不使用专门的硬件译码器,而采用软件程序进行译码。
【关键词】单片机;ATC51;LED数码管显示器;keil C;晶体振荡器
二、硬件设计
2.1.ATC51芯片
ATC51是一种带4K字节闪烁可编程可擦除只读存储器(FPEROM—Flash Programmable and Erasable Read Only Memory)的低电压,高性能CMOS 8位微处理器,俗称单片机。
图1 ATC51 单片机的内部结构
管脚说明:
图2 ATC51管脚图
(1)P0口:P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。当P1口的管脚第一次写1时,被定义为高阻输入。P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。在FIASH编程时,P0 口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须被拉高。
(2)P1口:P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。在FLASH编程和校验时,P1口作为第八位地址接收。
(3)P2口:P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。并因此作为输入时,P2口的管脚被外部拉低,将输出电流。这是由于内部上拉的缘故。P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
(4)P3口:P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
(5)RST:复位输入。当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
(6)ALE/PROG:当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的地位字节。在FLASH编程期间,此引脚用于输入编程脉冲。在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。因此它可用作对外部输出的脉冲或用于定时目的。然而要注意的是:每当用作外部数据存储器时,将跳过一个ALE脉冲。如想禁止ALE的输出可在SFR8EH地址上置0。此时, ALE只有在执行MOVX,MOVC指令是ALE才起作用。另外,该引脚被略微拉高。如果微处理器在外部执行状态ALE禁止,置位无效。
(7)/PSEN:外部程序存储器的选通信号。在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
(8)/EA/VPP:当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
(9)XTAL1:反向振荡放大器的输入及内部时钟工作电路的输入。
(10)XTAL2:来自反向振荡器的输出。
2.2硬件电路的设计
本设计分为硬件设计和软件设计,这两者相互结合,不可分离;从时间上看,硬件设计的绝大部分工作量是在最初阶段,到后期往往还要做一些修改。只要技术准备充分,硬件设计的大返工时比较少的,软件设计的任务贯彻始终,到中后期基本上都是软件设计任务,随着集成电路技术的飞速发展,各种功能很强的芯片不断出现,是硬件电路的集成度越来越高,硬件设计的工作量在整个项目中所占的比重逐渐下降。为使应硬件电路设计尽可能合理,应注意以下几个方面:
(1)尽可能采用功能强的芯片,以简化电路,功能强的芯片可以代替若干普通芯片,随着生产工艺的提高,新型芯片的价格不断下降,并不一定比若干普通芯片的价格总和高。
(2)留有设计余地。在设计硬件电路时,要考虑到将来修改扩展的方便。因为很少有一锤定音的电路设计,如果现在不留余地,将来可能要为一点小小修改或扩展而被迫进行全面返工。
(3)程序空间,选用片内程序空间足够大的单片机,本设计采用ATC51单片机。
(4)RAM空间,ATC51内部RAM不多,当要增强软件数据处理功能时,往往觉得不足。如果系统配置了外部RAM,则建议多留一些空间。随着软件设计水平的提高,往往只要改变或增加软件中的数据处理算法,就可以是系统功能提高很多,而系统的硬件不必做任何更换就使系统升级换代。只要在硬件电路设计初期考虑到这一点,就应该为系统将来升级足够的RAM空间,哪怕多设计一个RAM得插座,暂不插芯片也好。
(5)I/O端口;在样机研制出来进行现场使用时,往往会发现一些被忽视的问题,而这些问题不是靠单纯的软件措施来解决的。如有些新的信号需要采集,就必须增加输入检测端:有些物理量需要控制,就必须增加输出端。如果在硬件电路设计就预留出一些I/O端口,虽然当时空着没用,但是需要用的时候就派上用场了。
最小系统
最小系统就是单片机在发挥具体测控功能时所必须的组成部分。如下图六所示为最小系统方框图:
复位电路的设计
单片机的第九脚RES为硬件复位端,只要将该端持续4个机器周期的高电平即可实现复位,复位后单片机的各状态都恢复到初始化状态,其电路图如下图:
图中由按键K以及电解电容C3构成了复位电路。由于单片机是高电平复位,所以当按下K时,单片机的9脚RESET管脚处于高电平,此时单片机处于复位状态。当上电后,由于电容缓慢充电,单片机的9脚电压逐步由高向低转化,经过一段时间后,单片机的9脚处于稳定的低电平状态,此时单片机上复位完毕,系统程序从0000H开始执行。
值得注意的是,在设计当中使用到了硬件复位和软件复位两种功能,由上面的硬件复位后的各状态可知寄存器及存储器的值都恢复到了初始值,而前面的功能介绍中提到的倒计时时间的记忆功能。
时钟频率电路的设计
单片机必须在时钟的驱动下才能工作。在单片机内部有一个时钟振荡电路,只要外界一个振荡源就能产生一定的时钟信号送到单片机内部的各个单元,决定单片机的工作速度。时钟电路如下图:
一般选用石英晶体振荡器。此电路在加电大约延迟10ms后振荡器起振,在XTAL2引脚产生幅度为3V左右的正弦波时钟信号,其振荡频率主要由石英晶振的频率确定。电路中两个电容C1、C2的作用有两个:一是帮助振荡器起振;二是对振荡器的频率进行微调。C1、C2的典型值为20pf。
单片机在工作时,有内部振荡器产生或由外直接输入的送至内部控制逻辑单元的时钟信号的周期称为时钟周期。其大小是时钟信号频率的倒数,f表示。图中的时钟频率为12MHz,即f=12MHz,则时钟周期为1/12us。
2.3 LED数码管显示器概述
本设计中采用的是7SEG-MPX2-CC型号双数码管,它是一种半导体发光器件,期基本单元是发光二极管。实物如下图:
数码管的分类
数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按能显示多少个“8”可分为1位,2位,4位等等数码管;按发光二极管单元连接方式分为共阳极和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。共阴极数码管是指将发光二极管的阴茎接到一起形成公共阴极(COM)的数码管。共阴极数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就亮。当某一字段的阳极为低电平时,相应字段就不亮。
显示功能与硬件关系极大,当硬件固定后,如何在不引起操作者误解的前提下提供尽可能丰富的信息,全靠软件来解决。
在这里我们使用的是七段数码管显示,通常在显示上我们采用的方法一般包括两种:一种是静态显示,另一种是动态显示。其中静态显示的特点是显示稳定不闪烁,程序编写简单,但占用端口资源多;动态显示的特点是显示稳定性没静态好,程序编写复杂,但是相对静态显示而言占用端口资源少。在本设计中根据实际情况采用的是动态显示方法。
七段数码管显示电路如下图:
三、软件设计
3.1 Keil C软件
用到了Keil C软件,集成调试环境,集成了编辑器、译码器、调试器,支持软件模拟,支持项目管理功能强大的观察窗口,支持所有的数据类型。树状结构显示,一目了然,支持ASM(汇编)、C语言多模块源程序混合调试,在直接修改、编译、调试源程序,错误指令定位。功能很强大,用于对程序的调试和编辑。其界面如下(见附件):
定时/计数器初值计算
(1)本电路应用TIMER0 MODE 16位计数器的计时中断法。
(2)1秒等于1000000微秒,而每一计时脉冲是1微秒,因此需输入100000个计时脉冲,方可达到1秒的时间。本设计中,设定中断每次溢出时间50ms。
(3)由上式得知,循环20次即可达到1秒定时,即:
N=t/Tcy=0.05s/0.000001=5000
X=65536-5000=15536=3CB0H
(4)由上式得知5000个脉冲,首先需设定TL0=3CH,TH0=0B0H,此时第1次只要输入5000个脉冲输入,就会溢出;第2次至第20次,则需每1000000个计时脉冲,定时1秒。
(5)上电时,显示99,开始倒数计时按下开关实现复位。
3.2 Proteus软件
系统仿真还用到了Proteus软件,可通过仿真显示出所设计系统的功能,对于程序的调试等有很大的帮助。
系统仿真时首先在使用Keil C 译码器,把所写的程序进行编译,同时在仿真器里设置生成HEX文件,编译无错误进行Proteus仿真。等所有的原件都连接完成后可以把Keil C编译生成的无错误文件加载到ATC51中,方法是,右键点中器件然后再用左键点击,出来一个对话框在program file后选择要添加的文件,文件要求必须是HEX文件。然后可以点击运行观察现象,看与自己设置的是否符合,如果不相符再查找错误进行修改,一般的错误都是程序中的,所以要认真的读取程序的每一个部分。
3.3 流程图
四、调试与仿真
系统调试工具keil c51
Keil C51 仿真器是一款利用KEIL C51 的IDE 集成开发环境作为仿真环境的廉价仿真器,是利用SST公司具有IAP功能的单片机SSTC58制作而成,主要是利用了SSTC58的IAP功能,所谓IAP功能是In application program 的英文缩写,是在应用编程的意思,通俗一点讲就是:它可以通过串口将用户的程序下载到单片机中,可以通过串口对单片机进行编程。它之所以具有这种功能,实际上它有两块程序flash区,其中一块flash中运行的程序可以更改另外的一块程序flash区中的程序,正是利用这一特性才用它作成了仿真器,我们把仿真器的监控程序事先烧入SSTC58,监控程序通过SSTC58的串口和PC通讯,当使用KEIL C51的IDE环境仿真时,用户的程序通过串口被监控程序写入flash程序区中,当用户设置断点等操作仿真程序时,flash程序中的用户程序也在相应的更改,从而实现了仿真功能 。
调试的主要方法 :
1. 启动Keil c51
2. 新建一个工程。Project菜单——〉New project ,选择好我们要保存的文件夹后,键入Frist 保存。接着弹出CPU类型选择框,我们选择最常用的ATC51,按确定。
3. 在工程中加入文件。新建一个文件,文件菜单File——〉New,我们再选择:文件菜单File——〉Save As? (另存为)弹出 对话框后,我们文件名框中键入First.c(注意文件后缀名是 .c)保存。C文件建好啦。现在我们把文件加入到工程中去。 点击Target 1前面的+号,右键单击Source Group 1——〉选择Add Files to Group ,Source Group 1,选择添加 Add。编译运行,检查程序是否有错误。
2. PROTEUS
Proteus是一款EDA软件,该软件具有模拟电路仿真,数字电路仿真,单片机以及外围电路组成的系统的仿真,RS-232动态仿真,I2C调试器,SPI调试器,键盘和LCD系统的仿真,以及各种虚拟仪器,如示波器,逻辑分析仪,信号发生器等。该软件目前支持的单片机类型有:68000系列、8051系列、AVR系列、PIC12系列、PIC16系列、PIC18系列、Z80系列、HC11系列、ARM以及各种外围芯片。该软件还支持大量的存储器和外围芯片,所以,该软件是一款集单片机和SPICE分析于一身的仿真软件。
调试方法:首先用Keil软件将C编译成HEX文件,打开Keil软件,新建一个文档,输入C程序,保存成C格式文件,然后新建工程,连接单片机为ATC51,选择Options for target,选择OUTPUT子菜单,在Create HEX Fi前打钩,DeBug子菜单中,Settings选择ProteusVSM Simulator,USE前打钩,再次运行文件,成功后在目录下会生成HEX文件,打开Proteus软件,或直接点击DSN文件,双击单片机模板,点击文件夹式样的图标选择对应的HEX驱动文件,然后点击开始,进行调试
根据原理图焊接电路。焊接完后检查电路是否正确、是否有虚焊,确定无误后接到5伏的稳压电源,倒计时开始。
五、心得体会
单片机课程是我们专业一个很重要的课程,因为单片机方面的很多知识都应用在机电一体化中。现代人类生活中所用的几乎每件电子和机械产品中都会集成有单片机。了解到单片机的重要性,一开始我就决定了一定要好好学这门课。
刚开始接触单片机是很陌生的,当学到C51单片机的结构及原理这一章的时候,感觉书本里面的内容抽象且难以理解,心里面本能地就有一股抵制情绪在作怪。但是一想到单片机是如此的重要又不得不逼着自己去学去记。学到指令系统这部分内容的时候,里面的很多指令往往让自己感到厌烦,面对一些冗长的C语言程序,往往不用看到最后就已经失去兴趣了。感觉自己学习单片机的过程其实就是一个对陌生领域的本能的抵制而又渴望征服的过程!
我意识到单片机的重要性也从心里面想过要学好这门课程,在学习的过程中我尽力的克服了由本能产生的对抽象知识的抵制情绪,上课认真听讲,做好笔记,最后总算对单片机有一个比较全面的了解。特别是在实验的实践过程中,我发现要学好单片机不仅仅要认认真真学习书本上的理论知识,更要学得透彻,还要实际操作单片机。理论联系实际,这样的学习才不会变得更加生动,更容易调动学习积极主动性。
虽然单片机这门课程已经结课了,但是老师传授给我的知识将使我终身受益!短短几十个学时的学习,老师作为领路者把我带入了单片机这一奇妙的领域。让我感受到了单片机的强大,实用与前景。我表示要把这门课程的结束当做是另外一个征程的开始,单片机的学习可以用这么一句话形容——路漫漫其修远兮,吾将上下而求索。
七、参考文献
[1]梅丽凤.《单片机原理及接口技术》 清华大学出版社。
[2]吴金荣.《8051单片机实践与应用》 清华大学出版社。
[3] 张迎辉 贡雪梅.《单片机实训教程》 北京大学出版社。
[4] 解广润.电力系统接地技术.北京:水利电力出版社.2002.
[5] 李朝清.单片机原理及口技术.北京航空航天大学出版社.2005.
[6] 高卫东.51单片机原理与实践. 北京航空航天大学出版社.2008.
[7] 江志红. 51单片机技术与应用系统开发.青华大学出版社.2008.
[8] 王守中. 51单片机应用开发速查手册.人民邮电出版社.2009.
[9] 徐建民.汇编语言程序设计.电子工业出版社.2007.
附件
系统原理图
图中U1为单片机ATC51,C1,C2为22pf的电容C3为10pf的电解电容,X1为12MHz的晶体振荡器。
Keil C
元件清单
序列 | 名称 | 型号规格 | 数量 |
1 | 单片机 | ATC51芯片 | 一块 |
2 | 七段数码管 | 7SEG-MPX8-CC-BLUE | 两个 |
3 | 石英晶体振荡器 | 12MHz | 一个 |
4 | 电容 | 30pf | 一个 |
5 | 电解电容 | 10pf | 一个 |
6 | 电阻 | 1千欧 | 一个 |
#include #define uchar unsigned char uchar j,k,i,a,A1,A2,second=100; sbit dula=P2^6; sbit wela=P2^7; uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; void delay(uchar i) { for(j=i;j>0;j--) for(k=198;k>0;k--); } void display(uchar sh_c,uchar g_c) { P2=0x01; P0=table[sh_c]; delay(5); P2=0x02; P0=table[g_c]; delay(5); } void main() { while(1) { if(second==1) second=100; second--; A1=second%10; A2=second/10; for(a=510;a>0;a--) { display(A1,A2); } } }