1、《单片机原理与应用》课程设计 总结报告 题 目:单片机电子时钟(带秒表)设计 设计人员: 张保江 江润洲 学 号: 197213 118029 班 级: 自动化1211 指引教师: 阮海容 目 录 1.题目与重要功能规定……………………………………2 2.整体设计框图及整机概述……………………………
2、…3 3.各硬件单元电路设计、参数分析及原理阐明………3 4.软件流程图和流程阐明…………………………………4 5.总结设计及调试体会…………………………………10 附 录 1.图一:系统电路原理图…………………………………11 2.图二:系统电路 PCB …………………………………12 3.表一:元器件清单………………………………………13 4.时钟程序源码……………………………………………14 题目:单片机电子时钟设计与实现 课程设计目和意义 课程设计目与意义在于让咱们将理论与实践相结合。培养咱们综合运用电子课程中理论知识解决实际性问题能力。让咱们对电
3、子电路、电子元器件、印制电路板等方面知识进一步加深结识,同步在软件编程、排错调试、焊接技术、有关仪器设备使用技能等方面得到较全面锻炼和提高,为此后可以独立完毕某些单片机应用系统开发和设计打下一种坚实基本。 课程设计基本任务 运用89C51单片机最小系统,综合应用单片机定期器、中断、数码显示、键盘输入等知识,设计一款单片机和简朴外设控制电子时钟。 重要功能规定 最基本规定 1)使用MCS-51单片机设计一种时钟。规定具备6位LED显示、3个按键输入。 2)完毕硬件实物制作或使用Pruteus仿真(注意位驱动应能提供足够电流)。 3)6位LED数码管从左到右分别显示时
4、分、秒(各占用2位),采用24小时原则计时制。开始计时时为000000,到235959后又变成000000。 4)使用3个键分别作为小时、分、秒调校键。每按一次键,相应显示值便加1。 分、秒加到59后再按键即变为00;小时加到23后再按键即变为00。在调校时均不向上一单位进位 (例如分加到59后变为00,但小时不发生变化)。 5) 软件设计必要使用MCS-51片内定期器,采用定期中断构造,不得使用软件延时法,也不得使用其她时钟芯片。 6)设计八段数码管显示电路并编写驱动程序,输入并调试拆字程序和数码显示程序。 7)掌握硬件和软件联合调试办法。 8)完毕系统硬件电路设计和制作。 9)
5、完毕系统程序设计。 10)完毕整个系统设计、调试和制作。 11)完毕课程设计报告。 基本规定 1)实现最基本规定1~10某些。 2)键盘输入可以控制电子时钟走时/调试。 3)设计键盘输入电路和程序并调试。 4)掌握键盘和显示配合用法和技巧。 提高发挥某些 1)另设三个键,分别作小时、分、秒减1调校。 2)在以上设计基本上,修改程序制作一种电子秒表。分、秒各占用2位显示,1/10秒、 1/100秒各占用1位显示。设定二个键分别作启动/停止、清零(清零应在停止后有效)。 3)在做完(2)后,将时钟与秒表合二为一,并且在同步使用时互不影响,即可在时钟与秒表之间任意切换,而
6、不影响走时、计秒。 整体设计框图及整机概述 整体设计框图 整机概述 1)开机为走时模式,正常显示时间。在此模式下,时钟可调。 2)共设立7个按键,分别为模式键、功能键、加一键、减一键、复位键、秒表启动键、秒表复位键。按动模式键,模式将在‘走时/调时/显示及秒表显示及调节’2个模式下切换。 3)在时钟模式下,功能键选取是正常走时,还是进入调试(时、分、秒)模式。 4)按动加一键可以将值(时、分、秒)加一。 5)按动减一键可以将值(时、分、秒)减一。 6)按动秒表中开始/暂停按键可以随时控制秒表开始和停止。 7)按动秒表中清零按键时,秒表计数就会被清除(只有在秒表停止了后来
7、 8)按下复位键后,无论是任何状态都会从新开始。 9)开机时钟与闹钟都为00:00:00。 各硬件单元电路设计、参数分析及原理阐明 电源电路 元件有限没有制作电源电路某些。使用9V电池通过7805稳压后进行供电。 按键 参照课本P232键盘接口电路原理图,P3口(除去P3.6)接是键盘按键。当按键按下后,P3口被拉成低电平,给单片机一种信号,使单片机产生一种中断。单片机再指令相应P0口,P2口产生变化。 单片机最小系统 参照实验指引书与课本及网络资料设计按键电平复位。 LED数码管 一方面P0口作为段码输出。由于P0口输出级无上拉电阻,故需
8、添加一排阻为其上拉电阻。另一方面采用共阳极数码管。段码端为低电平时导通LED,此时数码管向89S51芯片P0口灌电流,为防止芯片烧坏,还需加1个1 KΩ限流电阻。考虑到数码管亮度问题,采用了PNP三极管做驱动电路。基极接上1 KΩ电阻后再与P2口相连(P2.0~P2.5)进行位选。发射极接5V电源,集电极接数码管位选。 软件流程图和流程阐明 调用显示子程序 调用始时钟或秒表查询程序 调用按键扫描子程序 调用模式查询子程序 初始化 开始 等待定期器中断 软件流程图 1)主程序流程图 流程图阐明 初始化:涉及定期器赋 初值,初始化各内存单 元。开定期器中
9、断,开 CPU中断。 时间显示及调节子程序与秒表显示及调节子程序流程图与调时模式子程序大同小异。 调时模式设立 秒/分/时数据分别送display函数 Num11? 取键值送cpu Y 分钟数值加1,键值清零 N Num11值为2? N 返回 Y Num11值为3? 小时数值加1,键值清零
10、 总结设计及调试体会 硬件设计某些:一方面要通过计算与参照资料等决定参数。而后通过仿真软件等调试,拟定参数无误后再开始用AD画原理图,进而生成PCB进行布板。在焊板子时候,也浮现了问题,不小心将7805焊成了7905,成果又调试了一种时间。 软件设计某些:设计软件一方面要考虑要做功能,拟定
11、出合理算法。合理算法不但要可以实现功能,并且在添加功能时候要以便灵活。有人为了实现某种功能用了各种各样办法来实现,成果程序构造吃死,当想要添加功能或者修改其她功能时候,将修改程序大某些构造,也就是说要破坏程序既有构造。 关于调试:Keil软件调试单片机程序时候,编译通过并不代表程序是对的。编译通过只能阐明程序没有语法上错误。进行软件仿真或者下载到开发板上进行调试,经常会浮现各种各样错误。许多超过预期效果现象往往是某些微小错误引起。例如没有现场保护跟恢复现场等,因此养成良好编程习惯也很重要。有些想达到某些功能而添加语句,事实上确一点效果也没有。举个编程中小问题:当有按键按下时,咱们都要有软件防
12、抖。正常办法是调用一种延时。在实际调试中,要跳过这个抖动,需要100MS左右。如果使用正常延时,会导致按键按下时CPU100MS内无法进行其她操作,也就是说。平均1S内100MS不调用显示子程序,这样就会导致亮度减少。这时候,考虑到显示子程序一次有十几毫秒,就特别写了一种程序来作为按键防抖延时,事实上效果也是很不错。这个想法就是在修改了多次程序未达到想要效果(有按键按下时显示亮度不减少)后最后想出来办法。 最后在做完板,焊完电路后,在接通电源之前,要用万用表仔细检查电路与否有连接错,以免烧坏芯片和数码管。 设计课设其她体会:态度要积极,不要以为很简朴就不紧不慢。诸多东西并不是自己设想那么顺
13、利,有时候一种小问题可以花上你半天甚至一天时间。虽然自己在程序上并没遇到太大问题,但是由于态度不够积极,对于没画过PCB图迟迟不去下手,在周四晚上才解决。本觉得周五一天可以做完板并完毕整机调试,可是各种突发事件让自己措手不及。发现板来不及做完后才将程序功能进行扩展。这是我在这次实验中一种教训,也让我明白了对于自己不能太过于自信,态度决定一切。 图一:系统电路原理图 图二:系统电路PCB 在protues中调试成果 在开发板上实现效果(见实物) 在焊PCB板子上效果(见实物) 在protues里仿真以及在开发板上
14、实现和自己做实物所看到现象是不同样。在protues里不用接三极管(NPN)就可以实现效果,但是在自己做板子时候就不行了,由于51单片机输出电流不能驱动数码管发光,需要一种增长驱动9014三极管。此外,protues里复位按键不起作用(软件里就是这样设计)。将在PCB上实现程序用在开发板上又浮现了问题,delay(3)这个延时子程序不合理,浮现了闪烁问题,因此将delay(3)改成了delay(1),这样问题就解决了。我是将三极管加在了段选上,又加了限流电流,这样做数码管也能点亮。另一方面,同样程序用在不同显示上,现象也是不同样。因此,我需要不断地修正定期器装值。TH1=(65536-4999
15、7)/256; //重装初值 TL1=(65536-49997)%256; TH0=(65536-8000)/256; TL0=(65536-8000)%256; 通过实际测量,这个数值是最适当,一种小时一秒不差。 表一:元器件清单 器件名称 数量 电池 一种 Lm7805 一种 自锁开关 一种 51单片机 一种 LED 两个 极性电容 一种 非极性电容 两个 晶振 一种 10K电阻 九个 1K电阻 两个 按键 七个 100电阻 八个 PNP三极管 八个 4位数码管(共阴) 两个 时钟程序
16、源码
# include
17、bit clf_key=P3^5; //秒表中清零按键 sbit func_key=P3^1; //时钟换位按键(时、分、秒) sbit add_key=P3^2; //时钟加1按键 sbit sub_key=P3^3; //时钟减1按键 uchar k1_bit=0; //切换按键标志位 uchar shi1,shi2,fen1,fen2,miao1,miao2,fen3,fen4,miao3,miao4,num9,num10;
18、
19、
20、
21、 uint num1,num2,num3,num4,num5,num6,num7,num8,num11; void delay(uint xms) //延时函数 { uint i,j; for(i=xms;i>0;i--) for(j=110;j>0;j--); } void init() //中断初始化函数 { EA=1; //开总中断 TMOD=0X11; //定期器工作方式选取,定期器0和定期器1都选取第1种工作方式 TH0=(655
22、36-10000)/256; //定期器0装初值,定期10ms(用于秒表) TL0=(65536-10000)%256; ET0=1; //开定期器0开关 TR0=0; //开定期器0小开关 TH1=(65536-50000)/256; //定期器1装初值,定期50ms (用于时钟) TL1=(65536-50000)%256; ET1=1; //开定期器1开关 TR1=1; //关定期器1小开关 } void mode_key() //模式选取键,本程序两种模式,分别是时间显示、秒
23、表。当K1_bit为0时显示时钟,为1时进入秒表 { if(qiehuan_key==0) { delay(5); if(qiehuan_key==0) { k1_bit++; if(k1_bit==2) { k1_bit=0; } while(!qiehuan_key); } } } void display1(uchar shi1,uchar shi2,uchar fen1,uchar fen2,uchar miao1,uchar miao2) //
24、显示时钟函数 { shi1=num1/10; shi2=num1%10; fen1=num2/10; fen2=num2%10; miao1=num3/10; miao2=num3%10; P2=0xff; P0=table[shi1]; //第一位 P2=0xfe; delay(3); P2=0xff; P0=table[shi2]; //第二位 P2=0xfd; delay(3); P2=0xff; P0=0x40; // 第三位 P2=0xfb; delay(3); P2=0xff
25、 P0=table[fen1]; //第四位 P2=0xf7; delay(3); P2=0xff; P0=table[fen2]; // 第五位 P2=0xef; delay(3); P2=0xff; P0=0x40; // 第六位 P2=0xdf; delay(3); P2=0xff; P0=table[miao1];//第七位 P2=0xbf; delay(3); P2=0xff; P0=table[miao2];//第八位 P2=0x7f; delay(3); P2=0xff; }
26、 void display0(uchar fen3,uchar fen4,uchar miao3,uchar miao4,uchar num9,uchar num10) //显示秒表函数 { fen3=num8/10; fen4=num8%10; miao3=num7/10; miao4=num7%10; num9=num6; num10=num5; P2=0xff; P0=table[fen3]; //第一位 P2=0xfe; delay(3); P2=0xff; P0=table[fen4]; //第二位 P2=
27、0xfd; delay(3); P2=0xff; P0=0x40; // 第三位 P2=0xfb; delay(3); P2=0xff; P0=table[miao3]; //第四位 P2=0xf7; delay(3); P2=0xff; P0=table[miao4]; // 第五位 P2=0xef; delay(3); P2=0xff; P0=0x40; // 第六位 P2=0xdf; delay(3); P2=0xff; P0=table[num9];//第七位 P2=0
28、xbf; delay(3); P2=0xff; P0=table[num10];//第八位 P2=0x7f; delay(3); P2=0xff; } void key_miaobiao() { if(k1_bit==1) { if(sp_key==0) { delay(5); if(sp_key==0) { TR0=~TR0; while(!sp_key) display0(fen3,fen4,miao3,miao4,num9,num10); } }
29、 if(TR0==0) { led=0; if(clf_key==0) { delay(5); if(clf_key==0) { led=1; while(!clf_key) { num5=num6=num7=num8=0; } } } } } } void keyscan() //时钟按键扫描 { if(func_key==0) { delay(5); if(f
30、unc_key==0) { led=0; num11++; while(!func_key); if(num11==1) { TR1=0; } if(num11==2) { TR1=1; } if(num11==3) { TR1=1; } if(num11==4) { num11=0; TR1=1; } } } if(num11!=0) { if(ad
31、d_key==0) { delay(5); if(add_key==0) { while(!add_key); if(num11==1) { num3++; if(num3==60) num3=0; } if(num11==2) { num2++; if(num2==60) num2=0; } if(num11==3) { num1++; if(num1==24)
32、 num1=0; } } } if(sub_key==0) { delay(5); if(sub_key==0) { while(!sub_key); if(num11==1) { num3--; if(num3==-1) num3=59; } if(num11==2) { num2--; if(num2==-1) num2=59; } if(num11==3) {
33、 num1--; if(num1==-1) num1=23; } } } } } void main() { init(); led=0; while(1) { mode_key(); switch(k1_bit) //模式选取 { case 0: { display1(shi1,shi2,fen1,fen2,miao1,miao2); //显示时间 keyscan(); break; }
34、case 1: { display0(fen3,fen4,miao3,miao4,num9,num10); //显示秒表 key_miaobiao(); //扫描秒表操作 break; } } } } void Time1() interrupt 3 //定期器1函数(时钟) { TH1=(65536-49997)/256; //重装初值 TL1=(65536-49997)%256; num4++; if(num4==20) { num4=0; num3++;
35、if(num3==60) //秒针 { num3=0; num2++; if(num2==60) //分针 { num2=0; num1++; if(num1==24) //时针 num1=0; } } } } void Time0() interrupt 1 //定期器0函数(秒表) { TH0=(65536-8000)/256; //重装初值 TL0=(65536-8000)%256; num5++; if(num5==10) { num5=0; num6++; if(num6==10) { num6=0; num7++; if(num7==60) { num7=0; num8++; if(num8==60) { num8=0; } } } } }






