课程设计(论文)以AT89S51单片机为核心的数字电子钟控制器_第1页
课程设计(论文)以AT89S51单片机为核心的数字电子钟控制器_第2页
课程设计(论文)以AT89S51单片机为核心的数字电子钟控制器_第3页
课程设计(论文)以AT89S51单片机为核心的数字电子钟控制器_第4页
课程设计(论文)以AT89S51单片机为核心的数字电子钟控制器_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、一、设计题目:设计一个以at89s51单片机为核心的数字电子钟控制器,实现电子钟的时间、日期交替显示、闹钟功能,并可通过按钮开关或键盘切换显示内容、调整参数、设置闹钟,在单片机实验板上模拟调试实现控制器的功能。二、设计目的:通过单片机应用产品的设计与调试过程,巩固课程所学理论知识,初步了解单片机应用系统设计与调试的方法。三、设计要求:1开机自检,检查相关接口及数码管显示器、指示灯、蜂鸣器等外设是否正常。28位数码管显示器平常以一定的时间间隔、合适的格式显示时间和日期信息,时间显示时、分、秒;日期显示年(20002099)、月、日;设置闹钟功能时显示时、分、开/关状态。3可通过按键设定时间、日期

2、、闹钟等参数、手动切换显示。按键可用独立式按键或行列式键盘实现。设定参数过程有合适的方式指示当前可修改的内容。4对开关量输入进行软件消抖动处理,参数的设定有容错处理,如:小时不能超过23,日期中每月最大天数、闰年等。5用protel设计可实现上述功能的控制器的原理图(最小应用系统)。四、总体方案设计及说明:本设计电子时钟系统,主控芯片采用at89s51芯片。配合软件延时实现时、分、秒的计时。本系统设计采用此种软件控制方法来实现计时,通过定时器定时中断,使时间缓存单元数据加一,提供系统时间。同时可以通过独立键盘对电子时钟开始计时,暂停计时和结束计时的控制。单片机内的数据通过并行i/o接口输入输出

3、。并驱动八位led数码管(时、分、秒分别用2位数码管显示),动态显示数据。晶振及复位电路为单片机提供工作脉冲及复位信号。 五、系统资源分配说明:接口电路逻辑图:使用定时计数器0,tmod设置为0x01;晶振频率11.0592mhz下,定时50ms的计数初值经过计算为4c00h(216-46080=4c00h),th0设置为0x4c,tl0设置为0x00。五、软件流程图及说明:1.闹钟显示开 始闹钟是否打开后6位数码管分别显示“-”、小时的2位、“-”分钟的2位前2位数码管显示op前2位数码管显示cl是否按键扫描,判断有没有按键,若有按键则退出闹钟显示退 出闹钟显示子程序,8个数码管显示已经设置

4、好的闹钟时间,进行按键扫描,判断有没有按键,若有就去执行相应的功能,日期显示子程序和时间显示子程序和闹钟显示子程序类似。2.键盘子程序按键扫描: 功能扫描:开 始设置pc3pc0为输入,pc7pc4为输出,所有行(pc7pc4)置0,读取列值设置pc3pc0为输出,pc7pc4为输入,所有列(pc3pc0)置0,读取行值keyin=keyin_j|keyin_i;形成行列组合结 束开 始设置pc3pc0为输入,pc7pc4为输出,所有行(pc7pc4)置0,读取键盘无键按下,返回0 有键按下,返回1结 束3.中断子程序开 始设置定时50ms的初值为4c00h中断20次,秒单元加160秒到?秒单

5、元清零,分单元加160分钟到?分单元清零,时单元加124小时到?时单元清零,日单元加11个月到?日单元清零,月单元加11年到?月单元清零,年单元加1将小时(time.hour)除以10,商赋给77h(动态显示对应的小时十位),余数赋给78h(动态显示对应的小时个位)将分钟(time.minute)除以10,商赋给7ah(动态显示对应的小时十位),余数赋给7bh(动态显示对应的小时个位)将秒(time.second)除以10,商赋给7dh(动态显示对应的小时十位),余数赋给7eh(动态显示对应的小时个位)int0输入低电平,打开闹钟结 束六、系统功能与操作说明:数字时钟能显示实时时间(hh-mm

6、-ss)、日期(20yy.mm.dd)于led数码管,并可以修改时间、日期。可以设置闹钟,时间到时,蜂鸣器会响起。按切换键可以在时间、日期、闹钟时间中切换。时间、日期、闹钟时间可调,按外部中断键时间暂停,进入时间、日期、闹钟时间设置,此时可以矩阵键盘输入时间日期,输入完后确认键时间按照设置的值接着走。键盘用行列式键盘,按键定义如下图所示。主要的按键有:(1)数字键“0”“9”,用于设置时输入时间和日期,正常工作时无效。(2)“时间设置”、“日期设置”、“闹钟设置”,用于进入相应功能的设置状态。(3)“闹钟开关”在闹钟设置状态时,用于设置闹钟开或关,正常工作时,用于手动关闹铃的声音。(4)“确认

7、”用于设置参数的确认,并检查参数是否合理,如果符合要求,则参数有效;否则本次修改无效,保持原值。正常工作情况下按该键无操作。(5)“显示切换”用于正常工作时手动切换时间、日期的显示。七、调试记录:1、确定课程设计课题为数字电子钟,并查找相关资料。2、熟悉实验板数码管、两个8255、键盘、led等硬件资源的使用,弄清楚其对应的地址。3、调试出可以扫描矩阵键盘输入的数的程序,并在数码管上显示出来当前按下的键值。4、调试出可以显示时分秒和日期的时钟程序,并可以通过4个按键进行控制(分别为进入退出时间设置、时增1、分增1、秒增1),并可以切换时间和日期。5、调试闹钟的显示和设置程序,时间到了所设置的时

8、间时蜂鸣器响起。6、时间可以走,但只能通过在程序中给对应时间日期字节地址预先设置初始值,时钟根据该初始时间接着走,不能通过矩阵键盘输入时间日期。最后查阅资料并询问同学终于解决了这个问题。7、对整个程序做进一步优化处理,使其更稳定,修改其中的一些瑕疵,加上注释,方便以后读程序。八、实验设计总结:通过努力终于设计出一个以at89s51单片机为核心的数字电子钟控制器,实现电子钟的时间、日期交替显示、闹钟功能,并可通过按钮开关或键盘切换显示内容、调整参数、设置闹钟。 这次实验我收获了许多,得到了许多书本上学不到的知识。1、单片机的软件设计通常要考虑以下几个方面的问题:(1)根据软件功能要求,将系统软件

9、划分为若干个相对独立的部分,设计出合理的总体结构,使软件开发清晰、简洁和流程合理;(2)培养良好的编程风格,如考虑结构化程序设计、实行模块化、子程序化。既便于调试、链接,又便于移植和修改;(3)绘制程序流程图,再根据流程图写程序;(4)合理分配系统资源;(5)为程序加入注释,提高可读性,便于以后修改移植复用;2、关于程序的调试问题:(1)软件程序的调试应先分模块调试,统调是最后一环。通过各个模块程序的调试,使程序逐渐趋于完整、正确,最后将各个模块组合起来,统调程序。(2)充分利用实验板上的其他空余硬件资源来协助调试程序,比如,可以用cpl p1.x 来设置指示灯,用来指示有没有调用键盘扫描子程

10、序、用来指示有没有扫描到键值、用来指示外部中断、定时器0和定时器1有没有工作等等。附录:#include #include #define pa xbyte0x0fefc#define pb xbyte0x0fefd#define pc xbyte0x0fefe#define ctl xbyte0x0feff#define uchar unsigned charuchar ms20;sbit sound=p32;uchar open1=-1;/闹钟关闭code led19=0x0c0,0x0f9,0x0a4,0x0b0,0x99,0x92,0x82,0x0f8,0x80,0x90,0x88,0

11、x83,0x0c6,0x0a1,0x86,0x8e,0x0bf,0x8c,0x0c7;code table16=0x7e,0x0ee,0x0ed,0x0eb,0x0de,0x0dd,0x0db,0x0be,0x0bd,0x0bb,0x0e7,0x0d7,0x0b7,0x77,0x7b,0x7d; struct uchar hour; uchar minute; uchar second; uchar hour1;/闹钟小时 uchar minute1;/闹钟分钟 int year; uchar month; uchar day;time=23,59,55,00,00,2011,11,11;vo

12、id delay() uchar i; for(i=0;i200;i+); /*200个时钟周期*/ void scan(uchar x) uchar i,tb,tc=0x80; for(i=0;i=1; /*右移一位*/ delay(); int fastfound()uchar keyin; ctl=0x81; /pc3pc0为输入,pc7pc4为输出pc=0x0f; /所有行(pc7pc4)置0 keyin=pc; /读取键盘 if(keyin=0x0f) return 0;/无键按下,返回0 else return 1; /有键按下,返回1int keyfound() uchar ke

13、yvalue,keyin_i,keyin_j,keyin; uchar i; ctl=0x81;/pc3pc0为输入,pc7pc4为输出 pc=0x0f; keyin_j=pc;/读取列值 ctl=0x88;/pc3pc0为输出,pc7pc4(所有行)为输入 pc=0x0f0; keyin_i=pc;/读取行值 keyin=keyin_j|keyin_i; /形成行列组合 for(i=0;i16;i+) if(tablei=keyin) keyvalue=i; break; return keyvalue;void showclock() /显示闹钟 int a; uchar key=1; w

14、hile(key=1) key=fastfound();/消除按功能键时产生的影响 for(a=0;a800;a+) if(open1=1) dbyte0x57=0; dbyte0x58=17;/显示p,与前一个单元组合成op,表示闹钟已经打开 else dbyte0x57=0x0c; dbyte0x58=18;/显示l,与前一个单元组合成cl,表示闹钟已经关闭 dbyte0x59=0x10; dbyte0x5a=time.hour1/10; dbyte0x5b=time.hour1%10; dbyte0x5c=0x10; dbyte0x5d=time.minute1/10; dbyte0x5

15、e=time.minute1%10; scan(0x57);if(fastfound()=1) key=keyfound(); if(key=0x0a) break; void rq() /显示日期int a; uchar key=1; while(key=1) key=fastfound();/消除按功能键时产生的影响 for(a=0;a800;a+) dbyte0x47=time.year/1000; dbyte0x48=time.year%1000/100; dbyte0x49=time.year%100/10; dbyte0x4a=time.year%10; dbyte0x4b=tim

16、e.month/10; dbyte0x4c=time.month%10; dbyte0x4d=time.day/10; dbyte0x4e=time.day%10;x scan(0x47); if(fastfound()=1)/有键按下 key=keyfound();/获得键值 if(key=0x0a) /如果又按了显示切换键,则显示闹钟时间 showclock(); break; uchar isleap(int x) /判断闰年if(x%4=0 & x%100!=0) | (x%400=0) return 1; else return 0;void datechange() while(1

17、) if(time.month=1 & time.day31) time.day+;break; if(time.month=1 & time.day=31) time.month+;time.day=1;break; if(isleap(time.year) /是闰年 if(time.month=2 & time.day29) time.day+;break; if(time.month=2 & time.day=29) time.month+;time.day=1;break; else /不是闰年 if(time.month=2 & time.day28) time.day+;break

18、; if(time.month=2 & time.day=28) time.month+;time.day=1;break; if(time.month=3 & time.day31) time.day+;break; if(time.month=3 & time.day=31) time.month+;time.day=1;break; if(time.month=4 & time.day30) time.day+;break; if(time.month=4 & time.day=30) time.month+;time.day=1;break; if(time.month=5 & tim

19、e.day31) time.day+;break; if(time.month=5 & time.day=31) time.month+;time.day=1;break; if(time.month=6 & time.day30) time.day+;break; if(time.month=6 & time.day=30) time.month+;time.day=1;break; if(time.month=7 & time.day31) time.day+;break; if(time.month=7 & time.day=31) time.month+;time.day=1;brea

20、k; if(time.month=8 & time.day31) time.day+;break; if(time.month=8 & time.day=31) time.month+;time.day=1;break; if(time.month=9 & time.day30) time.day+;break; if(time.month=9 & time.day=30) time.month+;time.day=1;break; if(time.month=10 & time.day31) time.day+;break; if(time.month=10 & time.day=31) t

21、ime.month+;time.day=1;break; if(time.month=11 & time.day30) time.day+;break; if(time.month=11 & time.day=30) time.month+;time.day=1;break; if(time.month=12 & time.day31) time.day+;break; if(time.month=12 & time.day=31) time.month=1;if(time.year!=2099) time.year+;break; uchar checkall(uchar x)uchar i

22、,h,m,s,month,d; int y; if(x=0x0c)/对闹钟设置进行判断 for(i=3;i24 | (h=24 & (h!=0 | s!=0) return 0; if(m=60) return 0; return 1;/按键合法返回1 if(x=0x0f)/对时间设置进行判断 for(i=0;i24 | (h=24 & (h!=0 | s!=0) return 0; if(m=60) return 0; if(s=60) return 0; return 1;/按键合法返回1 if(x=0x0e)/对日期设置进行判断 for(i=0;i8;i+) if(dbyte0x57+i

23、=0x10) return 0;/如果按键不是数字,结束 y=dbyte0x57*1000+dbyte0x58*100+dbyte0x59*10+dbyte0x5a; month=dbyte0x5b*10+dbyte0x5c; d=dbyte0x5d*10+dbyte0x5e; if(y2099) return 0; if(month=0 | month12) return 0; if(d=0 | d31) return 0;if(month=1 & d31) return 0; if(month=3 & d31) return 0; if(month=4 & d30) return 0; i

24、f(month=5 & d31) return 0; if(month=6 & d30) return 0; if(month=7 & d31) return 0; if(month=8 & d31) return 0; if(month=9 & d30) return 0; if(month=10 & d31) return 0; if(month=11 & d30) return 0; if(month=12 & d31) return 0; if(isleap(y) /是闰年 if(month=2 & d29) return 0; else /不是闰年 if(month=2 & d28)

25、 return 0; return 1; void setclock() uchar i,j,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能键时产生的影响 dbyte0x57=0x10; dbyte0x58=0x10; dbyte0x59=0x10; dbyte0x5a=0; dbyte0x5b=0; dbyte0x5c=0x10;dbyte0x5d=0; dbyte0x5e=0; for (i=0;i2;i+) for(j=0;j2;j+) while(k) key=fastfound(); if(key=1) keyi

26、n=keyfound();k=0;/*如果有键按下,则退出while;否则,等待按键*/ scan(0x57);/显示按键 if(keyin9 ) keyin=0x10;/如果按键的值非法,置为- dbyte0x5a+i*3+j=keyin; while(key=1) key=fastfound();/*判断按键以后,手是否已放开;如果没放开,等待*/ k=1; /用于进入下一次按键状态 dbyte0x5a+i*3+j=0x10; /设置该单元显示- while(1) /设置时间完成后,判断是否按了确认键 key=fastfound(); scan(0x57); if(key=1) keyin

27、=keyfound(); if(keyin=0x0d)/*判断按键是否为确认键,如果是,则进行按键的判断;如果不是,则等待*/ if(checkall(0x0c)=0) break;/如果按键非法,退出,保持原来的值 time.hour1=dbyte0x5a*10+dbyte0x5b; time.minute1=dbyte0x5d*10+dbyte0x5e; break; void setdate() uchar i,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能键时产生的影响 dbyte0x57=time.year/10

28、00; dbyte0x58=time.year%1000/100; dbyte0x59=time.year%100/10; dbyte0x5a=time.year%10; dbyte0x5b=time.month/10; dbyte0x5c=time.month%10; dbyte0x5d=time.day/10; dbyte0x5e=time.day%10; for (i=0;i8;i+) while(k) key=fastfound(); if(key=1) keyin=keyfound();k=0;/如果有键按下,则退出while;否则,等待按键 scan(0x57);/显示按键 if(

29、keyin9 ) keyin=0x10;/如果按键的值非法,置为- dbyte0x57+i=keyin; while(key=1) key=fastfound();/*判断按键以后,手是否已放开;如果没放开,等待*/ k=1; /用于进入下一次按键状态 while(1) /设置时间完成后,判断是否按了确认键 key=fastfound(); scan(0x57); if(key=1) keyin=keyfound(); if(keyin=0x0d)/*判断按键是否为确认键,如果是,则进行按键的判断;如果不是,则等待*/ if(checkall(0x0e)=0) break;/如果按键非法,退出

30、,保持原来的值 time.year=dbyte0x57*1000+dbyte0x58*100+dbyte0x59*10+dbyte0x5a; time.month=dbyte0x5b*10+dbyte0x5c; time.day=dbyte0x5d*10+dbyte0x5e; break; void settime() uchar i,j,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能键时产生的影响 dbyte0x57=0; dbyte0x58=0; dbyte0x59=0x10; dbyte0x5a=0; dbyte0x

31、5b=0; dbyte0x5c=0x10; dbyte0x5d=0; dbyte0x5e=0; for (i=0;i3;i+) for(j=0;j2;j+) while(k) key=fastfound(); if(key=1) keyin=keyfound();k=0;/*如果有键按下,则退出while;否则,等待按键*/ scan(0x57);/显示按键 if(keyin9 ) keyin=0x10;/如果按键的值非法,置为- dbyte0x57+i*3+j=keyin; while(key=1) key=fastfound();/*判断按键以后,手是否已放开;如果没放开,等待*/ k=1

32、; /用于进入下一次按键状态 dbyte0x57+i*3+j=0x10; /设置该单元显示- while(1) /设置时间完成后,判断是否按了确认键 key=fastfound(); scan(0x57); if(key=1) keyin=keyfound(); if(keyin=0x0d)/*判断按键是否为确认键,如果是,则进行按键的判断;如果不是,则等待*/ if(checkall(0x0f)=0) break;/如果按键非法,退出,保持原来的值 time.hour=dbyte0x57*10+dbyte0x58; time.minute=dbyte0x5a*10+dbyte0x5b; ti

33、me.second=dbyte0x5d*10+dbyte0x5e; break; void timechange() interrupt 1 /秒加1int i; th0=0x4c; /晶振频率11.0592mhz下,定时50ms的计数初值 tl0=0x00; /216-46080=4c00hms20+; if( ms20=20) time.second+; ms20=0;if(time.second=60)time.minute+;time.second=0; if(time.minute=60)time.hour+;time. minute =0; if(time.hour=24)time.hour=0;datechange(); dbyte0x77=time.hour/10; dbyte0x78=time.hour%10; dbyte0x79=0x10; dbyte0x7a

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论