1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

real time clock ds1307 interfacing with 8051

Discussion in '8051/8951' started by siprax345, May 11, 2006.

  1. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0
    we are using ds1307 rtc with 8051,we want c language code for the interfacinng .can any one help?
     
  2. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    How are you connecting the part to the 8051, and why exactly can't you write the code yourself?
     
  3. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0
    Ds1307

    sir we r using I2C protocol which DS1307 supports but AT89S52 doesnt.
    We wrote the code in C but we are not getting whether the communication is goin or not. I can give u the code made by us also to see.
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0

    Sir this is the code that we made :

    #include<AT89X52.h>
    #include<abco.h>
    #include<Lcddisp.c>
    #define ack 0
    #define nack 1
    #define addrtc 0xd0
    //#define DS1307

    #define scl P1_1
    #define sda P1_2

    void i2c_start();
    void i2c_stop();
    void i2c_write(unsigned char d);
    unsigned char i2c_read(unsigned char);
    //void read_byte();
    //void write_byte();
    void disp_clk_regs(unsigned char);
    //void ramwrite(unsigned char);
    //void ramread();
    void initialize();
    void i2c_start()
    {
    sda=1;scl=1;sda=0;
    }
    void i2c_stop()
    {
    sda=0;sda=0;sda=0;scl=1;scl=1;sda=1;
    }
    void i2c_write(unsigned char d)
    {
    unsigned char i;
    scl=0;
    for(i=1;i<=8;i++)
    {
    sda=(d>>7);
    scl=1;
    d=d<<1;
    scl=0;
    }
    sda=1;
    scl=0;
    scl=1;
    if(sda)
    {
    disp_string("ACK missing",line1);
    disp_val(d,l1col1);
    }
    scl=0;
    }
    unsigned char i2c_read(unsigned char b)
    {
    unsigned char d,i;
    sda=1;
    scl=0;
    for(i=1;i<=8;i++)
    {
    scl=1;
    d=d<<1;
    d=d | (unsigned char)sda;
    scl=0;
    }
    sda=b;
    scl=0;
    scl=1;
    if(b==nack) sda=1;
    scl=0;
    sda=1;
    return d;
    }
    /*void readbyte()
    { unsigned char loc,value;
    loc=0x80;
    i2c_start();
    i2c_write(addrtc);
    i2c_write(loc);
    i2c_start();
    i2c_write(addrtc|1);
    value=i2c_read(nack);
    i2c_stop();
    } */
    /*void writebyte()
    {
    unsigned char address;
    address=0x80;
    i2c_start();
    i2c_write(addrtc);
    i2c_write(address);
    i2c_write(0x30);
    i2c_stop();
    } */
    void initialize()
    {
    //unsigned char yr,mon,dt,dy,hr,min,sec;

    i2c_start();
    i2c_write(addrtc);
    i2c_write(0x00);
    i2c_write(0x00);
    i2c_stop();

    i2c_start();
    i2c_write(addrtc);
    i2c_write(0x00);
    i2c_write(0x00);
    i2c_write(0x00);
    i2c_write(0x50); //01010000
    i2c_write(0x04);
    i2c_write(0x11);
    i2c_write(0x05);
    i2c_write(0x06);

    //#if defined DS1307
    i2c_write(0x10);
    //#endif
    i2c_stop();
    }
    void disp_clk_regs(unsigned char prv_sec)
    {
    unsigned char sec,min,hr,dt,mon,dy,yr,mil,pm;
    disp_string("DISP. CLOCK",line1);
    i2c_start();
    i2c_write(addrtc);
    i2c_write(0x00);
    i2c_start();
    i2c_write(addrtc|1);
    sec=i2c_read(ack);
    min=i2c_read(ack);
    hr=i2c_read(ack);
    dy=i2c_read(ack);
    dt=i2c_read(ack);
    mon=i2c_read(ack);
    yr=i2c_read(ack);
    i2c_stop();
    if(hr&0x40)
    mil=0;
    else
    mil=1;
    if(sec!=prv_sec)
    {
    if(mil)
    {

    disp_val((hr&0xf0)+0x30,l1col1);
    disp_val((hr&0x0f)+0x30,l1col2);
    disp_val((min&0xf0)+0x30,l1col3);
    disp_val((min&0x0f)+0x30,l1col4);
    disp_val((sec&0xf0)+0x30,l1col5);
    disp_val((sec&0x0f)+0x30,l1col6);
    }
    else
    {
    if(hr&0x20)
    pm='A';
    else
    pm='P';
    hr&=0x1f;
    disp_val((hr&0xf0)+0x30,l1col1);
    disp_val((hr&0x0f)+0x30,l1col2);
    disp_val((min&0xf0)+0x30,l1col3);
    disp_val((min&0x0f)+0x30,l1col4);
    disp_val((sec&0xf0)+0x30,l1col5);
    disp_val((sec&0x0f)+0x30,l1col6);}
    }
    if(prv_sec ==0xfe)
    return;
    prv_sec=sec;
    }
    void main()
    {
    //unsigned char M,M1;
    lcd_init();
    //#if defined DS1307
    disp_string("DS1307 RTC",line1);
    // #endif

    disp_string("INITIALIZING",line1);
    initialize();
    disp_string("INITIALIZED",line1);
    while(1)
    {
    /*#if defined DS1307
    disp_string("DS1307 RTC",line1);
    #endif */
    disp_clk_regs(0x99);
    clear_disp(line1);
    }
    }
     
  6. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    That's better now I have a chance. I see that you did write your own code but that it does not work the way you expect it to work. Now I need to know what exactly does not work. Can you help me out here?
     
  7. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0
    RE

    sir,the problem we are when we start reading from the clcok register the value is not at all incrementing .
    We are in dobut that whether the chip is getting the instructions or not coz we tried out 1Hz sqw wavw osc also but it didnt work, we tested the thing using LED at pin7.
    We also wrote many debug strings to be displayed in the LCD , the program flow was correct but nothin was happening when we access the clock registers.
    How to confirm whether the chip is getting our instructions or not ?
    Plz help !
     
  8. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    Let us focus on the following small code fragment

    Please tell me what code you think the compiler generates for the line
    Code (text):

      sda=(d>>7) ;
     
    You are taking a byte variable and shifting it to the right by 7 positions and assigning the result to the bit "sda". Is it your intention to set sda equal to the high order bit of the byte. Is that the code that the compiler generated?

    Assuming the right value was written to sda, you take the clock high, shift the input byte to the left by one position, then take the clock low. This loop repeats eight times.

    At the end of the loop you look for the ACK pulse. Are you getting the ACK pulse?

    Can you see the write transaction on an oscilliscope?

    That's all for now until we have more information.
     
  9. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    OK, we're crossing messages. So is there another register besides the incrementing clock that you can read to narrow the problem down to the I2C write transaction or the I2C read transaction. Maybe a status register or an internal RAM location? I will take a look at the data sheet since you may have a hardware problems. Would posting a schematic be out of the question?
     
  10. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0
    sir can u give us any sample C code
     
  11. siprax345

    siprax345 New Member

    Joined:
    Apr 4, 2006
    Messages:
    10
    Likes:
    0
    sir , when slave will be transmitting master (mc) will have to check the ack after 8 bits ? m i right here?
    and when master is transmitting, mc will generate the no ack pulse after 8 bits ?
     
  12. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    No I don't have any sample code handy that you can use.
    I'm going to assume that your circuit is similar to the one on page 13 of the data sheet.

    I think you have a slight misunderstanding of the ACK pulse convention. When the master transmits the slave address(0x1101000), the DS1307 transmits a single ACK bit after receiving 8 bits. Then depending on the state of the R/W bit the process continues for the data bytes.

    As near as I can tell the slave always sends an ACK for each 8 bits that the processor sends. When the master is reciving he sends an ACK of each byte except the last one.

    Did you attempt to turn on the CH bit in address 0 to enable the oscillator?
     
  13. kinjalgp

    kinjalgp Active Member

    Joined:
    Oct 28, 2002
    Messages:
    1,851
    Likes:
    3
    Location:
    INDIA/USA
    The other reason why seconds are not incrementing may be that the internal clock to DS1307 is disabed. This is the default state when DS1307 is powered up for the very first time. In the main code read CH bit, if it is 1 make it 0.

    This thing is clearly mentioned in the datasheet,
    "Please note that the initial power-on state of all registers is not defined. Therefore, it is important to
    enable the oscillator (CH bit = 0) during initial configuration."
     
    Last edited: May 11, 2006
  14. Papabravo

    Papabravo Well-Known Member

    Joined:
    Mar 9, 2006
    Messages:
    2,889
    Likes:
    25
    Location:
    Michigan, USA (GMT-5)
    So if you have read and write working well enough to access RAM locations then try turning on the CH bit as both of us have mentioned.

    If the read and write are still not working then we must look deeper.
     
  15. kinjalgp

    kinjalgp Active Member

    Joined:
    Oct 28, 2002
    Messages:
    1,851
    Likes:
    3
    Location:
    INDIA/USA

Share This Page