SDA=1;//判断发送位
else
SDA=0;
delayus
(1);
SCL=1;//置时钟线为高,通知被控器开始接收数据位
delayus(5);//保证时钟高电平周期大于4μs
SCL=0;
}
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++)
{
delayus
(1);
SCL=0;//置时钟线为低,准备接收数据位
delayus(5);//时钟低电平周期大于4.7μs
SCL=1;//置时钟线为高使数据线上数据有效
delayus(3);
retc=retc<<1;
if(SDA==1)
retc=retc+1;//读数据位,接收的数据位放入retc中
delayus
(2);
}
SCL=0;
delayus
(2);
return(retc);
}
voidAck_I2C(bita)
{
if(a==0)
SDA=0;//在此发出应答或非应答信号
else
SDA=1;
delayus(3);
SCL=1;
delayus(5);//时钟低电平周期大于4μs
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();
delayus(10);
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)
return(0);
SendByte(random_addr);
if(ack==0)
return(0);
return(read_current());
}
voidModifyTime(ucharyea,ucharmon,ucharda,ucharhou,ucharmin,ucharsec,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);//修改时
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);
en=0;
}
/*********************over***********************/
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++)
{
write_1602dat(tab2[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);
write_1602dat('E');//delay(5);
write_1602dat('D');
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;
case2:
write_1602com(er+3);//fen
//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);
write_sfm(0x03,fen);
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_byte(DS3231_HOUR,temp);
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,te