SDA=1;
else
SDA=0;
delayus
(1);
SCL=1;
数据位
delayus(5);
SCL=0;
//要传送的数据长度为8位
//判断发送位
//置时钟线为高,通知被控器开始接收
//保证时钟咼电平周期大于4阳
delayus
(2);
SDA=1;//8位发送完后释放数据线,准备接收应答位
delayus
(2);
SCL=1;
delayus(3);
if(SDA==1)
ack=0;
else
ack=1;//判断是否接收到应答信号
SCL=0;
delayus
(2);
}
ucharRcvByte()
{
ucharretc;
ucharBitCnt;
retc=0;
SDA=1;//置数据线为输入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
SCL=0;
delayus(5);
SCL=1;
delayus(3);
retc=retc<<1;
if(SDA==1)
retc=retc+1;
delayus
(2);
}
SCL=0;
delayus
(2);
return(retc);
}
//置时钟线为低,准备接收数据位
//时钟低电平周期大于4.7Q
//置时钟线为高使数据线上数据有效
//读数据位,接收的数据位放入retc中
voidAck_I2C(bita)
{
if(a==0)
SDA=0;
else
//在此发出应答或非应答信号
SDA=1;
SCL=1;
delayus(5);//时钟低电平周期大于4阴
SCL=0;//清时钟线,钳住I2C总线以便继续接收
delayus
(2);
}
ucharwrite_byte(ucharaddr,ucharwrite_data){
Start_I2C();
SendByte(DS3231_WriteAddress);
if(ack==0)
return0;
SendByte(addr);
if(ack==0)
return0;
SendByte(write_data);
if(ack==0)
return0;
Stop_I2C();
return1;
}
ucharread_current()
{
ucharread_data;
Start_I2C();
SendByte(DS3231_ReadAddress);
if(ack==0)
return(0);
read_data=RcvByte();
Ack_I2C
(1);
Stop_I2C();
returnread_data;
}
ucharread_random(ucharrandom_addr)
{
Start_I2C();
SendByte(DS3231_WriteAddress);
if(ack==0)
SendByte(random_addr);
if(ack==0)
return(0);
return(read_current());
}
voidModifyTime(ucharyea,uchar
sec,ucharweek)
{
uchartemp=0;
temp=HEX2BCD(yea);
write_byte(DS3231_YEAR,temp);
temp=HEX2BCD(mon);
write_byte(DS3231_MONTH,temp);
temp=HEX2BCD(da);
write_byte(DS3231_DAY,temp);
temp=HEX2BCD(hou);
write_byte(DS3231_HOUR,temp);
mon,ucharda,ucharhou,uchar
//修改年
//修改月
//修改日
//修改时
min,uchar
temp=HEX2BCD(min);
write_byte(DS3231_MINUTE,temp);//修改分
temp=HEX2BCD(sec);
write_byte(DS3231_SECOND,temp);//修改秒
temp=HEX2BCD(week);
write_byte(DS3231_WEEK,temp);//修改星期
****************
液晶写入**********************
}
write_1602com(ucharcom)//液晶写入指令函数{
rs=0;//置为写入命令
P0=com;//送入数据
delayus(1000);
en=1;//拉高使能端
delayus(1000);
en=0;//完成高脉冲
}
write_1602dat(uchardat)
{
rs=1;//置为写入数据
P0=dat;//送入数据
delayus(1000);
en=1;
delayus(1000);
*******************over*********************
en=0;
}
lcd_init()//液晶初始化函数
{wr=0;
write_1602com(0x38);//
设置液晶工作模式
write_1602com(0x0c);//
开显示不显示光标
write_1602com(0x06);//
整屏不移动,指针加一
write_1602com(0x01);
write_1602com(yh+1);//
字符写入的位置
for(a=0;a<14;a++)
{
write_1602dat(tab1[a]);
//delay(3);
}
write_1602com(er);
for(a=0;a<12;a++)
{
//delay(3);
}
write_1602com(er+14);//写温度符号
write_1602dat(0xdf);
write_1602dat(0x43);
voidwrite_sfm(ucharadd,uchardat)//写时分秒及温度{
uchargw,sw;
gw=dat%10;
sw=dat/10;
write_1602com(er+add);
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);
}
voidwrite_nyr(ucharadd,uchardat)//写日期{
uchargw,sw;
gw=dat%10;
sw=dat/10;
write_1602com(yh+add);
write_1602dat(0x30+sw);
write_1602dat(0x30+gw);
}
voidwrite_week(ucharweek)//写星期函数
{
write_1602com(yh+0x0c);
switch(week)
{
case1:
write_1602dat('M');//delay(5);
write_1602dat('O');//delay(5);
write_1602dat('N');
break;
case2:
write_1602dat('T');//delay(5);
write_1602dat('U');//delay(5);
write_1602dat('E');
break;
case3:
write_1602dat('W');//delay(5);
break;
case4:
write_1602dat('T');//delay(5);
write_1602dat('H');//delay(5);write_1602dat('U');
break;
case5:
write_1602dat('F');//delay(5);
write_1602dat('R');//delay(5);write_1602dat('I');
break;
case6:
write_1602dat('S');//delay(5);
write_1602dat('T');//delay(5);write_1602dat('A');
break;
case7:
write_1602dat('S');//delay(5);
write_1602dat('U');//delay(5);write_1602dat('N');
break;
}
voidkeyscan()
{
if(key1==0)//key1为功能键
{
delayus(5000);
if(key1==0)
{
while(!
key1);
key1n++;
if(key1n==9)
key1n=1;
switch(key1n)
{
case1:
TR0=0;//关闭定时器
//TR1=0;
write_1602com(er+0x06);//写入光标位置
write_1602com(0x0f);//设置光标为闪烁
break;
//write_1602com(0x0f);
break;
case3:
write_1602com(er+0);//shi
//write_1602com(0x0f);
break;
case4:
write_1602com(yh+0x0d);//week
//write_1602com(0x0f);
break;
case5:
write_1602com(yh+0x09);//ri
//write_1602com(0x0f);
break;
case6:
write_1602com(yh+0x06);//yue
//write_1602com(0x0f);
break;
case7:
write_1602com(yh+0x03);//nian
//write_1602com(0x0f);
break;
case8:
write_1602com(0x0c);//设置光标不闪烁
write_sfm(6,miao);//写入新的秒数
temp=(miao)/10*16+(miao)%10;
write_byte(DS3231_SECOND,temp);//退出时修改秒write_1602com(er+6);
temp=(fen)/10*16+(fen)%10;
write_byte(DS3231_MINUTE,temp);//修改分
write_1602com(er+3);
TR0=1;//打开定时器
break;
}
}
}
if(key1n!
=0)//当key1按下以下。
再按以下键才有效
{
if(key2==0)//上调键
{
delayus(5000);
if(key2==0)
{
while(!
key2);
switch(key1n)
{
case1:
miao++;
if(miao==60)
miao=0;
write_sfm(6,miao);//写入新的秒数
temp=(miao)/10*16+(miao)%10;
write_byte(DS3231_SECOND,temp);//修改秒
write_1602com(er+6);//设置液晶的模式是写入数据后,指针自动加一,在这里是写回原来的位置
break;
case2:
fen++;
if(fen==60)
fen=0;
write_sfm(0x03,fen);
temp=(fen)/10*16+(fen)%10;
write_byte(DS3231_MINUTE,temp);
write_1602com(er+3);
break;
case3:
shi++;
if(shi==24)
shi=0;
write_sfm(0,shi);
temp=(shi)/10*16+(shi)%10;
write_1602com(er+0);
break;
case4:
week++;
if(week==8)
week=0;
write_week(week);
write_byte(DS3231_WEEK,week);//
write_1602com(yh+0x0d);
break;
case5:
ri++;
if(ri==31)
ri=0;
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;
write_byte(DS3231_DAY,temp);
write_1602com(yh+9);
break;
case6:
yue++;
if(yue==13)
yue=0;
write_nyr(6,yue);
修改星期
//修改日
temp=(yue)/10*16+(yue)%10;
write_byte(DS3231_MONTH,temp);
write_1602com(yh+6);
break;
case7:
nian++;
if(nian==100)
nian=0;
write_nyr(3,nian);
temp=(nian)/10*16+(nian)%10;
write_byte(DS3231_YEAR,temp);
write_1602com(yh+3);
break;
//修改月
//修改年
}
if(key3==0)
{
delayus(5000);
if(key3==0)
{
while(!
key3);
switch(key1n)
{
case1:
miao--;
if(miao==-1)
miao=59;
write_sfm(6,miao);//写入新的秒数
temp=(miao)/10*16+(miao)%10;
write_byte(DS3231_SECOND,temp);//修改秒
指针自动加一,
write_1602com(er+6);//因为设置液晶的模式是写入数据后,在这里是写回原来的位置
break;
case2:
fen--;
if(fen==-1)
fen=59;
write_sfm(3,fen);
temp=(fen)/10*16+(fen)%10;
write_byte(DS3231_MINUTE,temp);//修改分
write_1602com(er+3);
break;
case3:
shi--;
if(shi==-1)shi=23;
write_sfm(0,shi);
temp=(shi)/10*16+(shi)%10;
write_byte(DS3231_HOUR,temp);
write_1602com(er+0);
break;
case4:
week--;
if(week==-1)
week=7;
write_week(week);
write_byte(DS3231_WEEK,week);//
write_1602com(yh+0x0d);
break;
case5:
ri--;
if(ri==-1)
ri=30;
write_nyr(9,ri);
temp=(ri)/10*16+(ri)%10;write_byte(DS3231_DAY,temp);
write_1602com(yh+9);
break;
case6:
yue--;
if(yue==-1)
//修改时
修改星期
//修改日
}
}
}
}
yue=12;
write_nyr(6,yue);
temp=(yue)/10*16+(yue)%10;
write_byte(DS3231_MONTH,temp);//修改月
write_1602com(yh+6);
break;
case7:
nian--;
if(nian==-1)
nian=99;
write_nyr(3,nian);
temp=(nian)/10*16+(nian)%10;
write_byte(DS3231_YEAR,temp);//修改年
write_1602com(yh+3);
break;
}
voidmain()
{
uintii=0;
lcd_init();
RESET=0x1;//DS3231复位操作,正常操作下不需要每次都复位
TMOD=0x11;//定时器0,1工作模式1,16位定时方式
TH0=0;
TL0=0;
EA=1;
ET0=1;
TCON=0x01;
IE=0x82;//使能timer0,1中断
TR0=1;
//ModifyTime(17,8,15,23,02,20,2);//初始化,年月日时分秒星期(24小时制)
while
(1)
{
keyscan();
}
}
voidtimer0()interrupt1
{
//TH0=(65536-60000)/256;
//TL0=(65536-60000)%256;
miao=BCD_Decimal(read_random(DS3231_SECOND));
fen=BCD_Decimal(read_random(DS3231_MINUTE));
shi=BCD_Decimal(read_random(DS3231_HOUR));
ri=BCD_Decimal(read_random(DS3231_DAY));
yue=BCD_Decimal(read_random(DS3231_MONTH));
nian=BCD_Decimal(read_random(DS3231_YEAR));
week=BCD_Decimal(read_random(DS3231_WEEK));
//温度高4位
//温度低4位
temp1=BCD_Decimal(read_random(DS3231_TEMPERATUREH));
temp2=BCD_Decimal(read_random(DS3231_TEMPERATUREL));
keyscan();
temp2=(temp2>