基于51单片机的数字秒表课程设计.doc
电气与自动化工程学院卓越工程师培养计划暑期实训报告题 目 秒表系统的设计 年 级 11级 专 业 自动化 班 级 卓越班 学 号 160111126 姓 名 俞雷 地 点 大学生创新实验室 日 期 2012年8月12日2012年8月20日目录一、单片机简介- 2 -二、设计目标- 3 -1、设计目的:- 3 -2、具体操作:- 3 -三、硬件设计- 4 -原理图: - 4 -四、系统的软件设计- 5 -1、软件整体设计思路:- 5 -2、软件流程图:- 5 -3、程序:- 6 -(1)数码管秒表显示程序:- 6 -(2)1602液晶秒表显示程序:- 13 -五、系统的调试及设计结果- 18 -1602液晶秒表显示效果图:- 18 -LED数码管秒表显示效果图:- 18 -六、创新实验室课程设计小结- 19 -一、单片机简介单片机以其高可靠性、高性价比、低电压、低功耗等一系列优点,近几年得到迅猛发展和大范围推广,广泛应用于工业控制系统,数据采集系统、智能化仪器仪表,及通讯设备、日常消费类产品、玩具等。并且已经深入到工业生产的各个环节以及人民生活的各层次中,如车间流水线控制、自动化系统等、智能型家用电器(冰箱、空调、彩电)等。管脚图如图1.1所示。图1.1 AT89C52单片机引脚图(1) 电源地组Vcc和Vss;VCC(40)脚接+5V电压;VSS(20)脚接地(2) 时钟电路组XTAL1和XTAL2(3) 控制信号组RST/ALE/PSEN和EA(4) I/O端口P0, P1, P2和P3二、设计目标1、设计目的:1.利用单片机定时器中断实现秒表计时功能。2.方案一:通过LED显示程序的调整,熟悉LED动态显示的控制过程。 方案二: 通过对1602设置,熟悉1602液晶显示的控制过程。3.通过键盘程序的调整,熟悉矩阵式键盘的控制,熟悉键盘扫描原理。4.通过阅读和调试简易秒表整体程序,学会如何编制含LED动态显示、1602液晶的显示、键盘扫描和定时器中断等多种功能的综合程序。2、具体操作:方案一:用AT89C51设计一个6位的数码管显示作为“秒表”,显示时间范围为0.00655.36秒(此处可以通过设置两个变量进行进位操作来达到最大计数9999.99秒),计时精度达到0.01秒。利用其定时器的原理,数码管以及定时器中断来设计计时器。将软硬件结合起来,使得系统能实现0.00655.36秒的计时。另外,通过独立按键的设计来对秒表进行控制。key1键控制计时的开始与暂停、key2键控制计时时的保存数据然后可以通过key4键控制数据的输出(可以保存十个,保存十个时秒表可以停止,该功能可用于赛跑中的计时)、key3键控制“清零”和保存按下清零键前的最后一次所计时间。(特别声明:每次处于“暂停状态”的时间都可以在此基础之上进行计时)。方案二:用AT89C51设计一个1602液晶显示的“秒表”,显示时间范围为0.00655.36秒(此处可以通过设置两个变量进行进位操作来达到最大计数9999.99秒),计时精度达到0.01秒。利用其定时器的原理,1602液晶以及定时器中断来设计计时器。将软硬件结合起来,使得系统能实现0.00655.36秒的计时。另外,通过独立按键的设计来对秒表进行控制。key1键控制计时的开始与暂停、key3键控制“清零”和保存按下清零键前的最后一次所计时间。(特别声明:每次处于“暂停状态”的时间都可以在此基础之上进行计时)。注:由于开发板的键盘对液晶显示有影响,顾放弃数码管秒表显示中的部分功能。三、硬件设计原理图:(程序可用于在下图在软件中仿真也可以用于开发板)四、系统的软件设计1、软件整体设计思路:将程序模块化与功能,含有多个子程序的调用与嵌套。通过对按键的是否按下来对秒表进行操作,按键功能在设计目标的具体操作中已经展现。10毫秒秒定时采用定时器T0中断的工作方式1进行,中断及计数的开启与关闭受控于按键处理程序。2、软件流程图:按键key1按键key3按键key4按键key2计时开始与暂停显示key2保存的时间清零并保留清零时的时间按一次保存一个时间如图所示。(注:用1602液晶的方案中无key2与key4)上电程序开始初始化函数选择按键3、程序:(1)数码管秒表显示程序:/* 数码管显示秒表计时*/* 头文件 宏定义 定义*/#include<reg52.h> #define uint unsigned int #define uchar unsigned charuint t,tt;uint table10;uchar yi,er,san,si,wu,liu,i,j,k,l,m,flag;uchar code table0=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00;uchar code table1=0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef;uchar code table2=0xfe,0xfd,0xfb,0xf7,0xef,0xdf;/* 位定义*/sbit dula=P26;sbit wela=P27;sbit key1=P34; /开始与暂停sbit key2=P35; /保存10次时间sbit key3=P36; / 清零与恢复sbit key4=P37; /读取保存的数据/* 函数的申明*/void init();void display(flag);void display1();void keyscan1();void keyscan2();void shu(uint t);void delay(uchar d);/* 主函数*/void main()init();while(1)display1();keyscan2();/* 初始化函数*/void init()m=1;TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;TR0=0;shu(t);/* 总显示函数*/void display(flag) while(flag)display1();keyscan1();/* 数据显示函数*/void display1()P0=table0liu;dula=1;dula=0;P0=0xff;P0=table20;wela=1;wela=0;delay(5);P0=table0wu;dula=1;dula=0;P0=0xff;P0=table21;wela=1;wela=0;delay(5);P0=table0si;dula=1;dula=0;P0=0xff;P0=table22;wela=1;wela=0;delay(5);P0=table1san;dula=1;dula=0;P0=0xff;P0=table23;wela=1;wela=0;delay(3);P0=table0er;dula=1;dula=0;P0=0xff;P0=table24;wela=1;wela=0;delay(3);P0=table0yi;dula=1;dula=0;P0=0xff;P0=table25;wela=1;wela=0;delay(3);/*动态显示数字循环中的键盘检测*/void keyscan1() if(key1=0)delay(10);if(key1=0) flag+;while(!key1);delay(10);while(!key1);if(flag%2) /判断 是否暂停TR0=1;elseTR0=0;if(key2=0)delay(10);if(key2=0)if(j=10)j=0;flag+;elsetablej=t;j+;while(!key2);delay(10);while(!key2);if(key3=0)delay(10);if(key3=0)l+;if(l%2) /判断 是否清零还是恢复tt=t;t=0;shu(t);elset=tt;shu(tt);display1();while(!key3);delay(10);while(!key3);if(key4=0)delay(10);if(key4=0)if(k=10)k=0;t=tablek;shu(t);display1();k+;while(!key4);delay(10);while(!key4);/*主程序中 计时暂停时的键盘检测*/void keyscan2() if(key1=0)delay(10);if(key1=0) flag+;while(!key1);delay(10);while(!key1);if(flag%2)TR0=1;elseTR0=0; display(flag%2);if(key4=0)delay(10);if(key4=0)if(k=10)k=0;t=tablek;shu(t);display1();k+;while(!key4);delay(10);while(!key4);/*数字的拆分*/void shu(uint t) liu=t/100000;wu=t/10000%10;si=t/1000%10;san=t/100%10;er=t/10%10;yi=t%10;if(liu=0)liu=10;if(wu=0)wu=10;if(si=0)si=10;/*延时函数*/void delay(uchar d) unsigned char a,b,c; for(c=d;c>0;c-) for(b=120;b>0;b-) for(a=2;a>0;a-);/*定时器0工作方式1 10毫秒计时*/void time0() interrupt 1 /计时10毫秒TH0=(65536-10000)/256;TL0=(65536-10000)%256;t+;shu(t);if(t%1000=170)if(m%2)P1=0xaa;m+;elseP1=0x55;(2)1602液晶秒表显示程序:/* 1602液晶显示秒表计时*/* 头文件 宏定义 定义*/#include<reg52.h>#define uint unsigned int#define uchar unsigned charuint t,tt;uchar flag,yi,er,san,si,wu,liu,l,m,num;uchar code table="0123456789 "uchar code table1=" *STOPWATCH*"/* 位定义*/sbit dula=P26;sbit wela=P27;sbit LCDE=P34;sbit rs= P35;sbit key1=P36;sbit key3=P37;/* 函数的申明*/void init();void write_com(uchar com);void write_da(uchar da);void shu(uint t);void keyscan1();void display();void display1();void delay(uchar z);/* 主函数*/void main() init();while(1)keyscan1();display1();/* 初始化函数*/void init() dula=1;P0=0x00;dula=0;wela=1;P0=0xff;wela=0;LCDE=0;write_com(0x01);write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x80);for(num=0;num<16;num+)write_da(table1num);delay(3);write_com(0x80+0x45);delay(5);shu(t);display1();TMOD=0x01;TH0=(65536-10000)/256;TL0=(65536-10000)%256;EA=1;ET0=1;/* 写指令*/void write_com(uchar com) P0=com;rs=0;LCDE=0;delay(5);LCDE=1;delay(5);LCDE=0;/* 写数据*/void write_da(uchar da) P0=da;rs=1;LCDE=0;delay(5);LCDE=1;delay(5);LCDE=0;/* 数的拆分*/void shu(uint t) liu=t/100000;wu=t/10000%10;si=t/1000%10;san=t/100%10;er=t/10%10;yi=t%10;if(liu=0)liu=10;if(wu=0)wu=10;if(si=0)si=10;/*动态显示数字循环中的键盘检测*/void keyscan1() if(key1=0)delay(10);if(key1=0) flag+;while(!key1);delay(10);while(!key1);if(flag%2) TR0=1;elseTR0=0;if(key3=0)delay(10);if(key3=0)l+;if(l%2) tt=t;t=0;shu(t);elset=tt;shu(tt);display1();while(!key3);delay(10);while(!key3);/* 总显示函数*/void display() while(flag%2)display1();keyscan1();/* 数据显示函数*/void display1() write_com(0x80+0x45);delay(5);write_da(tableliu);write_da(tablewu);write_da(tablesi);write_da(tablesan);write_da(0x2e);write_da(tableer);write_da(tableyi);/*延时函数*/void delay(uchar z) uchar i;for(z;z>0;z-)for(i=110;i>0;i-);/*定时器0工作方式1 10毫秒计时*/void time0() interrupt 1 TH0=(65536-10000)/256;TL0=(65536-10000)%256;t+;shu(t);if(t%1000=170)if(m%2)P1=0xaa;m+;elseP1=0x55;五、系统的调试及设计结果1602液晶秒表显示效果图:上电状态: 过程中灯亮状态: 四位数显示: LED数码管秒表显示效果图:上电初始状态: 三位数显示: 灯亮状态: 六、创新实验室课程设计小结此次为期九天的实训即将结束了,我对自己在此期间的表现还是比较满意的。还记得刚开始接触51单片机还是在去年,那时对单片机可谓是一窍不通。接触多了之后,渐渐的不再觉得它那么的难懂,自己对单片机也有了点认知。通过对本次的课程设计,也使自己深刻的认识到自己的很多不足之处。第一天,了解了一些关于robocup比赛的知识,同时也了解了我们院刚刚参加robocup比赛的一些情况,结合这些参赛队伍,毛老师讲了一些关于比赛队伍的小车的设计过程以及实现一些功能所需的条件。其中,了解了循迹,避障,超声测距等电路设计。下午了解了一些关于飞思卡尔的一些情况,李鑫老师也给我们介绍了些关于实验室的情况。接下来,毛老师讲了一些关于电子元件的知识,李鑫老师讲了飞思卡尔的比赛规则以及电磁组、摄像头组、光电组的智能车的不同以及其各自组别的特点与所需实现功能的条件。李鑫老师也找同学帮我们把学习51单片机的所需软件装好。接下来几天大家便开始了学习单片机的之路。期间,基本是戴老师给我们讲数码管、按键等一些知识。下面这12点是我在学习单片机之前,特地从网上找的别人学习51单片机的心得:1、万事开头难、要勇敢迈出第一步。2、 知识 点用到才学,不用的暂时丢一边。3、 程序不要光看不写,一定要自己写一次。4、必须学会掌握调试程序的方法。5、找到解决问题思路比找到代码更重要。6、开动脑筋,运用多种方法,不断优化自己的程序。7、看别人的代码,学习人家的思路。8、 尝试编写一下综合 应用 的程序。 9、着重于培养解决问题的能力,而不是具体看 自己编写了多少代码或者做过什么。11、面对一个新项目时,多自己开动脑筋,不要急于找别人的 程序。12、多利用网络的搜索,学会提问题。 通过这些好的方法加上我之前便自学过,所以单片机基本的程序、功能、用法等我还是会的,通过这段时间的学习,很多东西我也弄通了,比以前认识的更加深刻。这是此次实训,对于我来说最大的收获。记得老师将此次课程设计布置下来的那天上午,我就已经用数码管实现了秒表的功能,下午又增添了一些功能,接下来就是有一些想法然后完善程序。第二天,我又尝试了用1602液晶来制作秒表。程序写好后,下载到实验板上看看效果时却没有预计的效果,可以说是完全没有显示,然后一直调程序。就这样过了大半天。其中,我以为液晶有问题,试的第一个示例程序可以显示,后来自己不断调程序,再试一个示例程序时,我发现液晶第一行把7显示为3了,而且第二行不显示,而自己编的程序就是显示第二行,换了块1602液晶后,发现自己的程序还是正确的。在知道那块1602液晶是坏的时候,感觉挺郁闷的,但之前调程序时,自己却也不觉得累,总是想把问题解决了,那种状态的感觉很好。完成了课程设计任务要求后,自己便开始不断完善自己的程序。期间也会为别的同学提供帮助,与他们讨论他们出现错误的原因,解决的问题的方案等,解决这些各种各样的问题便是一种在实践中获取经验的过程,而过程使人成长,那么这个过程很好的帮助自己加深了对单片机的了解与认识。以上这些便是我在这些天的学习之后所要想要说的。这些天的学习也让我体会到带着任务学习让我们学的更快,这也是很好的学习方式。