基于51單片機的電子日歷+溫度顯示設計說明_第1頁
基于51單片機的電子日歷+溫度顯示設計說明_第2頁
基于51單片機的電子日歷+溫度顯示設計說明_第3頁
基于51單片機的電子日歷+溫度顯示設計說明_第4頁
基于51單片機的電子日歷+溫度顯示設計說明_第5頁
已閱讀5頁,還剩16頁未讀, 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

.圖2-8陽歷程序流程圖然后從DSl302中讀出數據,再經過處理后,送給顯示緩沖單元。圖2-8所示為陽歷程序流程圖,程序如下:#include<reg52.h>//#include"ds1302.h"#defineucharunsignedchar#defineuintunsignedint#defineSECOND0x80 //秒#defineMINUTE0x82 //分鍾#defineHOUR0x84 //小時#defineDAY 0x86 //天#defineMONTH0x88 //月#defineWEEK0x8a //星期#defineYEAR0x8c //年sbitDS1302_RST=P3^0;sbitDS1302_SCLK=P3^1;sbitDS1302_IO=P3^2;typedefstructsystime{ucharcYear;ucharcMon;ucharcDay;ucharcHour;ucharcMin;ucharcSec;ucharcWeek;}SYSTIME;voidDS1302_Write<ucharD>{uchari; for<i=0;i<8;i++>{ DS1302_IO=D&0x01;DS1302_SCLK=1;DS1302_SCLK=0;D=D>>1; } }ucharDS1302_Read<>{ucharTempDat=0,i;for<i=0;i<8;i++>{ TempDat>>=1; if<DS1302_IO>TempDat=TempDat|0x80;DS1302_SCLK=1;DS1302_SCLK=0;} returnTempDat;}voidWDS1302<ucharucAddr,ucharucDat> {DS1302_RST=0;DS1302_SCLK=0;DS1302_RST=1;DS1302_Write<ucAddr>; //地址,命令DS1302_Write<ucDat>; //寫1Byte數據DS1302_SCLK=1;DS1302_RST=0;}ucharRDS1302<ucharucAddr>{ucharucDat;DS1302_RST=0;DS1302_SCLK=0;DS1302_RST=1;DS1302_Write<ucAddr>; //地址,命令ucDat=DS1302_Read<>;DS1302_SCLK=1;DS1302_RST=0;returnucDat;}voidSetTime<SYSTIMEsys>{WDS1302<YEAR,sys.cYear>; WDS1302<MONTH,sys.cMon&0x1f>; WDS1302<DAY,sys.cDay&0x3f>; WDS1302<HOUR,sys.cHour&0xbf>; WDS1302<MINUTE,sys.cMin&0x7f>; WDS1302<SECOND,sys.cSec&0x7f>; WDS1302<WEEK,sys.cWeek&0x07>;}voidGetTime<SYSTIME*sys>{ ucharuiTempDat; uiTempDat=RDS1302<YEAR|0x01>; <*sys>.cYear=<uiTempDat>>4>*10+<uiTempDat&0x0f>;// uiTempDat=RDS1302<0x88|0x01>;// <*sys>.cMon=<<uiTempDat&0x1f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<0x88|0x01>; <*sys>.cMon=<<uiTempDat&0x1f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<DAY|0x01>; <*sys>.cDay=<<uiTempDat&0x3f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<HOUR|0x01>; <*sys>.cHour=<<uiTempDat&0x3f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<MINUTE|0x01>; sys->cMin=<<uiTempDat&0x7f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<SECOND|0x01>; sys->cSec=<<uiTempDat&0x7f>>>4>*10+<uiTempDat&0x0f>; uiTempDat=RDS1302<MONTH|0x01>; <*sys>.cMon=uiTempDat&0x17; uiTempDat=RDS1302<WEEK|0x01>; sys->cWeek=uiTempDat&0x07;}四、陰歷程序設計由于DS1302沒有陽歷計時功能,因此陰歷的計時與實現是要通過陽歷日期來推導。根據陽歷來推算陰歷日期,推算方法是,根據陽歷當前日期在一年中的天數來計算陰歷日期。陽歷一個月不是30天就是3l天<2月除外,閏年2月為29天,平年2月為28天>。陰歷一年有12個月或13個月<含閏月>,一個月為30天或29天。如果把一個只有29天的月稱為小月,用1為標志,把30天的月稱為大月,用0為標志,那么12位二進制就能表示一年12個月的大小。如果有閏月,則把閏月的月份作為一個字節的高4位,低4位表示閏月大小,大月低四位為0,小月為1。這樣一個字節就包含了所有閏月的信息。陰歷春節和陽歷元旦相差的天數也用一個字節表示。總共用1字節就可以存儲一年中任何一天陽歷和陰歷的對應關系的有關數據。按此方法,先要根據當前陽歷的日期,算出陽歷為該年中的第幾天。計算出當前陽歷日期為該年中的第幾天后,再減去陽歷該年春節和元旦的日差,如果夠減。則相減的結果就是陰歷在該年的總第幾天了。根據該數據就可以推算出具體的當前陰歷日期;如果不夠減,則表示當的陰歷年為陽歷年的前一年。這種情況下,當前陰歷日期會處于陰歷11月或12月,此時春節和元旦的日差減去前面計算出的當前陽歷日期在陽歷年為第幾天的數據。其結果表示當的陰歷日期離春節的天數。計算出的陽歷天數為該年的第幾天,存放在寄存器R2和R3中。計算出天數后,如果大于#FFH,則把#FFH存放在R2中,余值存放在R3中。也就是說在用寄存器R2和R3表示的天數信息中。R2充當主寄存器,數據先存滿R2,再存R3。整個轉換程序中,這里面的數據不能被覆蓋。R2減1個月天數R2減1個月天數夠減?下個月為閏月?減去閏月天數月加1R3=0?R2=R2+R3R3=0R2=0?月份為當前正在減的月份的前一個月的最后一天月份為當前正在減的月份,號數為R2的值YNYYNNYN程序入口圖2-9推算陰歷日期的程序流程圖計算出陽歷總天數后,就可以根據它來推算陰歷日期。推算方法是,先用總天數減去春節和元旦的日差,如果結果為1,則該天正好是春節<因為春節在元旦之后,在計算春節和幾旦的日差0時,假設元旦為0天,春節為M天,則日差為M。而前面計算的陽歷總天數是該天在該年中的第幾天,是以元旦為1而得到的,與計算春節和元旦日差的這種方法相比,其數值少了1。所以要在原來本應該以0作為該天就是春節的依據的基礎上加1,所以以1作為該天是春節的標志>。如果結果小于1,則陰歷應該是陽歷的前一年;如果結果大于1,說明陽歷和陰歷為同一年。圖2-9為由總天數推算出陰歷日期的程序流程圖。五、時間調整程序設計調整時間用3個調整按鈕,1個作為控制用,另外2個作為加和減用,分別定義為設置按鈕、加按鈕和減按鈕。在調整時間過程中,要調整的位與別的位應該有區別,所以增加了閃爍功能。時間調整程序程序流程圖如圖2-10所示。程序見附錄。開始開始設置鍵有效,進入時調整程序設置鍵有效,進入時調整程序等待按鍵程序加鍵有效減鍵有效小時加1小時減1控制鍵有效,進入秒調整程序等待按鍵程序加鍵有效減鍵有效秒加1秒減1控制鍵有效,進入月調整程序等待按鍵程序加鍵有效減鍵有效月加1月減1控制鍵有效,進入分調整程序等待按鍵程序加鍵有效減鍵有效分鐘加1分鐘減1控制鍵有效,進入日調整程序員等待按鍵程序加鍵有效減鍵有效日加1日減1控制鍵有效,進入年調整程序等待按鍵程序加鍵有效減鍵有效年加1年減1按鍵有效,跳出時間調整程序,進入主循環程序圖2-10時間調整程序程序流程圖2.4系統仿真本設計仿真采用Proteus電路仿真平臺,該軟件由Labcenter公司開發,是目前世界上最先進、最完整的嵌入式系統設計與仿真平臺,可以實現數字電路、模擬電路及微控制器系統與外設的混合電路系統的電路仿真、軟件仿真、系統協同仿真和PCB設計等功能,是目前唯一能夠對各種處理器進行實時仿真、調試與測試的EDA工具。圖2-11電路仿真圖Proteus7.4版本的電路仿真界面下搭建本設計電路,為了精簡電路設計,電路器件之間的連接采用網路標號,電路見圖2-11所示。然后加載程序的HEX文件,然后點擊仿真運行按鈕進入電路仿真狀態。仿真效果見圖2-12所示,系統通過在Proteus軟件仿真,模擬出了實際電路的運行效果,驗證了程序的正確性,達到了本設計的目的。圖2-12電路仿真效果總結本系統電路較為簡單,但軟件工作量較大。在系統軟件設計過程中,利用C語言編程,模塊化程序設計,由于程序率為復雜,數據處理指令較多,邏輯性強,對與軟件設計工作提出了較高要求。參考文獻[1]劉勇.數字電路[M].電子工業出版社,2006.156-169.[2]陳正振.電子電路設計與制作[J].廣西交通職業技術學院信息工程系,2007.[3]楊子文.單片機原理及應用[M].XX電子科技大學出版社,2006.[4]張毅剛.MCS-51單片機原理及應用[M].北京:教育出版社,2007.227-237.[5]周潤景,張麗娜.基于PROTEUS的電路及單片機系統設計與仿真[M].北京:北京航空航天大學出版社,2006.96-125.[6]楊將新,李華軍,劉東駿.單片機程序設計及應用從基礎到實踐[M].電子工業出版社,2006.4<3>:93一95.[7]林志琦,郎建軍.基于PROTEUS的單片機可視化軟硬件仿真[M].北京:北京航空航天大學出版社,2006.9<5>:45-51.[8]白駒珩,雷曉平.單片計算機及運用[M].電子科技大學出版社,2008.[9]ATMEL.HowtoCalculateTheCapacitorofTheResetInputofaC51Microcontroller.2003<9>.[10]ATMEL.8-bitMicrocontrollerwith4KBytesIn-SystemProgrammableFlashAT89S51.2002<12>.附錄程序清單#include<reg52.h>#include"12864.h"#include"model.h"#include"ds1302.h"#include"one-wire.h"#include"lunar.h"#include"input_080627.h"#defineucharunsignedchar#defineuintunsignedint#defineNoUpLine #defineUpLine #defineNoUnderLine1#defineUnderLine #defineFALSE #defineTRUEucharbdatagTmp;sbitt0=gTmp^0;sbitt1=gTmp^1;sbitt2=gTmp^2;sbitt3=gTmp^3;sbitt4=gTmp^4;sbitt5=gTmp^5;sbitt6=gTmp^6;sbitt7=gTmp^7;uchardispBuf[7];ucharT0_Count=0,Tmp_Count=0;bitT0_Flag,Tmp_Flag,Flash_Flag;SYSTIMEsys; //系統日期SPDATESpDat; //農歷日期//設置時間的標志bitHour_Flag=TRUE,Min_Flag=TRUE,Sec_Flag=TRUE;bitYear_Flag=TRUE,Mon_Flag=TRUE,Day_Flag=TRUE;ucharState_Set=0;//設置狀態<用來區分此時是在設置時,分,秒,日,月,年>bitState_Flag=FALSE,Inc_Flag=FALSE,Dec_Flag=FALSE; //用來標志三個按鍵是否按下。ucharcodeMon2[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};/*********************************************************** cDat: 要顯示的數 X: 行數0~7 Y:列數0~127 show_flag:是否反白顯示,0反白,1不反白 upline: 上劃線,0表示帶上劃線 underline:下劃線,0表示帶下劃線 返回:無************************************************************/voidLCD_ShowTime<charcDat,ucharX,ucharY,bitshow_flag,bitup,bitunder>{uchars[2];s[0]=cDat/10+'0';s[1]=cDat%10+'0';en_disp<X,Y,2,Asc,s,show_flag,up,under>;}/***********************************************************//函數名:Show_YMD<>//入口參數:void//出口參數:void//功能:顯示公歷與農歷的年、月、日、星期//說明:普通模式每天刷新一次// 設置模式每次循環刷新一次***********************************************************/voidShow_YMD<> //顯示年月日星期{ucharuiTempDat;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>; //星期日elsehz_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>; //"正"elseif<SpDat.cMon==11>hz_disp<4,64,1,ucLunar[16],1,UpLine,NoUnderLine>; //"冬"elseif<SpDat.cMon==12>hz_disp<4,64,1,ucLunar[17],1,UpLine,NoUnderLine>; //"臘"elsehz_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>;elseif<SpDat.cDay/10==2&&SpDat.cDay%10>0>//顯示"廿"例如"廿三"而不是"二四"hz_disp<4,95,1,ucLunar[19],1,UpLine,NoUnderLine>;elsehz_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>;//地支}/**************************************************************//函數名:LCD_ShowTemp<>//入口參數:void//出口參數:void//功能:采集溫度并顯示//說明:30秒更新一次***************************************************************/voidLCD_ShowTemp<>{uchardatTm[2];floattemp;ucharbuftmp;if<!Tmp_Flag>return;Tmp_Flag=FALSE;DS18B20_Init<>;DS18B20_RomCmd<0xcc>; //SkipRomcommand;Delay_Xms<20>;DS18B20_MemCmd<0x44>; //ConvertTcommand;DS18B20_Init<>;DS18B20_RomCmd<0xcc>;DS18B20_MemCmd<0xbe>;DS18B20_ReadDat<2,datTm>;gTmp=datTm[0];temp=<uchar>t0*0.0625+<uchar>t1*0.125+<uchar><t2>*0.25+<uchar><t3>*0.5;buftmp=<uchar><temp*10>;dispBuf[2]='.';dispBuf[3]=buftmp+'0';buftmp=<uchar>t4+<uchar>t5*2+<uchar>t6*4+<uchar>t7*8;gTmp=datTm[1];gTmp&=0x07;buftmp+=<gTmp*16>;dispBuf[0]=<buftmp/10>+'0';dispBuf[1]=<buftmp%10>+'0';dispBuf[4]=0xdf; //攝氏度;dispBuf[2]='C';en_disp<0,65,2,Asc,dispBuf,1,UpLine,UnderLine>;}/***********************************************************//函數名:LCD_ShowWNL<>//入口參數:void//出口參數:void//功能:顯示萬年歷//說明:***********************************************************/voidLCD_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;}}/***********************************************************//函數名:CAL_Init<>//入口參數:void//出口參數:void//功能:日期初始化//說明:星期通過計算得到***********************************************************/voidCAL_Init<>{sys.cYear=0x09;sys.cMon=0x05;sys.cDay=0x05;sys.cHour=0x10;sys.cMin=0x27;sys.cSec=0x00;sys.cWeek=GetWeekDay<sys.cYear,sys.cMon,sys.cDay>;}/***********************************************************//函數名:SFR_Init<>//入口參數:void//出口參數:void//功能:寄存器初始化//說明:定時器0控制溫度采集,定時器1控制按鍵掃描***********************************************************/voidSFR_Init<>{T0_Flag=FALSE;Tmp_Flag=TRUE;Flash_Flag=FALSE;TMOD=0x11;ET0=1;ET1=1;TH0=<-50000>/256;TL0=<-50000>%256;TH1=<-10000>/256;TL1=<-10000>%256;EA=1;}/***********************************************************//函數名:GUI_Init<>//入口參數:void//出口參數:void//功能:圖形界面初始化//說明:一些永遠不耍更新的圖形<如線條,"年"、"月"、"日"等>只是在初始化時寫入,中間過程不再更新。***********************************************************/voidGUI_Init<>{uinti,j;////////進入界面///////////LCD12864_init<>;ClearLCD<>;LCD_ShowTemp<>; //在顯示圖片之前啟動溫度轉換img12864_disp<uBmp>; //顯示圖片for<i=0;i<10;i++>for<j=0;j<32767;j++>;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>;Line<97,0,97,15,1>;//Line<24,15,24,48,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>; //"月"http:////////顯示初始化溫度//////en_disp<0,65,2,Asc,dispBuf,1,UpLine,UnderLine>;hz_disp<0,81,1,ucLunar[18],1,UpLine,UnderLine>;}/***********************************************************//函數名:DecToBCD<>//入口參數:void//出口參數:void//功能:把時間由10進制轉為BCD//說明:DS1302以BCD存儲***********************************************************/voidDecToBCD<>{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>;}/***********************************************************//函數名:Time_Set<>//入口參數:void//出口參數:void//功能:時間設置//說明:具體的時間設置***********************************************************/voidTime_Set<>{if<State_Flag> //設置鍵按下{State_Flag=FALSE;State_Set++;//State_Set%=7;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>//設置類型{case0://無設置break;case1: //設置時Hour_Flag=FALSE;break;case2: //設置分Min_Flag=FALSE;break;case3: //設置秒Sec_Flag=FALSE;break;case4: //設置天Day_Flag=FALSE;break;case5:Mon_Flag=FALSE;//設置月break;case6:Year_Flag=FALSE; //設置年break;case7: //無動作,設置此值為讓"年"的反白消失。break;}if<Inc_Flag> //加鍵被按下{Inc_Flag=FALSE;switch<State_Set>{case0:break;case1: //小時加sys.cHour++;<sys.cHour>%=24;break;case2: //分加sys.cMin++;sys.cMin%=60;break;case3: //秒加sys.cSec++;sys.cSec%=60;break;case4: //天加<sys.cDay>=<sys.cDay%Mon2[YearFlag<sys.cYear>][sys.cMon]>+1;break;case5: //月加sys.cMon=<sys.cMon%12>+1;break;case6:sy

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論