实时时钟设计实验报告_第1页
实时时钟设计实验报告_第2页
实时时钟设计实验报告_第3页
实时时钟设计实验报告_第4页
实时时钟设计实验报告_第5页
已阅读5页,还剩11页未读 继续免费阅读

下载本文档

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

文档简介

1、实验报告姓 名学 号专业班级课程名称实验日期成 绩实验名称实时时钟设计一、 实验环境1) µPD78F0485单片机:接受来自PC的程序,并通过实验盒中的LCD显示屏、蜂鸣器、LED灯等部件显示出来。2 Notepad+:编写修改源程序;3) 软件NEC Electronics Microcomputer:运行所编写的源程序;二、实验内容1、电路原理PD78F0485单片机外围硬件端口P13到端口P15都是具有输出锁存功能的4位I/O端口。实验中选择这三个端口分别控制12个LED灯的亮灭。端口4是具有输出锁存功能的8位I/O端口,有P40到P47共8个I/O引脚。选择P40到P45共

2、6个端口与6个按钮连接,当对按键模式寄存器KRM进行有效设置,并且在P40/KR0到P47/KR7引脚上输入一个下降沿信号时,就会产生一个按键返回中断信号INTER。P34引脚连接一个led灯,P33引脚连接一个蜂鸣器。LCD驱动方式为4分时1/3偏压,驱动电压为3V,通过COM0COM3,SEG0-SEG19引脚连接1个LCD显示屏2、实验步骤(1)、设计时钟功能对应到每个按键并设计各个时钟函数如显示年月日函数Display_Date()。(2)、 打开PM+ V6.31软件,新建一个工作空间( SS )。 (3)、在PM plus环境下在“File”选项下选择“New”,在弹出的窗口中编写

3、源程序。(4)、编译源程序并调试成功。 (5)、设置PM plus环境并且安装µPD78F0485单片机。 (6)、运行结果并改进。3、实验结果单片机通电后运行启动Show_Time()函数和分秒计数函数。Led小灯从P13.1开始每五秒顺时针一个一个亮。Key1按键后显示年月日,key2按下后显示时分秒,按下key3键则可以在年,月,日,时,分,闹钟时,闹钟分之间进行切换。按下key4键则可以进行加1调整。按下key5键则可以进行减1调整。按下key6键则确定,小灯灭。按下INT键则闹钟结束。4、操作说明1.无按键Lcd显示屏中间显示程序默认分秒00.00,并且时间运行。P13.1

4、灯亮,其它灯按照5秒顺时针一次亮。2.按下Key1Lcd显示屏显示程序默认日期2014.05.12。Led灯按照5秒顺时针一个一个亮。3.按下Key2Lcd显示屏显示程序时间,并且时间运行。Led灯按照5秒顺时针一个一个亮。4.按下Key3每按一下按键,Lcd显示屏中间循环显示年,月,日,时,分,闹钟时,闹钟分。Led灯按照5秒顺时针一个一个亮。5.按下Key4Key3执行时,该按键执行加一操作,Led灯按照5秒顺时针一个一个亮。6.按下Key5Key3执行时,该按键执行减一操作,Led灯按照5秒顺时针一个一个亮。7.按下Key6Key3执行时,该按键执行确定操作,Led灯按照5秒顺时针一个一

5、个亮。 8.按下INT闹钟关闭。5、实验总结本次实验是对课本上“电子日历钟设计”的加深。通过本次试验我对led和lcd显示有了更加熟悉的认识,能熟练应用它们的功能。同时我对时钟计数器也有了一定的认识,可以使用定时中断实现实时时钟,更重要的是我的实践能力有很大的提高。程序设计中遇到的问题 (1)、问题:初始完成程序后秒针走的时间很快,不是精确的一秒走一次。 原因:单片机只能用主系统时间,修改fprs后可以真确显示。(2)、问题:时间切换函数与显示函数和设计的不一样,如只需要显示时,却多显示分。 原因:在仔细看代码后发现每次按键中断都在调用time1()函数,而second+在里面,所以每次都会加

6、快秒的运行。把second+移到外面放入time()函数后这个问题就解决了。 (3)、问题:运行时发现按键中断总会加快秒的运行,不是很精确。 原因:最后设置了一个虚拟的key7,当执行完时间指向case7,然后调用Freshddisplaybuffer();函数,这样就很好的解决了这个问题。在程序调试过程中,设置断点并且在断点处增加一个LED灯,通过判断灯是否亮可以判断程序是否执行到该位置,对程序调试有很大的帮助。附件:程序流程图:主程序流程图开始关中断DI()初始化蜂鸣器并关闭蜂鸣器BZOE = 0;开中断EI();Time1()Freshddisplaybuffer();Display_D

7、ate();noise();d_c_inter()Freshddisplaybuffer();Set_D_T();noise();key=7;结束N1YWhile(1)?Key?UpNum();Freshddisplaybuffer();Set_D_T();noise();key=7;Time1();Freshddisplaybuffer();Set_D_T();noise();key = 0;noise();DownNum();Freshddisplaybuffer();Set_D_T();noise();key=7;FreshddisplaybufferTime1();Show_Time(

8、);Show_Time();023456初始化Lcd和Led; Init_Lcd(),Init_Led();初始化按键中断 InitKey_INTKR();关中断EI()初始化INT 按键 Init_Inter();Time1(); noise();按键中断程序入口关中断DI()key=2key=30x3D(P4 & 0x3F)?key=4breakkey=6key=5key=10x3E0x3B0x370x2F0x1F开中断EI()退出中断INT中断入口关中断DI()Que = 0;BZOE = 0;开中断EI()退出中断按键中断流程图INT中断流程图源代码:#pragma sfr /

9、使用特殊功能寄存器#pragma EI /开中断#pragma DI /关中断#pragma access /使用绝对地址指令#pragma interrupt INTTM000 Time /定义时间中断函数为Time#pragma interrupt INTKR OnKeyPress /定义按键中断为OnKeyPress #pragma interrupt INTP5 OnKeyOver /定义INT中断为OnKeyOvervoid Init_Led();void InitKey_INTKR();void Init_Lcd();void Init_Inter();void LightOneL

10、ed(unsigned char ucNum);void LightOff();int Count_Day(int month);char i=0; /定义变量i,是切换时间的标志int key=0; /定义key=0int temp=1;/用于存放当前月的天数int temp1=1;int second=0;/默认的秒second=0int minute=0;/默认的分minute=0int hour=12;/默认的时hour=12int day=1;/默认的天day=1int month=5;/默认的月month=5int year=2014;/默认的年year=2014int c_hou

11、r=1;/默认的闹钟时=1int c_minute=1;/默认的闹钟分=1int buffs2;/秒的数码显示缓存区int buffm2;/分的数码显示缓存区int buffh2;/时的数码显示缓存区int buffday2;/天的数码显示缓存区int buffmonth2;/月的数码显示缓存区int buffyear4;/年的数码显示缓存区int buffmd4;/月,天的数码显示缓存区int buffhm4;/时,分的数码显示缓存区int buffms4;/分,秒的数码显示缓存区int buffch2;/闹钟时的数码显示缓存区int buffcm2;/闹钟分的数码显示缓存区unsigned

12、 char Que = 0; /INT中断中间变量int LCD_num10=0X070d,0x0600,0x030e,0x070a,0x0603,0x050b,0x050f,0x0700,0x070f,0x070b;/数字09的显示码unsigned char Scond;/延时函数1/void Delay(int k)int i,j;for(i=0;i<k;i+) for(j=0;j<k;j+) /初始化Led函数/void Init_Led()PM13=0XF0; /端口13的第四位为输出模式PM14=0XF0; /端口14的第四位为输出模式PM15=0XF0; /端口15的

13、第四位为输出模式/按键中断函数/void InitKey_INTKR() PM4 = 0x3F; /P4的六个端口设置为输入模式 PU4 = 0x3F; /接通上拉电阻 KRM = 0x3F; /允许六个按键中断 KRMK = 0; PM3.0 = 1; PU3.0 = 1; EGP.5 = 1; PMK5 = 0; PPR5 = 0; KRPR = 1;/ 初始化lcd函数/void Init_Lcd()PFALL=0x0F; /所有接lcd引脚指定为lcd引脚LCDC0=0x34; /设置原时钟和时钟频率LCDMD=0x30; /设置lcd电压为3/5电压LCDM=0xC0; /4分时1/

14、3偏压模式 /初始化定时器Inter函数/void Init_Inter()CRC00.0=0; /CR000为比较寄存器PRM00=0X04; /计数时钟为fprs/28CR000=0X7FFF;/时间间隔为1sTMMK010=1; /TMMK010中断屏蔽TMMK000=0; /TMMK000中断允许TMC00=0X0C; /TM00和CR000相等时进入清零&启动模式 void Time()second+;/按键中断函数/void OnKeyPress()DI();switch(P4&0x3F) /判断哪个按键按下case 0x3e:key=1; /按键key1按下bre

15、ak; case 0x3d:key=2; /按键key2按下break; case 0x3b:key=3; /按键key3按下break;case 0x37:key=4; /按键key4按下break;case 0x2f:key=5; /按键key5按下break;case 0x1f:key=7; /按键key6按下break;default:break;EI();/INT按键中断函数/void OnKeyOver()DI();Que = 0; /判断Que是否为0BZOE = 0; /蜂鸣器关闭EI();/Led小灯函数/void LightOneLed(unsigned char ucNu

16、m)switch(ucNum) /检测变量ucNumcase 0:case 1:case 2:case 3:P13 |= (unsigned char) 1 << (ucNum); /如果为0到3中的一个值则让LED1到LED4中的一个亮 break;case 4:case 5:case 6:case 7:P14 |= (unsigned char) 1 << (ucNum - 4); /如果为4到7中的一个值则让LED5到LED8中的一个亮break;case 8:case 9:case 10:case 11:P15 |= (unsigned char) 1 <

17、< (ucNum - 8); /如果为8到11中的一个值则让LED9到LED12中的一个亮break;default:break;/Led小灯熄灭函数/void LightOff()P13 = 0;P14 = 0;P15 = 0;/时间函数/void Time1()if(second % 5) = 0) /秒大于5变为0Scond = second / 5 + 1; LightOff(); /调用小灯亮函数LightOneLed(Scond % 12);if(second>=60)minute+; /秒大于60时分加1second=0;if(minute>=60)minute

18、=0;hour+; /分大于60时时加1if(hour>=24)hour=0;day+; /时大于24时天加1temp=Count_Day(month);if(day>=temp)day=1;month+; /天大于当前月份的天数时月加1if(month>=13)month=1; year+; /月大于12时年加1/计算当前月的天数/int Count_Day(int month)int day;if(month=4)|(month=6)|(month=9)|(month=11)/4,6,9,11月为30天day=30;else if(month=2)if(year%4=0&

19、amp;&year%100=0)|(year%400=0)day=29; /闰年2月29天elseday=28; /平年2月28天elseday=31; /1,3,5,7,8,10,12月为31天return (day);/倒计时函数./void Show_Time()pokew(0xFA40,0x00);pokew(0xFA42,0x00);pokew(0XFA48,buffs1); /在lcd右边显示1pokew(0XFA4A,buffs0); /在lcd右边显示0 pokew(0XFA44,buffm1); /在lcd右边显示1pokew(0XFA46,buffm0); /在lc

20、d右边显示0pokew(0xFA4C,0x00);pokew(0xFA4E,0x00);Delay(100);/日期显示函数/void Display_Date()buffm0|=0x0800;pokew(0xFA40,buffyear3); /显示年pokew(0xFA42,buffyear2);pokew(0xFA44,buffyear1);pokew(0xFA46,buffyear0);pokew(0xFA48,buffmonth1); /显示月pokew(0xFA4A,buffmonth0);pokew(0xFA4C,buffday1); /显示日pokew(0xFA4E,buffda

21、y0);temp1=0;/时间显示函数/void Display_Time()pokew(0xFA40,0x00); pokew(0xFA42,0x00);pokew(0xFA44,buffh1); /显示时pokew(0xFA46,buffh0);pokew(0xFA48,buffm1); /显示分pokew(0xFA4A,buffm0);pokew(0xFA4C,buffs1); /显示秒pokew(0xFA4E,buffs0);/设定时间函数/void Set_D_T()int lcd_addr;lcd_addr = 0xFA40;switch(i)case 1:pokew(lcd_ad

22、dr,buffyear3); /时间年pokew(lcd_addr+2,buffyear2);pokew(lcd_addr+4,buffyear1);pokew(lcd_addr+6,buffyear0);pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 2:pokew(lcd_addr,0x00);pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,0x00);pokew(lcd_addr+6,0x00)

23、;pokew(lcd_addr+8,buffmonth1); /时间月pokew(lcd_addr+10,buffmonth0);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 3:pokew(lcd_addr,0x00);pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,0x00);pokew(lcd_addr+6,0x00);pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,buffday1); /时间日poke

24、w(lcd_addr+14,buffday0);break;case 4:pokew(lcd_addr,0x00);pokew(lcd_addr+2,0x00);pokew(lcd_addr+4,buffh1); /时间时pokew(lcd_addr+6,buffh0); pokew(lcd_addr+8,0x00);pokew(lcd_addr+10,0x00);pokew(lcd_addr+12,0x00);pokew(lcd_addr+14,0x00);break;case 5: pokew(0xFA40,0x00);pokew(0xFA42,0x00);pokew(0xFA44,0x0

25、0);pokew(0xFA46,0x00);pokew(0xFA48,buffm1); /时间分pokew(0xFA4A,buffm0);pokew(0xFA4C,0x00);pokew(0xFA4E,0x00);break;case 6:pokew(0xFA40,0xd1);pokew(0xFA42,0xd0);pokew(0xFA44,0xd7);pokew(0xFA46,0xd1);pokew(0xFA48,0x50);pokew(0xFA4A,0x56);pokew(0xFA4C,buffch1); /闹钟时pokew(0xFA4E,buffch0);break;case 7:poke

26、w(0xFA40,0xd1);pokew(0xFA42,0xd0);pokew(0xFA44,0xd7);pokew(0xFA46,0xd1);pokew(0xFA48,0x50);pokew(0xFA4A,0x00);pokew(0xFA4C,buffcm1); /闹钟分pokew(0xFA4E,buffcm0);break;default:break;/切换时间函数/void d_c_inter()DI(); /关中断i+;if(i>7) /切换标志>7,i=1,否则i+i=1;EI(); /开中断/调整时间加函数/void UpNum()switch(i)case 1:yea

27、r+;case 2:month+;if(month > 12)month = 1;break;case 3:temp = Count_Day(month); day+; if(temp < day)day = 1; break;case 4:hour+;if(hour > 23)hour = 1; break;case 5:minute+;if(minute > 59)minute = 0;break;case 6:c_hour+;if(c_hour > 23)c_hour = 1; break;case 7:c_minute+;if(c_minute >

28、59)c_minute = 0;break;default:break;/调整时间减函数/void DownNum()switch(i)case 1:year-;case 2:month-;if(month < 1)month = 12;break;case 3:temp = Count_Day(month); day-; if(day < 1)day = temp; break;case 4:hour-;if(hour < 1)hour = 23; break;case 5:minute-;if(minute < 0)minute = 59;break;case 6:

29、c_hour-;if(c_hour < 1)c_hour = 23; break;case 7:c_minute-;if(c_minute < 0)c_minute = 59;break;default:break;/闹铃以及小灯函数/void noise()if(c_hour = hour && c_minute = minute && Que = 1) /闹铃的时,分与系统时,分相等,并且闹钟标志开启CKS=0XE0; /开启蜂鸣器输出,输出频率为0.98khz的音频Time1(); /调用时间函数/显示缓存区刷新时间函数/void Freshd

30、displaybuffer()buffs1=LCD_numsecond/10;/秒的显示码放入秒的数码显示缓存区buffs0=LCD_numsecond%10;buffm1=LCD_numminute/10;/分的显示码放入分的数码显示缓存区buffm0=LCD_numminute%10;buffm0|=0x0800; /分的后面显示一个"."buffh1=LCD_numhour/10; /时的显示码放入时的数码显示缓存区buffh0=LCD_numhour%10;buffh0|=0x0800; /时的后面显示一个"."buffday1=LCD_numd

31、ay/10; /天的显示码放入天的数码显示缓存区buffday0=LCD_numday%10;buffmonth1=LCD_nummonth/10;/月的显示码放入月的数码显示缓存区buffmonth0=LCD_nummonth%10;buffmonth0|=0x0800; /月的后面显示一个"."buffyear3=LCD_numyear/100/10;/年的显示码放入年的数码显示缓存区buffyear2=LCD_num(year/100)%10;buffyear1=LCD_num(year%100)/10;buffyear0=LCD_num(year%100)%10;b

32、uffyear0|=0x0800; /年的后面显示一个"."buffmd3=LCD_nummonth/10;/月,天的显示码放入月,天的数码显示缓存区buffmd2=LCD_nummonth%10;buffmd2|=0x0800; /月,天后显示一个"."buffmd1=LCD_numday/10;buffmd0=LCD_numday%10;buffhm3=LCD_numhour/10;/时,分的显示码放入时,分的数码显示缓存区buffhm2=LCD_numhour%10;buffhm2|=0x0800; /时,分的后显示一个"."b

33、uffhm1=LCD_numminute/10;buffhm0=LCD_numminute%10;buffms3=LCD_numminute/10;/分,秒的显示码放入分,秒的数码显示缓存区buffms2=LCD_numminute%10;buffms2|=0x0800; /分,秒的后显示一个"."buffms1=LCD_numsecond/10;buffms0=LCD_numsecond%10;buffch1=LCD_numc_hour/10;/闹钟时的显示码放入闹钟时的数码显示缓存区buffch0=LCD_numc_hour%10;buffcm1=LCD_numc_minute/10;/闹钟分的显示码放入闹钟分的数码显示缓存区buffcm0

温馨提示

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

最新文档

评论

0/150

提交评论