|
電子萬年歷軟件程序。整個軟件程序分模塊編寫:
1.包含主程序模塊main.c
2.日歷時鐘程序模塊ds1302.c
3.年歷轉換程序模塊lunarc.c
4.鍵盤處理程序模塊keyinput.c
5.液晶顯示程序模塊12864.h
6.字模模塊model.h
WIN_20170116_112412.JPG (340.05 KB, 下載次數: 163)
下載附件
2017-1-16 11:25 上傳
0.png (33.88 KB, 下載次數: 171)
下載附件
2017-1-16 23:18 上傳
單片機主程序:
- #include <reg52.h>
- #include "12864.h"
- #include "model.h"
- #include "ds1302.h"
- #include "lunar.h"
- #include "keyinput.h"
- #define uchar unsigned char
- #define uint unsigned int
- #define NoUpLine 1
- #define UpLine 0
- #define NoUnderLine 1
- #define UnderLine 0
- #define FALSE 0
- #define TRUE 1
- uchar dispBuf[7];
- uchar T0_Count=0,Tmp_Count=0;
- bit T0_Flag,Tmp_Flag,Flash_Flag;
- SYSTIME sys; //系統日期
- SPDATE SpDat; //農歷日期
- bit Hour_Flag=TRUE,Min_Flag=TRUE,Sec_Flag=TRUE; //設置時間標志
- bit Year_Flag=TRUE,Mon_Flag=TRUE,Day_Flag=TRUE;
- uchar State_Set=0; //設置時、分、秒、日、月、年等狀態
- bit State_Flag=FALSE,Inc_Flag=FALSE,Dec_Flag=FALSE; //三個按鍵是否按下的標志
- uchar code Mon2[2][13]={0,31,28,31,30,31,30,31,31,30,31,30,31,
- 0,31,29,31,30,31,30,31,31,30,31,30,31};
- /*****************************LCD顯示函數******************************
- 入口參數:
- cDat: 要顯示的數
- X: 行數 0~7
- Y: 列數 0~127
- show_flag: 是否反白顯示,0反白,1不反白
- upline: 上劃線, 0表示帶上劃線
- underline: 下劃線, 0表示帶下劃線
- ***********************************************************************/
- void LCD_ShowTime(char cDat,uchar X,uchar Y,bit show_flag,bit up,bit under){
- uchar s[2];
- s[0]=cDat/10+'0';
- s[1]=cDat%10+'0';
- en_disp(X,Y,2,Asc,s,show_flag,up,under);
- }
-
- void Show_YMD(){ //年、月、日、星期、顯示函數
- uchar uiTempDat;
- uiTempDat=RDS1302(0x88|0x01);
- sys.cMon=((uiTempDat&0x1f)>>4)*10+(uiTempDat&0x0f);
- LCD_ShowTime(sys.cMon,2,5,Mon_Flag,NoUpLine,NoUnderLine);
- hz_disp(4,5,1,uMod[1],1,NoUpLine,NoUnderLine); //月
- Show16X32(2,27,ucNum3216[sys.cDay/10],Day_Flag); //日
- Show16X32(2,43,ucNum3216[sys.cDay%10],Day_Flag);
- hz_disp(6,8,2,ucLunar[13],1,UpLine,UnderLine);
- if(sys.cWeek==7)
- hz_disp(6,40,1,uMod[2],1,UpLine,UnderLine); //星期
- else
- hz_disp(6,40,1,ucLunar[sys.cWeek],1,UpLine,UnderLine); //星期
- LCD_ShowTime(20,0,9,1,UpLine,UnderLine);
- LCD_ShowTime(sys.cYear,0,25,Year_Flag,UpLine,UnderLine);
- hz_disp(0,41,1,uMod[0],1,UpLine,UnderLine); //年
- SpDat=GetSpringDay(sys.cYear,sys.cMon,sys.cDay); //獲得農歷
- if(SpDat.cMon==1) //顯示農歷月
- hz_disp(4,64,1,ucLunar[15],1,UpLine,NoUnderLine); //"正"
- else if(SpDat.cMon==11)
- hz_disp(4,64,1,ucLunar[16],1,UpLine,NoUnderLine); //"冬"
- else if(SpDat.cMon==12)
- hz_disp(4,64,1,ucLunar[17],1,UpLine,NoUnderLine); //"臘"
- else
- hz_disp(4,63,1,ucLunar[SpDat.cMon],1,UpLine,NoUnderLine); //"二"~"十"
- if(SpDat.cDay/10==1 && SpDat.cDay%10>0) //顯示"十" 例如"十四"而不是"一四"
- hz_disp(4,95,1,ucLunar[10],1,UpLine,NoUnderLine);
- else if(SpDat.cDay/10==2 && SpDat.cDay%10>0) //顯示"廿" 例如"廿三"而不是"二四"
- hz_disp(4,95,1,ucLunar[19],1,UpLine,NoUnderLine);
- else
- hz_disp(4,95,1,ucLunar[SpDat.cDay/10],1,UpLine,NoUnderLine); //正常數字
- if(!(SpDat.cDay%10)) //"十"
- hz_disp(4,111,1,ucLunar[10],1,UpLine,NoUnderLine);
- else //正常數字
- hz_disp(4,111,1,ucLunar[SpDat.cDay%10],1,UpLine,NoUnderLine);
- hz_disp(0,104,1,SX[(uint)(2000+SpDat.cYear)%12],1,UpLine,UnderLine); //生肖
- hz_disp(2,95,1,TianGan[(uint)(2000+SpDat.cYear)%10],1,NoUpLine,NoUnderLine); //天干
- hz_disp(2,111,1,DiZhi[(uint)(2000+SpDat.cYear)%12],1,NoUpLine,NoUnderLine); //地支
- }
- void LCD_ShowWNL(){ //萬年歷顯示函數
- LCD_ShowTime(sys.cSec,6,111,Sec_Flag,UpLine,UnderLine); //秒,每秒鐘刷新
- if(!sys.cSec || State_Set) //分,普通模式每分鐘刷新
- LCD_ShowTime(sys.cMin,6,87,Min_Flag,UpLine,UnderLine); // 設置模式每次刷新
-
- if(!sys.cSec && !sys.cMin || State_Set) //時,普通模式每小時刷新
- LCD_ShowTime(sys.cHour,6,63,Hour_Flag,UpLine,UnderLine); // 設置模式每次刷新
-
- if(!sys.cSec && !sys.cMin && !sys.cHour || State_Set ){ //公歷農歷的年、月、日、星期
- Show_YMD(); //普通模式每天刷新
- if(State_Set==7) State_Set=0; //設置模式每次刷新
- }
- }
- void CAL_Init(){ //日期初始化函數
- sys.cYear=0x13; //BCD碼表示的日歷時間值
- sys.cMon=0x06;
- sys.cDay=0x030;
- sys.cHour=0x23;
- sys.cMin=0x59;
- sys.cSec=0x55;
- sys.cWeek=GetWeekDay(sys.cYear,sys.cMon,sys.cDay);
- }
- void SFR_Init(){ //定時器1初始化函數
- Flash_Flag=FALSE;
- TMOD=0x11;
- ET1=1;
- TH1= (-10000)/256;
- TL1= (-10000)%256;
- EA=1;
- }
- void GUI_Init(){ //LCD圖形初始化函數
- LCD12864_init();
- ClearLCD();
- Rect(0,0,127,63,1); //描繪框架
- Line(62,0,62,62,1);
- Line(0,48,127,48,1);
- Line(0,15,127,15,1);
- Line(24,15,24,48,1);
- Line(63,32,128,32,1);
- SetTime(sys); //設置時間
- GetTime(&sys); //獲得時間
-
- Show_YMD();
- LCD_ShowTime(sys.cSec,6,111,Sec_Flag,UpLine,UnderLine);
- en_disp(6,103,1,Asc,":",1,UpLine,UnderLine);
- LCD_ShowTime(sys.cMin,6,87,Min_Flag,UpLine,UnderLine);
- en_disp(6,79,1,Asc,":",1,UpLine,UnderLine);
- LCD_ShowTime(sys.cHour,6,63,Hour_Flag,UpLine,UnderLine);
- hz_disp(2,64,1,ucLunar[11],1,NoUpLine,NoUnderLine); //"農"
- hz_disp(2,80,1,ucLunar[12],1,NoUpLine,NoUnderLine); //"歷"
- hz_disp(4,79,1,uMod[1],1,UpLine,NoUnderLine); //"月"
- }
- void DecToBCD(){ //二-十進制轉換函數
- sys.cHour=(((sys.cHour)/10)<<4)+((sys.cHour)%10);
- sys.cMin=(((sys.cMin)/10)<<4)+((sys.cMin)%10);
- sys.cSec=((sys.cSec/10)<<4)+((sys.cSec)%10);
- sys.cYear=((sys.cYear/10)<<4)+((sys.cYear)%10);
- sys.cMon=((sys.cMon/10)<<4)+((sys.cMon)%10);
- sys.cDay=((sys.cDay/10)<<4)+((sys.cDay)%10);
- }
- void Time_Set(){ //時間設置函數
- if(State_Flag){ //設置鍵按下
- State_Flag=FALSE;
- State_Set++;
- if(State_Set==8) State_Set=0;
- }
- Hour_Flag=TRUE;Min_Flag=TRUE;Sec_Flag=TRUE;
- Year_Flag=TRUE;Mon_Flag=TRUE;Day_Flag=TRUE;
- switch(State_Set){ //設置類型
- case 0: //無設置
- break;
- case 1: //設置時
- Hour_Flag=FALSE;
- break;
- case 2: //設置分
- Min_Flag=FALSE;
- break;
- case 3: //設置秒
- Sec_Flag=FALSE;
- break;
- case 4: //設置天
- Day_Flag=FALSE;
- break;
- case 5:
- Mon_Flag=FALSE; //設置月
- break;
- case 6:
- Year_Flag=FALSE; //設置年
- break;
- case 7: //無動作,設置此值為讓"年"的反白消失。
- break;
- }
-
- if(Inc_Flag){ //加鍵被按下
- Inc_Flag=FALSE;
- switch(State_Set) {
- case 0:
- break;
- case 1: //小時加
- sys.cHour++;
- (sys.cHour)%=24;
- break;
- case 2: //分加1
- sys.cMin++;
- sys.cMin%=60;
- break;
- case 3: //秒加1
- sys.cSec++;
- sys.cSec%=60;
- break;
- case 4: //天加1
- (sys.cDay)=(sys.cDay%Mon2[YearFlag(sys.cYear)][sys.cMon])+1;
- break;
- case 5: //月加1
- sys.cMon=(sys.cMon%12)+1;
- break;
- case 6:
- sys.cYear++; //年加1
- sys.cYear=sys.cYear%100;
- break;
- }
- DecToBCD(); //轉為BCD數
- sys.cWeek=GetWeekDay(sys.cYear,sys.cMon,sys.cDay); //算出星期
- SetTime(sys); //存入DS1302
- }
- if(Dec_Flag){ //減鍵按下
- Dec_Flag=FALSE;
- switch(State_Set){
- case 0:
- break;
- case 1:
- sys.cHour=(sys.cHour+23)%24; //時減1
- break;
- case 2: //分減1
- sys.cMin=(sys.cMin+59)%60;
- break;
- case 3: //秒減1
- sys.cSec=(sys.cSec+59)%60;
- break;
- case 4: //天減1
- sys.cDay=((sys.cDay+Mon2[YearFlag(sys.cYear)][sys.cMon]-1)%Mon2[YearFlag(sys.cYear)][sys.cMon]);
- if(sys.cDay==0) sys.cDay=Mon2[YearFlag(sys.cYear)][sys.cMon];
- break;
- case 5: //月減1
- sys.cMon=(sys.cMon+11)%12;
- if(sys.cMon==0) sys.cMon=12;
- break;
- case 6: //年減1
- sys.cYear=(sys.cYear+99)%100;
- break;
- }
- DecToBCD();
- sys.cWeek=GetWeekDay(sys.cYear,sys.cMon,sys.cDay);
- SetTime(sys);
- }
- }
- void main(){ //主函數
- SFR_Init();
- CAL_Init();
- GUI_Init();
- TR1=1;
- while(1){
- GetTime(&sys); //獲得時間
- LCD_ShowWNL(); //顯示萬年歷
- Time_Set(); //時間設置
- }
- }
- void timer1() interrupt 3 { //定時器1中斷服務函數
- TH1= (-10000)/256;
- TL1= (-10000)%256;
- keyinput(); //讀取按鍵
- if (keyvalue&0x10){
- State_Flag=TRUE;
- keyvalue &= 0xef; //清鍵值,保證一直按下只執行一次按鍵動作。
- }
- if (keyvalue&0x20 ){ //加
- Inc_Flag=TRUE;
- keyvalue &= 0xdf; //清鍵值,保證一直按下只執行一次按鍵動作。
- }
- if (keyvalue&0x40){ //減
- Dec_Flag=TRUE;
- keyvalue &= 0xbf; //清鍵值,保證一直按下只執行一次按鍵動作。
- }
-
- }
復制代碼
0.png (69.53 KB, 下載次數: 162)
下載附件
2017-1-16 23:17 上傳
資料下載:
帶農歷的萬年歷.zip
(146.45 KB, 下載次數: 401)
2017-1-16 11:21 上傳
點擊文件名下載附件
萬年歷 下載積分: 黑幣 -5
|
評分
-
查看全部評分
|