STC单片机C51程序读取DS3231时钟芯片参数

//-------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;
}   

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值