//-------STC12C5A60S2--外置晶振11.0592M-2023/1/16/CSDN短枪王博客
//ModifyTime();修改日期函数,上电初始化时写一次即可,电池会保持写入的参数
//get_show_time(void);获取时间函数,主程序里直接调用即可
// get_show_date(void) ;获取日期函数,主程序里直接调用即可
//get_show_Temperature(void);温度转换函数,主程序里直接调用即可
uint xdata NIAN1,YUE1,DAY1,SHI1,FEN1,MIAO1,WEN1,WEN2;//时间+温度变量定义
sbit SDA=P0^1; //I2C数据传送位SDA,配置DS3231接口,
sbit SCL=P0^0; //I2C时钟控制位SCL
bit ack; //应答标志位
#define DS3231_WriteAddress 0xD0 //器件写地址
#define DS3231_ReadAddress 0xD1 //器件读地址
#define DS3231_SECOND 0x00 //秒
#define DS3231_MINUTE 0x01 //分
#define DS3231_HOUR 0x02 //时
#define DS3231_WEEK 0x03 //星期
#define DS3231_DAY 0x04 //日
#define DS3231_MONTH 0x05 //月
#define DS3231_YEAR 0x06 //年
#define OSF 7 //振荡器停止标志
#define DS3231_XTAL 0x10 //晶体老化寄存器
#define DS3231_TEMPERATUREH 0x11 //温度寄存器高字节(8位)
#define DS3231_TEMPERATUREL 0x12 //温度寄存器低字节(高2位)
uchar code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0,1,2,3
0x99,0x92,0x82,0xf8,0x80,0x90, 0xff}; // 4,5,6,7,8,9,off
uchar data dis_buf[8];
uchar data dis_index;
uchar data dis_digit;
//================================================
uchar BCD2HEX(uchar val) //BCD转换为Byte
{ uchar temp;
temp=val&0x0f;
val>>=4;
val&=0x0f;
val*=10;
temp+=val;
return temp;
}
uchar HEX2BCD(uchar val) //B码转换为BCD码
{ uchar i,j,k;
i=val/10;
j=val%10;
k=j+(i<<4);
return k; }
void delayus(uint us)
{ while (us--);
}
void Start_I2C()
{ SDA=1; //发送起始条件的数据信号
delayus(1);
SCL=1;
delayus(5); //起始条件建立时间大于4.7us,延时
SDA=0; //发送起始信号
delayus(5); // 起始条件锁定时间大于4μs
SCL=0; //钳住I2C总线,准备发送或接收数据
delayus(2);
}
void Stop_I2C()
{ SDA=0; //发送结束条件的数据信号
delayus(1); //发送结束条件的时钟信号
SCL=1; //结束条件建立时间大于4us
delayus(5);
SDA=1; //发送I2C总线结束信号
delayus(4);
}
void SendByte(uchar c)
{ uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位
{ if((c<<BitCnt)&0x80)
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);
}
//------------------------------------------------------------------------------------------------------------
uchar RcvByte()
{ uchar retc;
uchar BitCnt;
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);
}
//------------------------------------------
void Ack_I2C(bit a)
{ if(a==0) SDA=0; //在此发出应答或非应答信号
else SDA=1;
delayus(3);
SCL=1;
delayus(5); //时钟低电平周期大于4μs
SCL=0; //清时钟线,钳住I2C总线以便继续接收
delayus(2);
}
//=========================================================================================
uchar write_byte(uchar addr, uchar write_data)
{ Start_I2C();
SendByte(DS3231_WriteAddress);
if (ack == 0)
return 0;
SendByte(addr);
if (ack == 0) return 0;
SendByte(write_data);
if (ack == 0) return 0;
Stop_I2C();
delayus(10);
return 1;
}
//------------------------------------------
uchar read_current()
{
uchar read_data;
Start_I2C();
SendByte(DS3231_ReadAddress);
if(ack==0) return(0);
read_data = RcvByte();
Ack_I2C(1);
Stop_I2C();
return read_data;
}
//-----------------------------------------
uchar read_random(uchar random_addr)
{
Start_I2C();
SendByte(DS3231_WriteAddress);
if(ack==0) return(0);
SendByte(random_addr);
if(ack==0) return(0);
return(read_current());
}
//-----------------------------------------
void ModifyTime(uchar yea,uchar mon,uchar da,uchar hou,uchar min,uchar sec)
{ uchar temp=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); //修改秒
}
//---
//----------------------------------------------------------------------------
void get_show_time(void)
{
uchar Htemp1,Htemp2,Mtemp1,Mtemp2,Stemp1,Stemp2;
Htemp1=read_random(DS3231_HOUR);
Htemp1&=0x3f;
Htemp2=BCD2HEX(Htemp1);
SHI1=Htemp2;
Mtemp1=read_random(DS3231_MINUTE);
Mtemp2=BCD2HEX(Mtemp1);
FEN1=Mtemp2;
Stemp1=read_random(DS3231_SECOND);
Stemp2=BCD2HEX(Stemp1);
MIAO1=Stemp2;
}
//-----------------------------------------------------------------------------
void get_show_date(void)
{
uchar Ytemp1,Ytemp2,Mtemp1,Mtemp2,Dtemp1,Dtemp2;
Ytemp1=read_random(DS3231_YEAR);
Ytemp2=BCD2HEX(Ytemp1);
NIAN1=Ytemp2;
Mtemp1=read_random(DS3231_MONTH);
Mtemp2=BCD2HEX(Mtemp1);
YUE1=Mtemp2;
Dtemp1=read_random(DS3231_DAY);
Dtemp2=BCD2HEX(Dtemp1);
DAY1= Dtemp2;
}
//-------------------------------------------------------------------------------
void get_show_Temperature(void)
{
uchar Ttemp1,Ttemp2,Ttemp3,Ttemp4;
Ttemp1=read_random(DS3231_TEMPERATUREH);
Ttemp2=BCD2HEX(Ttemp1);
WEN1=Ttemp2;
Ttemp3=read_random(DS3231_TEMPERATUREL);
Ttemp4=BCD2HEX(Ttemp3);
WEN2 =Ttemp4;
}