|
單片機:STC89C52RC 時鐘芯片:DS1302
測溫元件:DS18B20 顯示元件:LCD1602
信息保持:STC單片機內部EEPROM
作者:BrightBell 時間:2016年1月初
郵箱:brightbell@qq.com
備注:
1.DS1302沒有第二電源,掉電不走時,誤差 < 1s/5天
2.時間、背光開關時間、蜂鳴器整點報時時間、LCD背光亮度、
按鍵音皆可設置
3.長按KEY0馬上開/關LCD背光,長按KEY1進入系統設置界面,
長按KEY2進入時間設置界面
4.每3秒讀取一次DS18B20溫度
5.每一小時更新一次EEPROM中的時間信息,重新設置時間后馬
上更新
6.進行一次系統設置后,馬上更新EEPROM中的系統設置信息,
下次啟動時會先加載
正.jpg (561.51 KB, 下載次數: 239)
下載附件
2016-1-27 16:10 上傳
反.jpg (310.46 KB, 下載次數: 219)
下載附件
2016-1-27 16:10 上傳
視頻:
部分源文件預覽:(完整版可從附件下載)
- #ifndef _DS1302_H_
- #define _DS1302_H_
- void DS1302ByteWrite(unsigned char dat) //向DS1302寫入一個字節
- {
- unsigned char mask;
- for(mask=0x01; mask!=0; mask<<=1) //低位在先
- {
- if((mask&dat) != 0)
- DS1302IO = 1;
- else
- DS1302IO = 0;
- DS1302CK = 1;
- DS1302CK = 0;
- }
- DS1302IO = 1;
- }
- unsigned char DS1302ByteRead(void) //從DS1302讀取一個字節
- {
- unsigned char mask;
- unsigned char dat = 0;
- for(mask=0x01; mask!=0; mask<<=1)
- {
- if(DS1302IO != 0)
- dat |= mask;
- DS1302CK = 1;
- DS1302CK = 0;
- }
- return dat;
- }
- void DS1302SingleWrite(unsigned char reg, unsigned char dat) //寫入DS1302的某一寄存器
- {
- DS1302CE = 1;
- DS1302ByteWrite((reg<<1)|0x80);
- DS1302ByteWrite(dat);
- DS1302CE = 0;
- }
- unsigned char DS1302SingleRead(unsigned char reg) //讀取DS1302的某一寄存器
- {
- unsigned char dat;
- DS1302CE = 1;
- DS1302ByteWrite((reg<<1)|0x81);
- dat = DS1302ByteRead();
- DS1302CE = 0;
- return dat;
- }
- void DS1302BurstWrite(unsigned char *dat) //Brust模式寫入時間信息
- {
- unsigned char i;
- DS1302CE = 1;
- DS1302ByteWrite(0xBE);
- for(i=0; i<8; i++)
- {
- DS1302ByteWrite(dat[i]);
- }
- DS1302CE = 0;
- }
- void DS1302BurstRead(unsigned char *dat) //Brust模式讀出時間信息
- {
- unsigned char i;
- DS1302CE = 1;
- DS1302ByteWrite(0xBF);
- for(i=0; i<8; i++)
- {
- dat[i] = DS1302ByteRead();
- }
- DS1302CE = 0;
- }
- //欲寫入的是十進制的時間信息,不是BCD碼,已進行轉換
- struct TIME Bcd1302ToDec(struct TIME *time)
- {
- struct TIME dectime;
- dectime.year = (time->year >> 4) * 10;
- dectime.year = (time->year & 0x0F) + dectime.year;
- dectime.mon = (time->mon >> 4) * 10;
- dectime.mon = (time->mon & 0x0F) + dectime.mon;
- dectime.day = (time->day >> 4) * 10;
- dectime.day = (time->day & 0x0F) + dectime.day;
- dectime.hour = (time->hour >> 4) * 10;
- dectime.hour = (time->hour & 0x0F) + dectime.hour;
- dectime.min = (time->min >> 4) * 10;
- dectime.min = (time->min & 0x0F) + dectime.min;
- dectime.sec = (time->sec >> 4) * 10;
- dectime.sec = (time->sec & 0x0F) + dectime.sec;
-
- dectime.week = time->week & 0x0F;
-
- return dectime;
- }
- //獲取到的是十進制的時間信息,不是BCD碼,獲取后已進行轉換
- void GetRealTime(struct TIME *time) //獲取時間信息,并保存在時間結構體中
- {
- unsigned char buf[8];
- struct TIME temp;
- DS1302BurstRead(buf);
- temp.year = buf[6];
- temp.mon = buf[4];
- temp.day = buf[3];
- temp.hour = buf[2];
- temp.min = buf[1];
- temp.sec = buf[0];
- temp.week = buf[5];
-
- *time = Bcd1302ToDec(&temp); //將BCD碼轉為十進制
- }
- struct TIME DecToBcd1302(struct TIME *time)
- {
- struct TIME bcdtime;
- bcdtime.year = (time->year / 10 % 10) * 16;
- bcdtime.year = (time->year % 10) + bcdtime.year;
- bcdtime.mon = (time->mon / 10 % 10) * 16;
- bcdtime.mon = (time->mon % 10) + bcdtime.mon;
- bcdtime.day = (time->day / 10 % 10) * 16;
- bcdtime.day = (time->day % 10) + bcdtime.day;
- bcdtime.hour = (time->hour / 10 % 10) * 16;
- bcdtime.hour = (time->hour % 10) + bcdtime.hour;
- bcdtime.min = (time->min / 10 % 10) * 16;
- bcdtime.min = (time->min % 10) + bcdtime.min;
- bcdtime.sec = (time->sec / 10 % 10) * 16;
- bcdtime.sec = (time->sec % 10) + bcdtime.sec;
-
- bcdtime.week = time->week % 10;
-
- return bcdtime;
- }
- void SetRealTime(struct TIME *time) //通過時間結構體設置時間
- {
- unsigned char buf[8];
- struct TIME temp;
- temp = DecToBcd1302(time);
- buf[7] = 0;
- buf[6] = temp.year;
- buf[5] = temp.week;
- buf[4] = temp.mon;
- buf[3] = temp.day;
- buf[2] = temp.hour;
- buf[1] = temp.min;
- buf[0] = temp.sec;
- DS1302BurstWrite(buf);
- }
- void InitDS1302(void) //初始化DS1302
- {
- unsigned char dat;
- struct TIME eepromtime;
- DS1302CE = 0;
- DS1302CK = 0;
- dat = DS1302SingleRead(0);
- if((dat & 0x80) != 0) //檢測時間在掉電時是否停止過,停1走0,如果停過就從新寫入初始化時間
- {
- GetE2promTime(&eepromtime); //停止過,獲取EEPROM里的時間
- DS1302SingleWrite(7, 0x00); //撤銷保護
- SetRealTime(&eepromtime);
- }
-
- lcdShowStr(0, 0, "20 - -");
- lcdShowStr(3, 1, ": :");
- }
- void lcdShowWeek(unsigned char x, unsigned char y, unsigned char week)
- {
- unsigned char str[5];
- lcdShowStr(x-4, y, "week");
- str[0] = week % 10 + '0';
- str[1] = '\0';
- lcdShowStr(x, y, str);
- }
- void RefreshTime(struct TIME *time)
- {
- static unsigned char dayBF = 88;
- if(dayBF != time->day) //日期發生變化,更新年月日周
- {
- lcdShowNum(2, 0, time->year);
- lcdShowNum(5, 0, time->mon);
- lcdShowNum(8, 0, time->day);
- lcdShowWeek(15,0, time->week);
- dayBF = time->day;
- }
- lcdShowNum(1, 1, time->hour);
- lcdShowNum(4, 1, time->min);
- lcdShowNum(7, 1, time->sec);
- }
- void HourlyWork(struct TIME *time) //小時事件
- {
- static char hourBF = 88;
- static char lightlevelBF = 3;
- if(time->hour != hourBF) //時有變
- {
- if(time->hour==lcdlighton) //判斷是否有背光開關
- {
- lcdlight = 0;
- if(lightlevelBF != 0)
- lcdlightlevel = lightlevelBF;
- else
- lcdlightlevel = 4;
- }
- else if(time->hour==lcdlightoff) //判斷是否有背光開關
- {
- lcdlight = 1;
- lightlevelBF = lcdlightlevel;
- lcdlightlevel = 0;
- }
-
- if((time->hour>=ZDBSbegin)&&(time->hour<=ZDBSend))
- {
- if(hourlybuzz != 0) //整點報時開
- flagZD = 1;
- }
-
- SaveTimeToE2prom(time); //每小時更新EEPROM里的時間信息
-
- hourBF = time->hour; //更新備份值
- }
- }
- void LedWaterShow() //流水燈效果
- {
- static unsigned char ledshow = 0x01;
- static bit dir = 0;
- ledDB = ledshow;
- if(dir == 0)
- {
- ledshow = ledshow << 1;
- if(ledshow == 0x00)
- {
- dir = 1;
- ledshow = 0x40;
- }
- }
- else
- {
- ledshow = ledshow >> 1;
- if(ledshow == 0x00)
- {
- dir = 0;
- ledshow = 0x02;
- }
- }
- }
- /*******************************************************************************
- 補償值計算方法:當X秒后時間慢Y秒,則:實減=X/當前值;應減=實減-Y; 補償值=X/應減
- ********************************************************************************/
- void TimeBuChang(struct TIME *time)
- {
- static char flagBC = 0;
- static unsigned int BCcnt = 0;
- static struct TIME BCtime;
- if(flagBC != 0)
- {
- flagBC = 0;
- SetRealTime(&BCtime); //寫入上一秒時間,相當于減一秒
- }
-
- BCcnt++;
- if(BCcnt > secBuChang) //每X秒減1秒
- {
- timemenu = 88; //禁止時間更新
- BCcnt = 0;
- BCtime = *time; //備份上一秒時間
- flagBC = 1;
- timemenu = 0; //開時間更新
- }
- }
- void UpdateTime()
- {
- static unsigned char secBF = 88;
- static unsigned int ds18b20cnt = 0;
- struct TIME buftime; //從DS1302中讀取出來的值
- GetRealTime(&buftime);
- if(buftime.sec != secBF)
- {
- RefreshTime(&buftime);
- secBF = buftime.sec;
-
- ds18b20cnt++;
- if(ds18b20cnt > GetTempSpace)
- {
- ds18b20cnt = 0;
- RefreshTemp();
- }
-
- HourlyWork(&buftime);
- LedWaterShow();
-
- TimeBuChang(&buftime); //時間補償
- }
- }
- void RefreshTimeNow()
- {
- struct TIME buftime;
- GetRealTime(&buftime);
- lcdShowStr(0, 0, "20 - -");
- lcdShowStr(3, 1, ": :");
- lcdShowNum(2, 0, buftime.year);
- lcdShowNum(5, 0, buftime.mon);
- lcdShowNum(8, 0, buftime.day);
- lcdShowNum(1, 1, buftime.hour);
- lcdShowNum(4, 1, buftime.min);
- lcdShowNum(7, 1, buftime.sec);
- lcdShowWeek(15,0, buftime.week);
- if(hourlybuzz != 0)
- lcdShowImage(0, 1, image0, 0);
- else
- lcdShowStr(0, 1, " ");
- lcdShowImage(15, 1, image1, 1);
- }
- #endif
復制代碼 網盤下載:
游客,本帖隱藏的內容需要積分高于 1 才可瀏覽,您當前積分為 0
|
評分
-
查看全部評分
|