还剩31页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
课程设计实验报告实验题目万年历的单片机实现专业班级XXXXXXXXXXXX姓名XXXXXXXXX学号XXXXXXXXXX指导老师XXXXXXXXXXXXXXXXX0x02,0xB6,0x44,//19350x39,0x37,0x38,//19360x09,0x2e,0x4B,//19370x7C,0x96,0xBf,//19380x00,0x95,0x53,//19390x0d,0x4A,0x48,//19400x6d,0xA5,0x3B,//19410x0B,0x55,0x4f,//19420x05,0x6A,0x45,//19430x4A,0xAd,0xB9,//19440x02,0x5d,0x4d,//19450x09,Ox2d,0x42,//19460x2C,0x95,0xB6,//1947OxOA,0x95,0x4A,//19480x7B,0x4A,Ox Bd,//19490x06,0xCA,0x51,//1950OxOB,0x55,0x46,//19510x55,0x5A,0xBB,//19520x04,0xdA,0x4e,//19530x0A,0x5B,0x43,//19540x35,Ox2B,0xB8,9550x05,0x2B,0x4C,//19560x8A,0x95,0x3f,〃7957OxOe,0x95,0x52,//19580x06,OxAA,0x48,//19590x7A,0xd5,0x3C,//19600x0A,0xB5,0x4f,//19610x04,0xB6,0x45,//19620x4A,0x57,0x39,//19630x0A,0x57,0x4d,//19640x05,0x26,0x42,//19650x3e,0x93,0x35,//1966OxOd,0x95,0x49,//19670x75,0xAA,0xBe,//19680x05,0x6A,0x51,//19690x09,0x6d,0x46,//19700x54,0xAe,0xBB,//19710x04,0xAd,0x4f,//19720x0A,0x4d,0x43,//19730x4d,0x26,0xB7,//19740x0d,0x25,0x4B,//19750x8d,0x52,0xBf,//1976OxOB,0x54,0x52,//19770x0B,0x6A,0x47,//19780x69,0x6d,0x3C,//19790x09,Ox5B,0x50,//19800x04,0x9B,0x45,//19810x4A,0x4B,0xB9,//19820x0A,0x4B,0x4d,//19830xAB,0x25,0xC2,//19840x06,0xA5,0x54,//19850x06,0xd4,0x49,//19860x6A,0xdA,0x3d,//19870x0A,0xB6,0x51,//19880x09,0x37,0x46,//19890x54,0x97,OxBB,//19900x04,0x97f0x4fr//19910x06,0x4B,0x44,//19920x36,OxA5,0x37,//19930x0e,0xA5,0x4A,//19940x86,0xB2,0xBf,//19950x05,Ox AC,0x53,//19960x0A,0xB6,0x47,//19970x59,0x36,OxBC,//19980x09,Ox2e,0x50,//19992940x00,0x96,0x45,//20002970x4d,0x4A,0xB8,//20010x0d,0x4A,0x4C,//20020x0d,0xA5,0x41,//20030x25,0xAA,0xB6,//20040x05,0x6A,0x49,//20050x7A,0xAd,0xBd,//20060x02,Ox5d,0x52,//20070x09,Ox2d,0x47,//20080x5Cr0x95,0xBA,//20090x0A,0x95,0x4e,//20100x0B,0x4A,0x43,//20110x4B,0x55,0x37,//20120x0A,0xd5,0x4A,//20130x95,0x5A,0xBf,//20140x04,OxBA,0x53,//20150x0A,0x5B,0x48,//20160x65,0x2B,0xBC,//20170x05,Ox2B,0x50,//2018OxOA,0x93,0x45,//20190x47,0x4A,0xB9,//20200x06,0xAA,0x4C,//20210x0A,0xd5,0x41,//20220x24,0xdAt0xB6,//20230x04,0xB6,0x4A,//20240x69,0x57,0x3d,//20250x0A,0x4e,0x51,//2026OxOd,0x26,0x46,//20270x5e,0x93,0x3A,//20280x0d,0x53,0x4d,//20290x05,Ox AA,0x43,//20300x36,OxB5,0x37,//20310x09,0x6d,0x4B,//20320xB4,0xAe,0xBf,//20330x04,Ox Ad,0x53,//20340x0A,0x4d,0x48,//20350x6d,0x25,0xBC,//2036OxOd,0x2510x4fr//2037OxOd,0x52,0x44,//20380x5dQxAA,0x38,//2039OxOB,0x5A,0x4C,//20400x05,0x6d,0x41,//20410x24,OxAd,0xB6,//20420x04,0x9B,0x4A,//20430x7A,0x4B,0xBe,//20440x0A,0x4B,0x51,//20450x0A,0xA5,0x46,//20460x5B,0x52,0xBA,//20470x06,Oxd2,0x4e,//20480x0A,0xdA,0x42,//20490x35,0x5B,0x37,//20500x09,0x37,0x4B,//20510x84,0x97,OxC1,//20520x04,0x97,0x53,//20530x06,0x4B,0x48,//20540x66,0xA5,0x3C,//20550x0e,0xA5,0x4f,//20560x06,OxB2,0x44,//20570x4A,0x36,0x38,//20580x0A,0xAe,0x4C,//20590x09,Ox2e,0x42,//20600x30,0x97,0x35,//20610x00,0x96,0x49,//20620x7d,0x4A,0xBd,//20630x0d,0x4A,0x51,//20640x0d,0xA5,0x45,//20650x55,0xAA,0xBA,//20660x05,0x6A,0x4e,//20670x0A,0x6d,0x43,//20680x45,0x2e,0xB7,//20690x05,0x2d,0x4B,//20700x8A,0x95,0xBf,//2071OxOA,0x95,0x53,//20720x0B,0x4A,0x47,//20730x6B,0x55,0x3B,//20740x0A,0xd5,0x4f,//20750x05,0x5A,0x45,//20760x4A,0x5d,0x38,//20770x0A,0x5B,0x4C,//20780x05,Ox2B,0x42,//20790x3A,0x93,0xB6,//20800x06,0x93,0x49,//20810x77,0x29,OxBd,//20820x06,OxAA,0x51,//20830x0A,0xd5,0x46,//20840x54,0xdA,0xBA,//20850x04,0xB6,0x4e,//20860x0A,0x57,0x43,//20870x45,0x27,0x38,//20880x0d,0x26,0x4A,//20890x8e,0x93,0x3e,//2090OxOd,0x52,0x52,//20910x0d,0xAA,0x47,//20920x66,0xB5,0x3B,//20930x05,0x6d,0x4f,//20940x04,OxAe,0x45,//20950x4A,0x4e,0xB9,//20960x0A,0x4d,0x4C,//2097OxOd,0x15,0x41,//20980x2d,0x92,0xB5,//2099};sbitRST=P1A0;sbitkl=P1A4;sbitk2=P3A5;sbitk3=P3A4;sbitk4=P3A0;sbitk5=P3A1;sbit soundOn=P1A7;int timeCount=0;int AlarmSwitch=0;int flag=0;int SoundFlag=0;int TimeSwitch=1;//月份数据表code ucharday_code1
[9]={0x0,Ox1f,0x3b,0x5a,0x78,0x97,Oxb5,0xd4,0xf3};code uint day_code2
[3]={0x111,0x130,0x14e};timerOf interrupt1{//定时器中断THO=-2000/256;TLO=-2000%256;ifTimeSwitch{timeCount++;ifSoundFlag{soundOn=IsoundOn;Delayms1;}iftimeCount==500{TimeUpdatef;timeCount^O;Sound;}}//timerO voidSound{//判断是否到达所设置的闹钟时间if!SoundFlagAlarmSwitch==1Time[O]==Alarm[O]Time
[1]==Alarm
[1]Time
[3]==Alarm
[3]Time
[4]==Alarm
[4]Time
[6]==Alarm
[6]Time
[7]==Alarm
[7]{SoundFlag=1;}else ifSoundFlag{if!k5{T_delay;if!k5{SoundFlag=0;//Sound voidmain{//主函数int changeFlag=0;TMOD=0x01;THO=-2000/256;TLO=-2000%256;EA=1;ET0=1;TR0=1;LCM_Displni;window_now;while1{k1=k2=k3=k4=k5=1/changeFlag=0;if!k1{T_delay;if!k1{changeFlag=1;flag=O;}}else ifk2==0{T_delay;if!k2{changeFlag=1;flag=1;}}else ifk3==0{T_delay;if!k3{changeFlag=1;flag=2;ifchangeFlag{LCM_Displni;}switchflag{case0:window_now;break;case1:window alarmf;break;case2:window_search;break;default:break;//main void Delaymsfuint ms{〃延时程序fori=0;ims;i++[forj=0;j117;j++}//Delayms void T_delay{//延时以去抖Delayms30;}//T_delay void window_now{“第一个界面,当前日期与时间显示DateShowf;if!k4{T_delay;if!k4{TimeSwitch=0;TimeDateChanged;//013467}TimeShowf;}//window_now intJudgeRunuchar Year[]{〃判断平闰年,若为闰年,返回值为1,否则返回0int year=Year[O]-Oy WOO+Year
[1]-0*100+Year
[2]-,0*W+Year
[3]-O;ifyear%400==0Hyear%100!=0year%4==0{return1;}else{return0;}//JudgeRun void TimeDateChanged{//调整时间与日期uchari=1;while1{if!k4{T_delay;if!k4{TimeSwitch=1;break;}whilek4{TimeShowf;DateShowf;ifi=7{LCM_DispChar5,6+i;;DelaymsWO;LCM_DispChar5,6+i,Time[i];DelaymsIOO;if!k1{T_delay;if!k1{Time[i]++;ifTime[i]9,{Time[i]=O;Time[i-1]++;ifTime[i-1]5,{Time[i-1]=0;}else ifTime
[0]==2Time⑴==4{Time[i]=O;Time[i-1]=O;else if!k2{T_delay;if!k2{Time[i]-;ifTime[ikO{ifi!=1{Time[i]=9;Time[i-1]-;ifTime[i-1]0{Time[i-1]=5;}else ifTime[O]==O{Time⑴=3;Time
[0]=2;}else{Time
[1]=9;Time[O]-;else if!k3{T_delay;if!k3{i++;ifi==2II i==5{//01234567i=i+2;}}}else ifi=17{LCM_DispChar3,i-31;DelaymsWO;L CM_DispChar3,i-3,Date[i-8];DelaymsWO;if!k3{T_delay;if!k3{i++;ifi==12/li==15{i=i+2;ifi=11{if!k1{T_delay;Date[i-8]++;ifDate[i-8]9,{Date[i-8]=O;}else if!k2{T_delay;if!k2{Date[i-8]-;ifDate[i・8k0{Date[i-8]=9;}else ifi==14{//891011112j1314H15111617if!k1{T_delay;if!k1{Date
[6]-p+;ifDate
[6]9,{Date
[6]=O;ifDate
[5]==0{Date
[5]++;}}else ifDate
[6]2Date
[5]==1{Date
[6]=r;Date
[5]=O;}}else if!k2{T_delay;if!k2{Date
[6]-;ifDate
[6]1Date[5J==0{Date
[6]=2;Date
[5]=,1,;}else ifDate
[6]0Date
[5]==1{Date
[6]=9;Date
[5]=O;}}else ifi==17{if!k1{T_delay;if!k1{//0123456789Date
[9]++;if!Date
[6]==2Date
[5]==,0{ifDate
[9]9Date[8k=2{Date
[9]=O;Date
[8]++;}if{Date
[5]==0Date
[6]==1II Date
[6]==3II Date
[6]==5II Date
[6]==7II Date
[6]==8,H Date
[5]==TDate⑹==0//Date
[6]==2{ifDate
[9]1Date网==3{
一、实验内容用单片机实现万年历
二、实验要求1平时显示实时时钟与日历2输入任意日子可显示对应的星期和阴历3可设置的闹钟功能
三、实验器件DP-51PR
0.NET综合实验箱微机一台Keil软件
四、设计任务分析本实验是基于51单片机的电子万年历的设计,其中包括当前时间与日期的显示,当前时间与日期的调整,闹铃的设置,任意日期的阴历查询以及星期查询的功能可以依据功能,将显示分为三个界面,分别为当前时间与日期显示界面,闹铃设置界面,综合查询界面,可通过三个按键进行切换,按键时需要软件“去抖”显示器件为型号为LCM12864的LCD液晶显示屏具体实现过程如下Date
[9]=1;Date
[8]=O;}else{ifDate
[9]0Date
[8]==,3,{Date[9J=T;Date
[8]=O;}ifDate
[5]==0Date
[6]==,2{ifDate
[8]=1Date
[9]9{Date
[8]++;Date
[9]=O;}ifDate
[8]==2{ifDate
[9]9JudgeRunDate{Date
[8]=O;Date
[9]=T;else ifDate
[9]8!JudgeRunDate{Date
[8]=O;Date
[9]=T;}}else if!k2{T_delay;if!k2{//0123456789Date
[9]-;if!Date
[6]==,2Date
[5]==,0{ifDate
[9]0Date
[8]=1{Date
[9]=9;Date
[8]-;ifDate
[5]==,0Date
[6]==,11II Date
[6]==3II Date
[6]==5II Date
[6]==T II Date
[6]==,8,H Date
[5]==TDate
[6]==0H Date
[6]==2{ifDate
[9]0Date
[8]==0{Date
[9]=r;Date
[8]=3;}}else{ifDate
[9],0,Date
[8]==0,{Date
[9]=0;Date
[8]=3;ifDate
[5]==0Date
[6]==2{ifDate
[8]=,1,Date
[9],0,{Date
[8]-;Date
[9]=9;}ifDate
[8]==0{ifDate
[9]=0JudgeRunDate{Date
[8]=2;Date
[9]=9;}else ifDate
[9]=0iJudgeRunDate{Date
[8]=2;Date
[9]=8;}}else{i=1;}}}//TimeDateChanged void window_alarm{//闹钟显示界面AlarmShowf;if!k4{T_delay;if!k4{AlarmChanged;}}//window_alarm void AlarmChanged{//调整闹铃时间uchari=1;while1{if!k4{T_delay;if!k4{break;whilek4{AlarmShow;if!k5{T_delay;if!k5{Alarm Switch=1-AlarmSwitch;LCM_DispChar3,6+i;DelaymsWO;LCM_DispChar3,6+i,Alarm[i];DelaymsIOO;if!k1{T_delay;Alarm[i]++;Alarmfi^O1;Alarm[i-1]-F-F;Alarm[i-1]=O;else ifAlarm[O]==2Alarm
[1]==4{Alarm[i]=O;Alarm[i-1]=O;}}else if!k2{T_delay;if!k2{Alarm卜;ifAlarm[i]O{Alarm[i]=9;ifAlarm[i・1k0{Alarm[i-1]=,5,;}else ifTime[O]==O{Alarm
[1]=3;Alarm⑼=2;}else{Alarm
[1]=9;Alarm[O]-;T_delay;if!k3{i++;ifi!=1i!=4i!=7{//01234567i++;}else{i=1}//AlarmChanged void window_search{//闹钟显示界面SearchShowQ;T_delay;if!k4{SearchDateChangedf;}//window_search voidSearchShow{//显示查询界面内容uchar i,j;int year;LCM DispStr0,2,Search Window;LCM_DispStr2,0,nInput yourdate:;fori=0;i10;i++{LCM_DispChar3,4-t-i,lnput[i];forj=0;j9;j++{LCM_DispChar5,j+6,Week[Judge WeekInput-1][j];LCM_DispStr6,0,Lunar:;year=lnput[O]-OT1000+lnput
[1]-OyiOO+lnput
[2]-OyiO+lnput
[3]-O;iffyear1901//year2099{L CM_DispStr7,4,Wronginput;}else{LunarConversionlnput;forj=0;j10;j++{LCM_DispChar7,4+j,Lunar[j];}//SearchShow void SearchDateChanged{//输入需要查询的时间uchari=0;while1{if!k4{T_delay;if!k4{TimeSwitch=1;break;whilek4{SearchShowf;ifi=9{//0123456789LCM_DispChar3,4+i,;DelaymsIOO;LCM DispChar3,4+i,lnput[i];DelaymsWO;if!k3{T_delay;if!k3{i++;ifi==4Hi==7{i=i+2;ifi=3{if!k1{T_delay;if!k1{lnput[i]++;iflnput[i]9{lnput[i]=O;}else if!k2{T_delay;if!k2{lnput[i]-;lnput[i]=9;}}}else ifi==6{//891011/12/1314H15111617T_delay;lnput
[6]++;iflnput
[6]9,{lnput
[6]=O;iflnput
[5]==O{lnput
[5]++;}else iflnput
[6]2,lnput
[5]==,1{lnput
[6]=T;lnput
[5]=O;}}else if!k2{T_delay;if!k2{lnput
[6]-;iflnput
[6]1lnput
[5]==0{lnput
[6]=2;lnput
[5]=1}else iflnput[6k lnput
[5]==1{lnput
[6]=9;lnput
[5]=O;else ifi==9{if!k1{T_delay;if!k1{//0123456789lnput
[9]-F+;if!lnput
[6]==2lnput
[1]==,O{iflnput
[9]9lnput
[8]=2{Inputl^O;lnput
[8]++;if{lnput
[5]==0lnput
[6]==1H lnput
[6]==3H lnput
[6]==5II Inputiei^T II lnput
[6]==8H lnput
[5]==1lnput
[6]==O IIlnput
[6]==2{iflnput
[9]1lnput网==3{lnput
[9]=T;mput
[8]=O;}}else{iflnput
[9]0lnput
[8]==,3{lnput
[9]=T;lnput
[8]=O;iflnput
[5]==0lnput
[6]==2,{iflnput
[8]=1lnput
[9]9{lnput
[8]++;lnput
[9]=O;}iflnput
[8]==2{iflnput
[9]9JudgeFunlnput{lnput
[8]=O;lnput
[9]=1;}else iflnput
[9]8!JudgeRunlnput{lnput
[8]=O;lnput
[9]=T;else if!k2{T_delay;if!k2{//0123456789lnput
[9]-;if!lnput
[6]==2lnput
[1]==O{iflnput
[9]0lnput
[8]=,1{lnput
[9]=9;lnput
[8]-;}iflnput
[5]==0lnput
[6]==11II lnput
[6]==3II lnput
[6]==5II lnput
[6]==T IIlnput
[6]==,8H lnput
[5]==1lnput⑹==0//lnput
[6]==2{iflnput
[9],0lnput
[8]==,0{lnput
[9]=1;Input网=3;}}else{iflnput
[9],0,lnput
[8]==,0,{lnput
[9]=O;Input网=3;}iflnput
[5]==0lnput
[6]==2{iflnput
[8]=ra lnput
[9]0{lnput
[8]-;lnput
[9]=9;}iflnput
[8]==0{iflnput
[9]=0JudgeRunlnput{lnput
[8]=2;lnput
[9]=9;}else iflnput
[9]=0IJudgeFlunlnput{lnput
[8]=2;lnput
[9]=8;}else{i=0;}}}//SearchDateChanged voidTimeUpdate{//进行时间更新Time
[7]++;ifTime
[7]9乂Time
[7]=,0,;Time
[6]++;ifTime
[6]5,{Time
[6]=O;Time
[4]++;ifTime
[4]9{Time
[4]=O;Time
[3]-k+;ifTime
[3]5,{Time
[3]=O;Time
[1]++;ifTime
[1]9Time
[0]==1,}HTime
[1]3,Time
[0]==2,{Time
[1]=O;Time⑼++;ifTime
[0]2{Time⑼DateUpdatef;}//hour_shi}//hour_ge}//min_shi}//min_ge}//sec_shi}//sec_ge}//TimeUpdate voidTimeShow{//显示时间在界面上uchar i;LCM_DispStr0,4,NOW TIME;LCM_DispStr4,1,Time:n;fori=0;i8;i++{LCM_DispChar5,6+i,Time[i];}//TimeShow voidDateUpdate{//进行日期更新Date
[9]++;if!Date
[6]==2Date
[5]==0,{ifDate
[9]9Date
[8]=2,{Date
[9]=;Date
[8]++;if{Date
[5]==0Date
[6]==1,II Date
[6]==3H Date
[6]==5IIDate
[6]==TII Date
[6]==8H Date
[5]==1Date
[6]==OH Date
[6]==2{ifDate
[9]1Date
[8]==3{Date
[9]=r;Date
[8]=5Date
[6]+-p;ifDate
[6]9Date
[5]==O{Date
[6]=O;Date
[5]++;}else ifDate
[6]2Date
[5]==1{Date
[6]=T;Date
[5]=O;Date[3J++;ifDate
[3]9{Date
[3]=O;Date
[2]-p+;ifDate
[2]9,{Date
[2]=O;Date
[1]++;ifDate
[1]9,{Date
[1]=5Date[O]++;}else{ifDate
[9]0Date
[8]==3{Date
[9]=1;Date
[8]=O;
五、具体实现过程可以依据功能,将显示分为三个界面,分别为当前时间与日期显示与设置界面,闹铃设置界面,综合查询界面由于LCM12864的配置文件中自带一个函数LCM_DispStr,可以直接将指定字符串显示于指定行列,故为了方便起见,也为了减少变量,将本实验中所需的时间与日期全部定义为字符串形式事实证明,这样反而加大了程序代码的冗余
(一)、当前时间与日期显示与设置本界面中包含当前的时间与日期显示及设置功能,为主界面,即初始界面
1、当前时间与日期显示由于时间具有同步性,故时间应该是可以动态刷新的,又为了不被其它功能影响计时的准确性,可以用一个定时器中断予以实现采用定时方式1,由于定时器无法计时1S,故可以设置一个变量从而使其为2ms*500,不太清楚具体晶振频率,取TH=-2000/256,TL=-2000%256,即作12MHz处理,经测试平均约每分钟2s的误差之所以设置值不大,也是为了后期的闹铃部分的闹钟能稍微响亮一些同时每次更新完时间后,若秒钟达到了60秒,则会引起相应的时间甚至日期的进位同时在日期的进位中,需要注意的是平闰年的2月只有28/29天,以及大月31天与小月30天
2、当前时间与日期修改Date
[6]-h+;ifDate
[6]9Date
[5]==O{Date
[6]=O;Date
[5]++;NDate⑸==0Date⑹==2{ifDate
[8]=1Date[9J9{Date
[8]++;Date
[9]=O;ifDate
[8]==2{ifDate
[9]9JudgeRunDate{Date
[8]=O;Date
[9]=,1,;Date
[6]++;}else ifDate
[9]8!JudgeRunDate{Date
[8]=O1;Date
[9]=T;Date
[6]++;}//DateUpdate voidDateShow{//显示日期在界面上uchar i;LCM^DispStr2,l/Date:;fori=0;i10;i++{LCM_DispChar3,5+i,Date[i];}}//DateShow voidAlarmShow{//显示闹钟页面在界面上uchar i;LCM_DispStr0,2,Alarm Window;LCM_DispStr2,0,Setting Time:;LCM_DispStr5,0,Switch:;ifAlarmSwitch==1{LCM_DispStr5,8,On;LCM_DispChar5,10,;}else{LCM_DispStr5,8Off;fori=0;i8;i++{LCM_DispChar3,6+i,Alarm];}}//AlarmShow int JudgeWeekfuchar Year[]{//0123456789〃判断星期几int year=Year[O]-Oyi000+Year
[1]-OyiOO+Year
[2]-,0,*10+Year
[3]-O;int month=Year
[5]-0,*10+Year⑹,O;int day=Year
[8]-0yi0+Year⑼-⑺;int WhichDay;int y=0;int i;fori=1;i=month;i++{ifi==2/I i==4II i==6//i==8//i==9///==11{}else ifi==3{ifJudgeRun lnput{y+=29;}else{y+=28;}}else ifi==1{y+=day;}else{y+=30;WhichDay=year-1+year-1/4-year-1/100+year-1/400+y;ifWhichDay%7==0{return7;else{return WhichDay%7;}}//JudgeWeek int LunarBigOrSmallfuchar month_n,uint table_addr{//判断table_addr所对应年的month_n月是否为大月“若大月,返回1,否则,返回0uchar temp;switchmonth_n{case1:{temp=year_code[table_addr]0x08;if temp==OreturnO;else return1;}case2:{temp=year_code[table_addr]0x04;if temp==OreturnO;else return1;}case3:{temp=year_code[table_addr]0x02;if temp==OreturnO;else return1;}case4:{temp=year_code[table__addr]0x01;if temp==OreturnO;else retum1;}case5:{temp=year_code[table_addr-F1]0x80;if temp==O returnO;else return1;}case6:{temp=year_code[table_addr+1]0x40;if temp==OreturnO;else return1;}case7:{temp=year_code[table_addr-i-1]0x20;if temp==OreturnO;else return1;}case8:{temp=year_code[table_addr+1]0x10;if temp==OreturnO;else return1;}case9:{temp=year_code[table_addr+1]0x08;if temp==OreturnO;else return1;}case10:{temp=year_code[table_addr+1]0x04;if temp==OreturnO;else return1;}case11:{temp=year_code[table_addr+1]0x02;if temp==OreturnO;else return1;}case12:{temp=year_code[table_addr+1]Ox01;if temp==OreturnO;else return1;}case13:{temp=year_code[table_addr+2]0x80;if temp==OreturnO;else return1;}}}//LunarBigOrSmall voidLunarConversionuchar Year[]{//阳历转阴历intyear=Year⑼-0*1000+Year⑴-0*100+Year[2卜0*10+Year
[3]-O;int month=Year
[5]-0,*10+Year
[6]-O;intday=Year
[8]-0yW+Year⑼,0;uchar c=year20001:0;〃若为
2、世纪,则为0,否则为1uchar temp1,temp2,temp3,month_p;uint temp4,table_addr;bit flag2,flag_y;year=year%100;temp1=month/16;temp2=month%16;month=temp V10+temp2;temp1=day/16;temp2=day%16;day=temp V10+temp2;ifc==O//定位数据表地址{table_addr=year+0x64-1*0x3;}else{table_addr=year-1*0x3;}〃定位数据表地址完成//取当年春节所在的公历月份temp1=year_code[table_addr+2]0x60;temp1=_cror_temp1,5;〃取当年春节所在的公历月份完成“取当年春节所在的公历口temp2=year_code[table_addr+2]Ox1f;//取当年春节所在的公历日完成//计算当年春年离当年元旦的天数,春节只会在公历1月或2月iftemp1==0x1{temp3=temp2-1;}else{temp3=temp2+0x1f-1;}//计算当年春年离当年元旦的天数完成〃计算公历日离当年元旦的天数,为了减少运算,用了两个表//day_code1
[9],day_code2
[3]//如果公历月在九月或前,天数会少J-Oxff,用表day_code1
[9],〃在九月后,天数大于Oxff,//JXday_code2
[3]〃如输入公历日为8月10日,则公历日离元旦天数为day_code1[8-1]+10-1如输入公历日为11月10日,则公历日离元旦天数为day_code2[11-10卜10-1if month10temp4=day_code1[month-1]+day-1;}else{temp4=day_code2[month-10]+day-1;if JudgeRunlnput{“加果公历月大于2月并且该年的2月为闰月,天数加1temp4+=1;“计算公历日离当年元旦的天数完成//判断公历日在春节前还是春节后if temp4=temp3{“公历日在春节后或就是春节当日使用下面代码进行运算temp4-=temp3;month=0x1;month_p=0x1;//monthj为月份指向,公历日在春节前或就是春节当H month_p指向首月flag2=LunarBigOrSmallmonth_p,table_addr;〃检查该农历月为大小还是小月,大月返回1,小月返回0flag_y=O;ifflag2==0temp1=0x td;〃小月29天else tempi=0x1e;“大小30天temp2=year_code[table_addr]OxfO;temp2=_cror_temp2,4;U从数据表中取该年的闲月月份,如为0则该年无闲月whiletemp4=temp1{temp4~=temp1;month_p+=1;ifmonth==temp2{flag_y=-flag_y;ifflag_y==O month+=1;}else month+=1;flag2=LunarBigOrSmallmonth_p,table_addr;ifflag2==0temp1=0x1d;else tempi=0x1e;}day=temp4+1;}else{〃公历日在春节前使用下面代码进行运算temp3-=temp4;if year==OxO{year=0x63;c=1;}else year-=1;table_addr-=0x3;month=Oxc;temp2=year_code[table_addr]OxfO;temp2=_cror_temp2,4;if temp2==0month_p=Oxc;else month_p=Oxd;//rmonth_p为月份指向,如果当年有闰月,一年有十三个月,月指向13,无闰月指向12*/flag_y=O;flag2=LunarBigOrSmallmonth_p,table_addr;ifflag2==0temp1=0x1d;else tempi=0x1e;whiletemp3temp1{temp3-=temp1;month_p-=1;ifflag_y==0month-=1;ifmonth==temp2flag_y=-flag_y;flag2=LunarBigOrSmallmonth_p,table_addr;ifflag2==0temp1=0x1d;else tempi=0x1e;day=temp1-temp3+1;ifc==O{Lunar[O]=2;Lunar
[1]=O;}else ifc==1{Lunar[O]=T;Lunar
[1]=9;Lun ar
[2]=year/10+O;Lunar
[3]=year%70+O;Lunar
[5]=month/10+O;Lunar
[6]=month%10+O;Lunar
[8]=day/10+O;Lunar
[9]=day%10+O;]//LunarConversion在此过程中,需要有按键可以进入修改界面,以及退出界面,同时,在修改时需要移位以及数字的加减功能,为了方便表明修改的哪位,设置了一个周期约为
0.2s的闪烁功能另在修改时,由于时间与日期有最大值限制,需要设置一个允许修改的范围为了实用性,除年份可以4位都设置外,其它部分定义为只能设置个位,并因个位的变化而引起十位的进位或退位调整时,不再计时
(二)、闹铃设置本界面包括闹铃的时间显示与设置,以及闹铃的开关,闹铃的执行
1、闹铃时间设置闹铃的时间设置类似于主界面中的时间设置功能,不同的是,增加了在每次时间更新后会与设定时间对比,若时间完全符合,且开关为On,即开启状态,会由定时器赋予蜂鸣器一个周期约为
0.2s的方波,从而使其发出声音,闹铃执行过程中,其它功能正常进行,不影响计时,按下指定键后闹铃停止
2、闹铃开关WWW闹铃的开关设置为仅可在设置闹铃时进行设置,其中闹铃的开关标识符为一个全局变量,可通过指定按键修改,显示界面中会根据全局变量的值显示闹铃的开关状态
(三)、综合查询
1、输入查询日期输入查询日期的过程与主界面中设置日期的过程类似,只是输入后会使查询的星期与阴历动态变化,而不需要确定键
2、显示查询的星期与阴历在输入查询的日期后,需要获得查询的星期儿可以通过在网上查询到的一个公式:W=Y-1+lY-1/4]-[Y-1/100J+[Y-1/400]+D其中Y是年份,D为累计的天数,然后W Mod7即是当前星期几,若为0,则为星期天,即Sunday阴历换算我确实不太懂,但经过网上搜索资料后,可以找到一个关于从1901年到2099年每年各阴历月份的大小,春节所在的公历以及有无闰月等的表,则可以通过累计日期求出农历的日期,为了方便,未采用传统的天干地支计法,而直接采用了数字计法
六、连线及实验配置准备
1、软件设置给出的拓展名.c的文件全部加入到Keil安装目录下的LIB文件夹里;给出的拓展名为.h的文件全部加入到INC文件夹里,并添加所有的c文件至工程中因为用到了外部I/O RAM,所以调试时,要开放系统总线点击工具栏的Project-Option fortarget targetl-debug-Settings,然后开放总线,即选择ALL BUS或者XBUS(推荐)
2、硬件连接a.将A2区J65的A0-A3分别连接到B3区J75的A0-A2及/CS b.将A2区J56的/WR、/RD分别连接到B3区J75的WR,WDO c.将A2区J51的P
1.0连接到B3区J75的RST d.将PL4,P
3.5,P
3.4,P
3.0,P
3.1分别连接至D1区的K1-K5,Pl.7连接至D4区的蜂鸣器
七、实验总结此次实验目的为设计一个电子万年历,并要求有一些指定功能经过了好几天的编程,最后能实现一个基本没BUG的作品,看见自己的万年历可以正常运行了,还是挺欣慰的通过这次实验给我最大的感受就是,不要着急写程序,架构最重要因为我图一时方便用了字符串存储日期与时间,致使后面的程序复杂了不少,虽然最后还是达到了一定的精确度,但是代码非常冗余如果开始架构好,完全可以用单纯的数字存储,并通过编写通用的子函数来大大简化函数如果在以后工作中,这点必须注意,不然代码维护性很差另外,在实验过程中,有一个花了不少时间的在于,我不太懂LCM的内部连接,并且执意不采用周立功键盘而自行采用普通按键,致使花了很长时间才找出了可以正常用于与单片机交互可输入的I/O口同时在实验中,我也学会了一些计算星期及阴历的算法,这样可以方便以后另外,还有点很重要,只要自己愿意花时间去研究,在复杂的问题都可以解决此次试验中,比较遗憾的一点,就是为图简单,未利用LCD的扫描函数,而使其完全为英文界面
八、程序代码Code:^include LCM_config.h^include intrins.h^define ucharunsigned char^define uintunsigned intvoidwindow_now;voidwindow_alarm;voidwindowsearchf;voidDelaymsfuintms;voidT_delay;void TimeUpdateQ;void TimeShowf;void DateUpdateQ;void DateShowf;void AlarmShowf;void SearchShowf;voidAlarmChanged;voidTimeDateChanged;voidSearchDateChanged;void Soundf;void LunarConversionfucharYear[];int JudgeRunfucharYear[];intJudgeWeekfucharYear[];intLunarBigOrSmallfucharmonth n,uint tableaddr;uchar Date[]=2014-07-10;uchar Time[]=12:15:00;ucharAlarm[]=13:27:40;uchar lnput[]=2014-07-09;uchar Lunar[]=2014-02-08;uchar codeWeek
[7]
[10]={Monday,Tuesday,Wednesday,Thursday Friday/Saturday n,Sunday);uchar codeyear_code[]={//1901-2099〃第一字节BIT7-4位我示闰月月份,值为为无闰月,//BIT3-0对应农历第1-4月的大小//第二字节BIT7-0对应农历第5-12月大小,//第三字节B/T7表示农历第13个月大小//月份对应的位为1表示本农历月大(3天\为表示小(29对//BIT6-5表示春节的公历月份,B/T4-0表示春节的公历口期0x04,OxAe,0x53,//19010OxOA,0x57,0x48,//190230x55,0x26,OxBd,//19036OxOd,0x26,0x50,//19049OxOd,0x95,0x44,//1905120x46,0xAA,0xB9,//1906150x05f0x6A,0x4d,//1907180x09,OxAd,0x42,//1908210x24,0xAe,0xB6,//19090x04,0xAe,0x4A,//19100x6A,0x4d,0xBe,//19110x0A,0x4d,0x52,//1912OxOd,0x25,0x46,//19130x5d,0x52,0xBA,//19140x0B,0x54,0x4e,//19150x0d,0x6A,0x43,//19160x29,0x6d,0x37,//19170x09,0x5B,0x4B,//19180x74,0x9B,0xC1,//19190x04,0x97,0x54,//19200x0A,0x4B,0x48,//19210x5B,0x25,0xBC,//19220x06,0xA5,0x50,//19230x06,0xd4,0x45,//19240x4A,0xdA,0xB8,//19250x02,0xB6,0x4d,//19260x09,0x57,0x42,//19270x24,0x97,0xB7,//19280x04,0x97,0x4A,//19290x66,0x4B,0x3e,//19300x0d,0x4A,0x51,//19310x0e,0xA5,0x46,//19320x56,0xd4,0xBA,//19330x05,0xAd,0x4e,//1934。