|
单片机: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中的系统设置信息,
下次启动时会先加载
视频:
部分源文件预览:(完整版可从附件下载)
- #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
|
评分
-
查看全部评分
|