微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > 嵌入式系统设计讨论 > 430单片机驱动ds3231sn,读取的时间都是0

430单片机驱动ds3231sn,读取的时间都是0

时间:10-02 整理:3721RD 点击:
做了块板子,用ds3231sn时钟芯片,板子其它部分都做好了,昨天网上找了一个stm32驱动ds3231的程序,我用的430单片机,按照程序修改了一下,却死活读取不到正确时间。貌似通讯不对,可是时序延时是完全按照网上的程序的。为什么会这样?附原理图。
补充:在仿真时,时间读取函数里面,仿真看到年月日时分秒都是0。 编辑


有人不

贴出来代码:
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
///////////////////////////////////////////////////////////////////////////////////
/*
DS3231.C文件
*/
////////////////////////////////////////////////////////////////////////////////////
#include"ds3231sn.h"
#define SETIIC_SCL P1OUT |= BIT7
#define CLRIIC_SCL P1OUT &=~BIT7
#define SETIIC_SDA P1OUT |= BIT6
#define CLRIIC_SDA P1OUT &=~BIT6
#define IIC_SDA (P1IN&BIT6)
_calendar_obj calendar;
#define DS3231_WriteAddress 0xD0   
#define DS3231_ReadAddress  0xD1
//-------------------------------------------------------------------
unsigned char BCD2HEX(unsigned char val)
{
    unsigned char i;
    i= val&0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;
    return i;
}
unsigned short B_BCD(unsigned char val)
{
  unsigned char i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
    P1DIR |= BIT7;P1DIR |= BIT6;
    SETIIC_SDA;//释放IIC总线的数据线。
    SETIIC_SCL;//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
     P1DIR |= BIT6;
     SETIIC_SDA;//拉高数据线
     delay_us(1);
     SETIIC_SCL;//拉高时钟线
     delay_us(5);
     CLRIIC_SDA;//在时钟线为高电平时,拉低数据线,产生起始信号。
     delay_us(5);
     CLRIIC_SCL;//拉低时钟线
     delay_us(2);
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线
    CLRIIC_SDA;//拉低数据线
    delay_us(4);
    SETIIC_SCL;//拉高时钟线。
    delay_us(5);
    SETIIC_SDA;//时钟时线为高电平时,拉高数据线,产生停止信号。
    delay_us(4);
}
//-------------------------------------------------------------------
unsigned char IIC_Tack(void)
{//接收应答信号函数
    unsigned char timnu=0;//定义一个位变量,来暂存应答状态。
    P1DIR &=~ BIT6;
    SETIIC_SDA;//释放数据总线,准备接收应答信号。
    delay_us(1);
    SETIIC_SCL;//拉高时钟线。
    delay_us(1);
    while(IIC_SDA==1)//读取应答信号的状态。
    {
      timnu++;
      if(timnu>250)
      {
        IIC_stop();
        return 1;//返回应答信号的状态,0表示应答,1表示非应答。
      }
    }
    CLRIIC_SCL;//拉低时钟线。
    return 0;//返回应答信号的状态,0表示应答,1表示非应答。
}
//产生ACK应答
void IIC_Ack(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        CLRIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}
//不产生ACK应答                    
void IIC_NAck(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        SETIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}               
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数
    unsigned char i;
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
    for(i=0;i<8;i++)
    {              
                if((Data&0x80)>>7)
                   SETIIC_SDA;
                else
                   CLRIIC_SDA;
                Data<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                SETIIC_SCL;//拉高时钟线。
                delay_us(2);
                CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
                delay_us(2);
    }
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte(unsigned char ack)
{//从IIC总线读取一个字节的数据函数
    unsigned char i;
    unsigned char Data=0;       //定义一个缓冲寄存器。
    P1DIR &=~ BIT6;
    for(i=0;i<8;i++)//有8位数据
    {
        CLRIIC_SCL;//拉低时钟线,为读取下一位数据做准备。
        delay_us(2);
        SETIIC_SCL;//拉高时钟线,为读取下一位数据做准备。
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
      
        if(IIC_SDA==1)//如果数据线为高平电平。
            Data++;delay_us(1);
    }
     if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    delay_us(5);
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答.
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Waddr)
{//从任意地址读取一个字节数据函数
    unsigned char Data;//定义一个缓冲寄存器。
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_ReadAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    Data=IIC_read_byte(1);//写入数据。
    IIC_stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}
void Read_RTC(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_month=IIC_single_byte_read(0x05);  
  calendar.w_date=IIC_single_byte_read(0x04);
  calendar.hour=IIC_single_byte_read(0x02);  
  calendar.min=IIC_single_byte_read(0x01);
  calendar.sec=IIC_single_byte_read(0x00);  
}
void Set_RTC(unsigned char yea,unsigned char mon,unsigned char da,unsigned char hou,unsigned char min,unsigned char sec)
{
  unsigned char temp=0;
  
  temp=B_BCD(yea);
  IIC_single_byte_write(0x06,temp);
  
  temp=B_BCD(mon);
  IIC_single_byte_write(0x05,temp);
   
  temp=B_BCD(da);
  IIC_single_byte_write(0x04,temp);
  
  temp=B_BCD(hou);
  IIC_single_byte_write(0x02,temp);
  
  temp=B_BCD(min);
  IIC_single_byte_write(0x01,temp);
  
  temp=B_BCD(sec);
  IIC_single_byte_write(0x00,temp);
}
void get_show_time(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_year=BCD2HEX(calendar.w_year);

  calendar.w_month=IIC_single_byte_read(0x05);
  calendar.w_month=BCD2HEX(calendar.w_month);

  calendar.w_date=IIC_single_byte_read(0x04);  
  calendar.w_date=BCD2HEX(calendar.w_date);
   
  calendar.hour=IIC_single_byte_read(0x02);
  calendar.hour&=0x3f;                  
  calendar.hour=BCD2HEX(calendar.hour);

  calendar.min=IIC_single_byte_read(0x01);
  calendar.min=BCD2HEX(calendar.min);
   
   
  calendar.sec=IIC_single_byte_read(0x00);
  calendar.sec=BCD2HEX(calendar.sec);
}
void DS3231_Initial()
{
    IIC_Init();
    IIC_single_byte_write(0x0e,0);
    delay_ms(2);
    IIC_single_byte_write(0x0f,0);
    delay_ms(2);
}

///////////////////////////////////////////////////////////////////////////////////
/*
DS3231.C文件
*/
////////////////////////////////////////////////////////////////////////////////////
#include"ds3231sn.h"
#define SETIIC_SCL P1OUT |= BIT7
#define CLRIIC_SCL P1OUT &=~BIT7
#define SETIIC_SDA P1OUT |= BIT6
#define CLRIIC_SDA P1OUT &=~BIT6
#define IIC_SDA (P1IN&BIT6)
_calendar_obj calendar;
#define DS3231_WriteAddress 0xD0   
#define DS3231_ReadAddress  0xD1
//-------------------------------------------------------------------
unsigned char BCD2HEX(unsigned char val)
{
    unsigned char i;
    i= val&0x0f;
    val >>= 4;
    val &= 0x0f;
    val *= 10;
    i += val;
    return i;
}
unsigned short B_BCD(unsigned char val)
{
  unsigned char i,j,k;
  i=val/10;
  j=val%10;
  k=j+(i<<4);
  return k;
}
//-------------------------------------------------------------------
void IIC_Init(void)
{//IIC总线初始化函数
    P1DIR |= BIT7;P1DIR |= BIT6;
    SETIIC_SDA;//释放IIC总线的数据线。
    SETIIC_SCL;//释放IIC总线的时钟线。
}
//-------------------------------------------------------------------
void IIC_start(void)
{//IIC总线产生起始信号函数
     P1DIR |= BIT6;
     SETIIC_SDA;//拉高数据线
     delay_us(1);
     SETIIC_SCL;//拉高时钟线
     delay_us(5);
     CLRIIC_SDA;//在时钟线为高电平时,拉低数据线,产生起始信号。
     delay_us(5);
     CLRIIC_SCL;//拉低时钟线
     delay_us(2);
}
//-------------------------------------------------------------------
void IIC_stop(void)
{//IIC总线产生停止信号函数
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线
    CLRIIC_SDA;//拉低数据线
    delay_us(4);
    SETIIC_SCL;//拉高时钟线。
    delay_us(5);
    SETIIC_SDA;//时钟时线为高电平时,拉高数据线,产生停止信号。
    delay_us(4);
}
//-------------------------------------------------------------------
unsigned char IIC_Tack(void)
{//接收应答信号函数
    unsigned char timnu=0;//定义一个位变量,来暂存应答状态。
    P1DIR &=~ BIT6;
    SETIIC_SDA;//释放数据总线,准备接收应答信号。
    delay_us(1);
    SETIIC_SCL;//拉高时钟线。
    delay_us(1);
    while(IIC_SDA==1)//读取应答信号的状态。
    {
      timnu++;
      if(timnu>250)
      {
        IIC_stop();
        return 1;//返回应答信号的状态,0表示应答,1表示非应答。
      }
    }
    CLRIIC_SCL;//拉低时钟线。
    return 0;//返回应答信号的状态,0表示应答,1表示非应答。
}
//产生ACK应答
void IIC_Ack(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        CLRIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}
//不产生ACK应答                    
void IIC_NAck(void)
{
        P1DIR |= BIT6;
        CLRIIC_SCL;
        SETIIC_SDA;
        delay_us(2);
        SETIIC_SCL;
        delay_us(2);
        CLRIIC_SCL;
}               
//-------------------------------------------------------------------
void IIC_write_byte(unsigned char Data)
{//向IIC总线写入一个字节的数据函数
    unsigned char i;
    P1DIR |= BIT6;
    CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
    for(i=0;i<8;i++)
    {              
                if((Data&0x80)>>7)
                   SETIIC_SDA;
                else
                   CLRIIC_SDA;
                Data<<=1;           
                delay_us(2);   //对TEA5767这三个延时都是必须的
                SETIIC_SCL;//拉高时钟线。
                delay_us(2);
                CLRIIC_SCL;//拉低时钟线,允许改变数据线的状态
                delay_us(2);
    }
}
//-------------------------------------------------------------------
unsigned char IIC_read_byte(unsigned char ack)
{//从IIC总线读取一个字节的数据函数
    unsigned char i;
    unsigned char Data=0;       //定义一个缓冲寄存器。
    P1DIR &=~ BIT6;
    for(i=0;i<8;i++)//有8位数据
    {
        CLRIIC_SCL;//拉低时钟线,为读取下一位数据做准备。
        delay_us(2);
        SETIIC_SCL;//拉高时钟线,为读取下一位数据做准备。
        Data=Data<<1;//将缓冲字节的数据左移一位,准备读取数据。
      
        if(IIC_SDA==1)//如果数据线为高平电平。
            Data++;delay_us(1);
    }
     if (!ack)
        IIC_NAck();//发送nACK
    else
        IIC_Ack(); //发送ACK   
    return Data;//返回读取的一个字节数据。
}
//-------------------------------------------------------------------
void IIC_single_byte_write(unsigned char Waddr,unsigned char Data)
{//向任意地址写入一个字节数据函数
    IIC_start();//产生起始信号
    delay_us(5);
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答.
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_write_byte(Data);//写入数据。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_stop();//产生停止符号。
}
//-------------------------------------------------------------------
unsigned char IIC_single_byte_read(unsigned char Waddr)
{//从任意地址读取一个字节数据函数
    unsigned char Data;//定义一个缓冲寄存器。
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_WriteAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    IIC_write_byte(Waddr);//写入要操作的单元地址。
    IIC_Tack();//等待设备的应答。
    delay_us(5);
    IIC_start();//产生起始信号
    IIC_write_byte(DS3231_ReadAddress);//写入设备地址(写)
    IIC_Tack();//等待设备的应答
    delay_us(5);
    Data=IIC_read_byte(1);//写入数据。
    IIC_stop();//产生停止符号。
    //-------------------返回读取的数据--------------------
    return Data;//返回读取的一个字节数据。
}
void Read_RTC(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_month=IIC_single_byte_read(0x05);  
  calendar.w_date=IIC_single_byte_read(0x04);
  calendar.hour=IIC_single_byte_read(0x02);  
  calendar.min=IIC_single_byte_read(0x01);
  calendar.sec=IIC_single_byte_read(0x00);  
}
void Set_RTC(unsigned char yea,unsigned char mon,unsigned char da,unsigned char hou,unsigned char min,unsigned char sec)
{
  unsigned char temp=0;
  
  temp=B_BCD(yea);
  IIC_single_byte_write(0x06,temp);
  
  temp=B_BCD(mon);
  IIC_single_byte_write(0x05,temp);
   
  temp=B_BCD(da);
  IIC_single_byte_write(0x04,temp);
  
  temp=B_BCD(hou);
  IIC_single_byte_write(0x02,temp);
  
  temp=B_BCD(min);
  IIC_single_byte_write(0x01,temp);
  
  temp=B_BCD(sec);
  IIC_single_byte_write(0x00,temp);
}
void get_show_time(void)
{
  calendar.w_year=IIC_single_byte_read(0x06);  
  calendar.w_year=BCD2HEX(calendar.w_year);

  calendar.w_month=IIC_single_byte_read(0x05);
  calendar.w_month=BCD2HEX(calendar.w_month);

  calendar.w_date=IIC_single_byte_read(0x04);  
  calendar.w_date=BCD2HEX(calendar.w_date);
   
  calendar.hour=IIC_single_byte_read(0x02);
  calendar.hour&=0x3f;                  
  calendar.hour=BCD2HEX(calendar.hour);

  calendar.min=IIC_single_byte_read(0x01);
  calendar.min=BCD2HEX(calendar.min);
   
   
  calendar.sec=IIC_single_byte_read(0x00);
  calendar.sec=BCD2HEX(calendar.sec);
}
void DS3231_Initial()
{
    IIC_Init();
    IIC_single_byte_write(0x0e,0);
    delay_ms(2);
    IIC_single_byte_write(0x0f,0);
    delay_ms(2);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top