《万历程序和电路图.doc》由会员分享,可在线阅读,更多相关《万历程序和电路图.doc(51页珍藏版)》请在课桌文档上搜索。
1、目录目录第一章设计方案 11.1.硬件设计 1设计要求 1硬件框图 1硬件选择 11.2 软件设计 3编程环境及语言 3程序框图 3第二章系统设计 42.1 硬件设计 4振荡电路 4复位电路 4按键 42.1.4 lcd 显示电路 5音乐播放电路 52.1.6 P0 上拉电阻计算 62.2 软件设计 7程序流程图 7流程的各个模块设计 9心得体会 21附录 1. 元器件表 22附录 2.程序源代码 231602.c 文件 23Clock.H 文件 24Music.h 文件 28LCD1602.H 文件 29参考文献 31引言引言单片机就是微控制器,是面向应用对象设计、突出控制功能的芯片。单片机
2、接上晶振、复位电路和相应的接口电路,装载软件后就可以构成单片机应用系统。将它嵌入到形形色色的应用系统中,就构成了众多产品、设备的智能化核心。本设计就是应用单片机强大的控制功能制作而成的电子万年历,该电子万年历包括三大功能:实时显示年、月、日、时、分、秒;实现位调;附加播放音乐功能。本设计是基于 AT89C51 和 LCD1602 液晶显示器设计的可调式电子钟。该单片机采用的 MCU51 核,因此具有很好的兼容性,部带有 4KB 的 ROM,能够存储大量的程序,最突出特点是具有 ISP 在系统烧写功能,使得烧写程序更加方便。显示器件采用通用型 1602 液晶,可显示 32 个字符,如果使用数码管
3、来做显示器件需消耗大量的系统资源,因此采用低功耗的 1602 液晶,该液晶显示方便,功能强大,完全能满足数字万年历的显示要求。通过此次设计能够更加结实的掌握单片机的应用技术,增强动手能力、硬件设计能力以及软件设计能力。第一章第一章 设计方案设计方案1.1.1.1.硬件设计硬件设计1.1.11.1.1 设计要求设计要求实现年月日、时分秒、星期的显示功能,用两个按键来实现日期和时间的调整功能,调整要求星期能自动更新,且能实现位调。显示格式:四位年,两位月,两位日,星期字母前三位,两位时,两位分,两位秒。比方:YYYY-MM-DD WEEKHH:MM:SS1.1.21.1.2 硬件框图硬件框图图 1
4、-1-硬件框图日期时间由硬件软件结合产生;按键之间相互配合完成当前日期时间的调整功能。过程与结果由控制芯片分别输出到显示器上。本设计附加了播放音乐的功能。音乐从蜂鸣器产生。1.1.31.1.3 硬件选择硬件选择1.显示模块本设计具体选用与实际应用与消耗资源相关。万年历用到的地方大多都在室。现市场上与许多显示器,在日常生活中最常见的有数码管,led 点阵屏,lcd 液晶显示器等。八段数码管的优点:亮度高,显示大。驱动部份的软件简单;缺点:与液晶相比,耗电及体积大。数码管只能单纯的显示数字,不能生动的表达各个参数的信息,消耗电力也比 led 液晶显示器大。LCD 液晶显示器它是一种专门用来显示字母
5、、数字、符号等的点阵型液晶模块,在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高,由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器CRT那样需要不断刷新新亮点。因此,液晶显示器画质高且不会闪烁。数字式接口,液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。控制芯片控制芯片显示器显示器按键调整按键调整体积小、重量轻,液晶显示器通过显示屏上的电极控制液晶分子状态来到达显示的目的,在重量上比一样显示面积的传统显示器要轻得多。功耗低,相对而言,液晶显示器的功耗主要消耗在其部的电极和驱动 IC 上,因而耗电量比其它显示器要
6、少得多。Lcd 液晶能一屏把本设计所要显示的信息表达完整。而且lcd 耗电小,体积小很适合与室使用。本设计的要求日期时间以数字表示、星期用 3 位英文字符表示共 21 个字符,lcd1602能显示 32 个字符,足以完成显示功能。Lcd1602 有 16 个引脚,各个引脚功能见下表:引脚号引脚名电平输入/输出作用1VSS电源地2VDDVcc电源+5v3VEE比照调整电压4RS0/1输入0=输入指令,1=输入数据5R/W0/1输入0=向 lcd 写入数据或指令1=从 lcd 读取数据6E1,1-0输入使能信号,1=读取信息1-0下降沿执行指令7DB00/1输入/输出数据总线 line08DB10
7、/1输入/输出数据总线 line19DB20/1输入/输出数据总线 line210DB30/1输入/输出数据总线 line311DB40/1输入/输出数据总线 line412DB50/1输入/输出数据总线 line513DB60/1输入/输出数据总线 line614DB70/1输入/输出数据总线 line715AVccLcd 背光正极14KLcd 背光负极表 1-1 lcd1602 引脚及功能2.按键与蜂鸣器本设计选用轻触按钮,型号为*DJT1102S。选用压电式蜂鸣器型号 PT-1540P RoHS。3.控制芯片根据 lcd1602 液晶显示器与按键的引脚 I/O 数量以及扩展功能的要求,所
8、选控制芯片至少需要三组 I/O 口,本设计功能简单,所以程序量较小,AT89C51 是一种带 4K 字节闪存只读存储器的低电压、高性能 CMOS 8 位微处理器。AT89c51 是 51 系列根本的控制芯片,能满足本设计的要求,性价比也要低于 51 系列其他的芯片。4.日期时间生成模块为了减少本钱,使用 51 的部定时器中断再配合软件计数的方式来生成一秒的时间。1.21.2 软件设计软件设计1.2.11.2.1 编程环境及语言:编程环境及语言:本设计的原理图实现是在 proteus 中实现的,本设计的程序在 keil Uvision4 环境中进展编程与调试的,keil Uvision4 与 p
9、roteus 联调能有效的对各个设计进展测试。编程语言51C。1.2.21.2.2 程序框图程序框图图 1-2 程序框图1.time0 中断用于生成时间,具体由程序和硬件共同产生 1 秒的时间。2.两个外部中断能进展时间日期的切换,和对时间日期进展调整,播放音乐,能满足对按键设置的要求。3.主函数能及时在液晶屏上显示默认的时间和调整后的时间。主函数主函数Time0 中断中断与软件计数与软件计数产生产生 1 秒的秒的时间,并实时间,并实现日期时间现日期时间更新更新按键按键 1 按下按下Int0 中断响中断响应应按键按键 2 按下按下Int1 中断响中断响应应液晶显示液晶显示第二章第二章 系统设计
10、系统设计2.12.1 硬件设计硬件设计2.1.12.1.1 振荡电路振荡电路本设计 51 芯片选用部振荡器方式。由于本设计的时间由部定时器中断与软件计数相结合产生的,所以从计算方便以及系统的效率上考虑,本设计选用 12MHz 频率的晶振,电路原理图如下:图 2-1 AT89C51 的振荡电路经厂家推荐稳定电路的电容 C1,C2=30pF+-10p附录资料 AT89C51.PDF 第 4-32 页 。2.1.22.1.2 复位电路复位电路本设计使用上电复位电路。单片机晶振为 12MHz,起振时间将近 1ms,单片机 1 个机器周期的时间为 1us。单片机每次上电复位所需的最短延时应该不小于 tr
11、eset。这里,treset 等于上电延时与起振延时之和。从实际上讲,延迟一个 treset 往往还不够,不能够保障单片机有一个良好的工作开端。复位电路把单片机锁定在复位状态上并且维持一个延时记作 TRST ,以便给予电源电压从上升到稳定的一个等待时间;在电源电压稳定之后,再插入一个延时,给予时钟振荡器从起振到稳定的一个等待时间;在单片机开场进入运行状态之前,还要至少推迟 2 个机器周期的延时间。单片机是高电平的时候复位,一般是用电阻和电容组成的,电容充电的时 RST 复位端为高电平,此时单片机开场复位.电容充电完成,此时单片机复位完成。由此电容值可取 22uf,电阻值取 10K。详细见附录文
12、件电容充电时间的计算方法.pdf图 2-2 AT89C51 上电复位电路2.1.32.1.3 按键按键选用两个轻触按键与单片机 P32int0 、P33int1两个引脚相接组成的独立按键。2.1.42.1.4 lcdlcd 显示电路显示电路1.lcd 的选用本设计选用型号为 LCD-016M002L 显示器。具体资料见附录文件 LCD-016M002L.pdf。2.lcd 与 51 引脚的连接Lcd1602 引脚AT89C51 引脚LCD1602 引脚AT89C51 引脚RSP20DB3P03R/WP21DB4P04EP22DB5P05DB0P00DB6P06DB1P01DB7P07DB2P0
13、2表 2-1 lcd1602 与 51 的连接VEE 为液晶显示器比照度调整端,接正电源时比照度最弱,接地时比照度最高,比照度过高时会产生“鬼影,使用时可以通过一个 10K 的电位器调整比照度。图 2-3 1602 液晶与单片机接口电路2.1.52.1.5 音乐播放电路音乐播放电路此模块采用蜂鸣器实现,蜂鸣器驱动电流为20mA,单片机的 P1 口输出电流为26mA 能够直接驱动蜂鸣器。只要编写相应的程序即可实现发出不同频率的声音,蜂鸣器与单片机的接口电路,蜂鸣器接线与单片机P17 引脚相连。图 2-5 蜂鸣器电路2.1.62.1.6 P0P0 上拉电阻计算上拉电阻计算由于 lcd 数据口是与
14、51 的 P0 口连接的,在 P0 口做一般 I/O 使用时要外接上拉电阻。根据 LCD-016M002L 显示器的伏安特性,要保证上拉电阻明显小于 lcd 的阻抗,以使高电平时输出有效Lcd 工作电压:+5VLcd 工作电流:20mAlcd 阻抗=5v/20mA=2.5k。上拉电阻值可以取 2.2k详细见附录资料上拉电阻下拉电阻的总结.doc,由于需要八个一样的上拉电阻如图 2-6 所示,也可用一个排阻。具体型号见附录表。图 2-6 上拉电阻2.22.2 软件设计软件设计2.2.12.2.1 程序流程图程序流程图开场初始化将数据写入缓冲区显示缓冲区内容开场赋计数初值判断是否计满一秒时间更新返
15、回是否图 2-6 主函数流程图 2-7 time0 中断效劳程序流程是否判断是否在调整状态调整当前指针号的值播放音乐开场返回图 2-8 int1 中断效劳流程开场定时器停顿工作,调整指针加 1。调状态标志置 1,秒清零。等待按键松开。判断调整指针是否增到上限值即调整完毕指针复位。调整状态标志清零,定时器开场工作。返回是否图 2-9 int0 中断效劳流程2.2.22.2.2 流程的各个模块设计流程的各个模块设计全局变量datetime 数组保存日期时间星期的容器。min2,hour2,day2,mon2,year4;调整时候使用的中间变量。buffer_date16,buffer_time16
16、显示缓冲区。1.定时器中断效劳程序定时器 1 计时一秒。计数初值的计算方法如下:设晶振频率为 f,则定时/计数器计数频率为 f/12, 定时/计数器的计数总次数 T_all 在方式 1 为 216=65536,定时间隔为 T,计数初值为 a,则有a=-Tf/12将计数初值 a 分别赋给加 1 计数器 TH0、TL0:TH0=T_all-a/256;TL0=T_all-a%256;本设计晶振频率为 12MHz,定时间隔为 50ms,所以a=-0.05*12000000/12a=50000TH0=65536-50000/256TL0=65536-50000%2561s 就要计 20 次,中断效劳程
17、序如下:void time0() interrupt 1 using 3TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(+count=20)/计时一秒count=0;DATATIME();/按实际规则日期时间更新2.int0 中断效劳程序按键 1 接在了 int0 对应的引脚 P32。按键 2 接在了 int1 对应的引脚 P33。Int0 为电平触发方式,int1 为边沿触发方式。由于按键 2 是一键多功能,具体功能由状态标志FLAG 说明。所以在 int0 中断效劳程序中要有对 FLAG 标志的置位及清位的操作。在调整期间为了时间准确定时器不能
18、工作,为了对日期时间的各位值进展循环调整,设置了一个计数器,它的值说明要调整的是哪位。终端效劳程序如下:void int0_K1() interrupt 0 TR0=0;/定时器停顿um+;/计数器加 1FLAG=1;/标志位置位datetime0=0;while(K1=0); /等待按键松开if(um12)/调整完毕,各个状态复原TR0=1;um=-1;FLAG=0;3.int1 中断效劳程序Int1 只要判断标志位执行任务就行了,中断效劳程序如下:void int1_K2() interrupt 2if(FLAG=1)/调整状态下则位对应调整位的增值,正常状态则播放音乐EDIT_datet
19、ime(um);/按计数器的值调整对应位elseShowString(0*00,0, );/播放音乐是屏幕上的字幕ShowString(0*00,1,happy);music();Delayms(500);4.主函数程序主函数对各个中断及 lcd1602 初始化后,就一直进展显示工作了,显示的时候判断标志 FLAG 以区别是正常显示还是闪烁显示。主程序如下:void main()IE=0*87;/开中断 ea=1,et0=1,et1=1,e*0=1TCON=0*04;/it1 为边沿触发,it0 电平触发IP=0*0a;/定时器 0,1 为高优先级TMOD=0*01;/设置定时器 0 方式 1
20、TH0=(65536-50000)/256;TL0=(65536-50000)%256;Initialize_LCD();/初始化 LCDTR0=1;while(1)buffer_value();/设置显示缓存区的容if(FLAG)/调整时对应调整位置闪烁if(+refresh=5)refresh=0;Flash(um);DIS_buffer();/将显示缓冲区的容输出到 lcd 上5.星期在调整是是自动更新的,这要归功于蔡勒公式。算法如下C51 表示:unsigned char week()unsigned int y,m,c,s;y=datetime5%100;c=datetime5/10
21、0;if(datetime4=1)m=13;y-;if(datetime4=2)m=14;y-; s=y+y/4+c/4-2*c+26*(m+1)/10+datetime3-1;/蔡勒公式s=s%7;return s;函数返回值:0-星期日,1-星期一6-星期六6.闰年是自动判断的,算法:(year%4=0)&(year%100!=0)|year%400=0函数代码如下:unsigned char Ynian(unsigned char year)if( (year%400=0|year%4=0) & (year%100!=0) )return 1;elsereturn 0;是闰年返回 1,否
22、则返回 07.月的天数判断,由于 1,3,5,7,8,10,12 每月有 31 天;4,6,9,11 每月有 30 天;2 月闰年 29天,平年 28 天。所以只要判断月号是哪一类的,就返回那类的值,2 月用闰年判断算法判断。函数代码如下:unsigned char MON(unsigned char month)switch(month)case 1:case 3:case 5:case 7:case 8:case 10:case 12: return 31;case 4:case 6:case 9:case 11: return 30;default:if(Ynian(datetime5)
23、/二月特殊,闰年判断return 29;elsereturn 28;返回各月的天数上限。8.日期时间更新按照实际规则更新,60 秒一分,60 分一时,24 小时一日,30 日或 31 日或 28 日或29 日一月,12 月一年。函数代码如下:void DATATIME()datetime0+;if(datetime059) /秒判断datetime0=0;datetime1+;if(datetime159)/分datetime1=0;datetime2+; if(datetime223)/时datetime2=0;datetime3+;if(datetime3MON(datetime4)/日d
24、atetime3=1;datetime4+; if(datetime412) /月datetime4=1;datetime5+; /年/时刻为进入调整状态作准备,将当前日期时间值赋给调整时的变量datetime6=week();min0=datetime1%10;min1=datetime1/10;hour0=datetime2%10;hour1=datetime2/10;day0=datetime3%10;day1=datetime3/10;mon0=datetime4%10;mon1=datetime4/10;year0=datetime5%10,year1=datetime5%100/1
25、0;year2=datetime5%1000/100,year3=datetime5/1000;9.调整日期时间函数,利用 um 计数器指定当前的调整属性,函数源代码如下:void EDIT_datetime(charum)switch(um)case 0: min0+;if(min09) /分低位调整限制 min0=0;break;case 1:min1+;if(min15) /分高调整限制min1=0;break;case 2:hour0+;if(hour09)/时低位调整限制hour0=0;break;case 3:hour1+;if(hour12)/时高位调整限制hour1=0;bre
26、ak;case 4:day0+; if(day09) /日低位调整限制day0=0;break;case 5:day1+;if(day13)/日高位调整限制day1=0;break;case 6:mon0+;if(mon09)/月低位调整限制mon0=0;break;case 7:mon1+;if(mon11)/月高位调整限制mon1=0;break;case 8:year0+; /年调整if(year09)year0=0;break;case 9:year1+;if(year19)year1=0;break;case 10:year2+;if(year29)year2=0;break;cas
27、e 11:year3+;if(year39)year3=0;break;datetime1=min0+min1*10; /调整后将 datetime 实时更新datetime2=hour0+hour1*10;datetime3=day0+day1*10;datetime4=mon0+mon1*10;datetime5=year0+year1*10+year2*100+year3*1000;调整后能及时让 datetime 更新。10.将 datetime 的日期时间星期按照格式放到缓冲区上,格式为:YYYY-MM-DD weekHH:MM:SS函数源代码如下:void buffer_value
28、()Format_Datetime(datetime0,buffer_time+6);/将年月日时分秒星期,Format_Datetime(datetime1,buffer_time+3);/放到对应缓冲区的位置上Format_Datetime(datetime2,buffer_time+0);/以待显示Format_Datetime(datetime3,buffer_date+8);Format_Datetime(datetime4,buffer_date+5);Format_Datetime(datetime5%100,buffer_date+2);Format_Datetime(date
29、time5/100,buffer_date+0);buffer_date13=week1week();buffer_date14=week2week();buffer_date15=week3week();Lcd1602 显示的是字符,所以用函数转换。Format_Datetime(数组 1,数组 2)功能:将数组 1 的数值转换为字符放到数组 2。11.闪烁显示,在主函数显示配合延时清空,写入缓冲区的容,到达闪烁效果。具体哪位闪烁还是有 um 决定。函数源代码如下:void Flash(char n)switch(n)case 0:buffer_clr(0,4); /对应分低位置,清空bre
30、ak;case 1:buffer_clr(0,3);break;case 2:buffer_clr(0,1);break;case 3:buffer_clr(0,0);break;case 4:buffer_clr(1,9);break;case 5:buffer_clr(1,8);break;case 6:buffer_clr(1,6);break;case 7:buffer_clr(1,5);break;case 8:buffer_clr(1,3);break;case 9:buffer_clr(1,2);break;case 10:buffer_clr(1,1);break;case 1
31、1:buffer_clr(1,0);break;case 12:Write_LCD_mand(0*c0 |12);/第 2 行 12 列后显示 overWrite_LCD_Data(o);Write_LCD_Data(v);Write_LCD_Data(e);Write_LCD_Data(r);break;12.显示缓冲区。源代码如下:void DIS_buffer()ShowString(0*00,0,buffer_date);/输出缓冲区的容ShowString(0*00,1,buffer_time);ShowString 是 lcd 的驱动函数。其他的驱动函数见下。13.lcd1602
32、的驱动程序Lcd1602 与单片机引脚的连接前面已将过了。下面是各个对 lcd1602 的操作。具体细节可看 lcd1602 的资料。/*-函数名:Busy_Check功能:读取 lcd 忙标志输入参数:无输出参数:返回读取的数据修改日期:2010-06-01-*/unsigned char Busy_Check()unsigned char LCD_Status;RS = 0; /存放器选择RW = 1; /读状态存放器EN = 1; /开场读Delayms(1);LCD_Status = P0;EN = 0;return LCD_Status;/*-函数名:Write_LCD_mand功能
33、:向 LCD 写指令输入参数:cmd-指令输出参数:无修改日期:2010-06-01-*/void Write_LCD_mand(unsigned char cmd)while(Busy_Check()&0*80)=0*80);/忙等待RS = 0; /选择命令存放器RW = 0; /写EN = 0;P0 = cmd;EN = 1;Delayms(1);EN = 0;/*-函数名:Write_LCD_Data功能:向 lcd 发送数据输入参数:dat-数据输出参数:无修改日期:2010-06-01-*/void Write_LCD_Data(unsigned char dat)while(Bu
34、sy_Check()&0*80)=0*80);/忙等待RS = 1;RW = 0;EN = 0;P0 = dat;EN = 1;Delayms(1);EN = 0;/*-函数名:Initialize_LCD功能:对 lcd 初始化输入参数:无输出参数:无修改日期:2010-06-01-*/void Initialize_LCD()Write_LCD_mand(0*38);/8 位,2 行,5*7 点阵Delayms(1);Write_LCD_mand(0*01);/清屏Delayms(1);Write_LCD_mand(0*06);/字符进入模式,屏幕不动,字符后移Delayms(1);Wri
35、te_LCD_mand(0*0c);/显示开,关光标Delayms(1);/*-函数名:ShowString功能:显示字符串输入参数:*-列 y-行 str 字符串输出参数:无修改日期:2010-06-01-*/void ShowString(unsigned char *,unsigned char y,unsigned char *str) unsigned char i = 0;/设置显示起始位置if(y = 0)Write_LCD_mand(0*80 | *);if(y = 1)Write_LCD_mand(0*c0 | *); /输出字符串for(i=0;i16;i+) Write_
36、LCD_Data(stri);心得体会心得体会单片机的学习已告一段落,我对自己的专业有了更深的体会。非常感钱教师的辛勤教诲,以企业的要求对我们进展培训,开拓我们的思维,改变我们的思维方式,让我们自主发挥,让我们在以后工作中少走很多弯路,并在此过程中让我们自己找到了自身的种种缺点,让我们受益非浅。也许现阶段的学习还存在诸多缺乏,在以后的学习中,会勤于总结,认真学好自己的专业课程。附录 1. 元器件表序号代号名称型号、规格数量备注1U1单片机AT89C5112K1,K2按钮*DJT1102S23C1,C2电容0805 30pF2贴片4C3电解电容CSR1322uF15*1晶振PTVC 75114
37、12MHz16Lcd液晶显示器LCD-016M002L17R1电阻RJ47 10k 0.5W18R2电位器W*2 27-15k 1W19RP1排阻A09-103J 2.2k8 1w1贴片10S1蜂鸣器PT-1540P RoHS1压电式11Vcc电源+5V1附录 2.程序源代码1602.c1602.c 文件文件/*-工程名称:万年历制作:强王先忠王子房振伟修改日期:2010-06-04-*/#include#include#includesbit K1=P32;sbit K2=P33;unsigned char count,refresh;charum=-1;/日期时间的指针unsigned c
38、har FLAG=0;/调整标志 flag=1 则是调整状态unsigned char happy16=Happy birthday;void main()IE=0*87;/开中断TCON=0*04;/it1 为边沿触发,it0 电平触发IP=0*0a; /定时器 0,1 为高优先级TMOD=0*01; /设置定时器 0 方式 1TH0=(65536-50000)/256;TL0=(65536-50000)%256;Initialize_LCD();/初始化 LCDTR0=1;while(1)buffer_value();/设置显示缓存区的容if(FLAG) /调整时对应调整位置闪烁if(+r
39、efresh=5)refresh=0;Flash(um);DIS_buffer();/将显示缓冲区的容输出到 lcd 上void time0() interrupt 1 using 3TH0=(65536-50000)/256;TL0=(65536-50000)%256;if(+count=20)/计时一秒count=0;DATATIME();/日期时间生成void int0_K1() interrupt 0 TR0=0;um+;FLAG=1;/标志位置位datetime0=0;while(K1=0);if(um12)/调整完毕,各个状态复原TR0=1;um=-1;FLAG=0;void in
40、t1_K2() interrupt 2if(FLAG=1)/调整状态下则位对应调整位的增值,正常状态则播放音乐EDIT_datetime(um);else ShowString(0*00,0, );ShowString(0*00,1,happy);music();Delayms(500);Clock.HClock.H 文件文件#ifndef _CLOCK_#define _CLOCK_unsigned int datetime7=0,59,0,1,6,2010,2;/秒,分,时,日,月,年,星期unsigned char code week17=SMTWTFS;/组成星期前三个字母unsign
41、ed char code week27=uouehra;unsigned char code week37=nneduit;unsignedchar min2,hour2,day2,mon2,year4;unsigned char buffer_date16=2010-06-01 2;unsigned char buffer_time16=00:00:00 ;/*-函数名:Ynian功能:判断年份是否为闰年输入参数:year 一个有效的年份输出参数:是闰年输出 1,否则输出 0制作人:强修改日期:2010-06-01-*/unsigned char Ynian(unsigned char ye
42、ar)if( (year%400=0|year%4=0) & (year%100!=0) )return 1;elsereturn 0;/*-函数名:MON功能:判断*一月分的天数上限输入参数:month 一个有效的月份输出参数:返回该月份的上限值制作人:强修改日期:2010-06-01-*/unsigned char MON(unsigned char month)switch(month)case 1:case 3:case 5:case 7:case 8:case 10:case 12: return 31;case 4:case 6:case 9:case 11: return 30;
43、default:if(Ynian(datetime5) /二月特殊return 29;elsereturn 28;/*-函数名:week功能:实现星期的更新输入参数:无输出参数:星期值,0-星期日,1-星期一6-星期六修改日期:2010-06-01-*/unsigned char week()unsigned int y,m,c,s;y=datetime5%100;c=datetime5/100;if(datetime4=1)m=13;y-;if(datetime4=2)m=14;y-; s=y+y/4+c/4-2*c+26*(m+1)/10+datetime3-1; /蔡勒公式s=s%7;r
44、eturn s;/*-函数名:DATATIME功能:实现时间日期的更新输入参数:无输出参数:无修改日期:2010-06-02-*/void DATATIME()datetime0+;if(datetime059) /秒datetime0=0;datetime1+;if(datetime159)/分datetime1=0;datetime2+; if(datetime223)/时datetime2=0;datetime3+;if(datetime3MON(datetime4)/日datetime3=1;datetime4+; if(datetime412)/月datetime4=1;dateti
45、me5+; /年datetime6=week();/时刻为进入调整状态作准备min0=datetime1%10;min1=datetime1/10;hour0=datetime2%10;hour1=datetime2/10;day0=datetime3%10;day1=datetime3/10;mon0=datetime4%10;mon1=datetime4/10; year0=datetime5%10,year1=datetime5%100/10;year2=datetime5%1000/100,year3=datetime5/1000;/*-函数名:Format_Datetime功能:日期
46、时间转换为数字字符输入参数:d-数据 a-指向存放转换结果的数组输出参数:无修改日期:2010-06-01-*/void Format_Datetime(unsigned int d,unsigned char *a ) a0=d/10+0; a1=d%10+0;/*-函数名:EDIT_datetime功能:实现对日期时间的调整包括闹钟调整输入参数:um 是表指示前调整的值-1,不调整,013 分别是分年的各位,14-保存调整结果输出参数:无修改日期:2010-06-05-*/void EDIT_datetime(charum)switch(um)case 0: min0+;if(min09)
47、 /分低位调整限制 min0=0;break;case 1:min1+;if(min15) /分高调整限制min1=0;break;case 2:hour0+;if(hour09)/时低位调整限制hour0=0;break;case 3:hour1+;if(hour12)/时高位调整限制hour1=0;break;case 4:day0+; if(day09) /日低位调整限制day0=0;break;case 5:day1+;if(day13)/日高位调整限制day1=0;break;case 6:mon0+;if(mon09)/月低位调整限制mon0=0;break;case 7:mon1
48、+;if(mon11)/月高位调整限制mon1=0;break;case 8:year0+; /年调整if(year09)year0=0;break;case 9:year1+;if(year19)year1=0;break;case 10:year2+;if(year29)year2=0;break;case 11:year3+;if(year39)year3=0;break;datetime1=min0+min1*10; /调整后将 datetime 实时更新datetime2=hour0+hour1*10;datetime3=day0+day1*10;datetime4=mon0+mon
49、1*10;datetime5=year0+year1*10+year2*100+year3*1000;/*-函数名:buffer_vlaue功能:对缓冲区的选择输入参数:无输出参数:无制作人:强修改日期:2010-06-02-*/void buffer_value()Format_Datetime(datetime0,buffer_time+6);/将年月日时分秒星期,Format_Datetime(datetime1,buffer_time+3);/放到对应缓冲区的位置上Format_Datetime(datetime2,buffer_time+0);/以待显示Format_Datetime
50、(datetime3,buffer_date+8);Format_Datetime(datetime4,buffer_date+5);Format_Datetime(datetime5%100,buffer_date+2);Format_Datetime(datetime5/100,buffer_date+0);buffer_date13=week1week();buffer_date14=week2week();buffer_date15=week3week();/*-函数名:buffer_clr功能:针对缓冲区位置进展清空输入参数:无输出参数:无修改日期:2010-06-01-*/void