This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

query about rtc ds1307

hi sir,
i am new to this rtc ds1307 and want to know dat according to its datasheet it is battery backed....does that mean that you need not initialize it when you use it for the first time?????

and if i want to simulate it on proteus software it shows correct date and time automatically without writing it for the first time.....

i m unable to understand all this plzzz help me out....and i m sorry if i irritated you...

  • Doesn't matter if a RTC have battery or not. Your code must still make a decision if you believe it has a valid time or not, when your device boots.

    Next thing is that if you did read the datasheet, you would know that the DS1307 do not have any internal battery. It just supports a battery. Didn't you look at the "Typical operating circuit" picture in the datasheet.

    Third thing is that even if a RTC "has time", it will slowly drift. So you need to give the user a way to correct the time.

    Fourth is that even when the time is perfect, you will either have to replace a battery or (if using a supercap) suffer the results of the battery running dry. So it doesn't matter if the RTC at some point have had a valid time.

    By the way - why ????? or large numbers of .....?

  • It's really very simple:

    Forget the fact that it's a "mysterious" semiconductor chip - just think of it as a clock.
    An ordinary, battery-operated clock.

    If anyone gave you a battery-operated clock, would you just assume that it must have the correct time?

    Of course not! You'd check it - wouldn't you?!

    And you'd keep checking it from time to time - to make sure that the battery was still OK - wouldn't you?!

    And, when the battery finally died, you'd have to re-set the clock after you'd replaced the battery - wouldn't you?!

    No mystery here - just perfectly normal stuff for any battery-operated clock!

  • sir,
    i a using AT89S52 and rtc 1307 for my project. I have made this program to write and read the rtc but when i simulate it and see on lcd it gives me ??:??:?? this type of an output...
    i m not getting what type of mistake i am committing plz help me out to resolve this error.

    #include<reg52.h>
    sfr lcddata=0x90;
    sbit rs=P3^2;
    sbit rw=P3^3;
    sbit en=P3^4;
    sbit SDA=P0^1;
    sbit SCL=P0^0;
    
    
    /*************************delay function*******************************************/
     void delay(unsigned char b)
     {
     unsigned char a;
     for(b;b>1;b--)
     for (a=12;a>1;a--);
     }
     void delay2(unsigned int b)
     {
     unsigned int a,j;
      for(a=0;a<b;a++)
      for(j=0;j<120;j++);
     }
    /************************************Lcd initilization Command Function***********/
    void  command(unsigned  char word)
    {
    en=1;
    rs=0;
    rw=0;
    
    delay(23);
    lcddata=word;
    en=0;
    }
    
    /******************************Display one word************************************/
    void lcddisplay(unsigned word)
    {
    lcddata=word;
    en=1;
    rw=0;
    rs=1;
    delay(5);
    delay(5);
    en=0;
    }
    /***************************display lcd word second line***************************************/
    
    void display(unsigned char *word)
    {
    int x;
    for(x=0;word[x]!=0;x++)
    {
    lcddisplay(word[x]);
    delay(5);
    }
    }
    
    /************************rtc initialaization************************************/
    
    
    
    
    
    void I2c_start(void)
    {
            SDA = 1;
            delay(50) ;
            SCL = 1;                //H-L Pulse
            delay(20) ;
            SDA = 0;
            delay(50) ;
            SCL = 0;
            delay(50) ;
    }
    
    
    
    void I2c_stop(void)
    {
            SCL = 0;
            delay(2) ;
            SDA = 0;
            delay(2) ;
            SCL = 1;                        //  L-H pulse.
            delay(4) ;
            SDA = 1;
            delay(4) ;
            SCL = 0;
    }
    
    void I2c_write(unsigned char out_data)
    {
            unsigned char i;
            for(i=0;i<8;i++)
            {
                    delay(2) ;
                    SDA = ((out_data & 0x80)? 1:0 );                      //checking MSB bit is '0' or'1'
                    out_data <<=1;                                        //used for sending the bit
                    SCL = 1;
                    delay(4) ;
                    SCL = 0;
                    delay(4) ;
            }
            i = SDA;
            delay(2);
            SCL = 1;
            delay(2);
            SCL = 0;
    }
    
    unsigned char I2c_read()
    {
            unsigned char i,in_data;
            in_data = 0x00;                                          //Reset in_data
    
            for(i=0;i<8;i++)
            {
                    in_data <<= 1;
                    SCL = 1;
                    in_data |= SDA;
                    delay(5) ;
                    SCL =0;
                    delay(5) ;
            }
            return (in_data);
    }
    void init()
    {
    
    delay2(200);
    I2c_start();
    I2c_write(0xA0);
    I2c_write(0x00);
    I2c_write(0x00);
                 // data to be sent(Seconds)
        delay(1);
           I2c_write(0x57);//minutes
             delay(1);
    
             I2c_write(0x29);//hours
             delay(1);
             I2c_write(0x07);//days
             delay(1);
             I2c_write(0x02);//date
             delay(1);
             I2c_write(0x07);//month
             delay(1);
    
             I2c_write(0x0B);//year
             delay(1);
            I2c_write(0x83);//control
             delay(1);
    
             I2c_stop();
    
    
    
    
    
    
    }
    
    
    
    
    
    
    
    
    /**************************BCD TO ASCII CONVERT ******************************************/
    
    void bcdconv(unsigned char mybyte)
    {
    unsigned char x, y;
    x = mybyte & 0x0f;
    x = x | 0x30;
    y = mybyte & 0xf0;
    y = y>>4;
    y = y|0x30;
    lcddisplay(y);
    lcddisplay(x);
    }
    /************************main function******************************************/
    
    void main()
    {
    //int k=1,i,l;
    unsigned char hr, min, sec, day, date, month, year;
    
    
    command(0x38);
    command(0x0C);
    command(0x80);
    command(0x01);
    init();
    display("Tishitu welcome");
    while(1)
    {
    
    command(0xC0);
    I2c_start();
    I2c_write(0xA0);
    I2c_write(0x00);
    I2c_start();
    I2c_write(0xA1);
    //hr = Read_EEPROM_byte1(0x02);
    
    
    sec = I2c_read();
    //lcddisplay(sec);
    bcdconv(sec);
    display(":");
    
    min = I2c_read();
    //min = Read_EEPROM_byte1(0x01);;
    bcdconv(min);
    display(":");
    
    hr = I2c_read();
    bcdconv(hr);
    display(":");
    
    day = I2c_read();
    bcdconv(day);
    display(":");
    
    date = I2c_read();
    bcdconv(date);
    display(":");
    
    month = I2c_read();
    bcdconv(month);
    display(":");
    
    year = I2c_read();
    bcdconv(year);
    I2c_stop();
    }
    }
    

  • The whole point of running code in a simulator is so that you can easily step through it and see exactly what is happening internally.

    Doing that, you should be able to see exactly where it writes to the LCD, and what it attempts to write...

  • You don't show enough code.

    One thing: You do

             I2c_write(0x29);//hours
    


    0x29 is obviously not any hours. Why do you use magic numbers like that? Why not make use of a constant saying HOURS_12H|HOURS_AM|9 or similar, to make it more obvious what the line does?

    You use "word" a number of times. But you don't seem to mean it as a word in a sentence. And you don't seem to mean it as a word data type (which is normally the natural size of the accumulator for "larger" processors and normally a 16-bit number size for 8-bit processors).

    If you have a function that prints a string until reaching a terminating zero '\0', then better call the parameter "str".

    If you have a function that takes a numeric value, and the size is not important, then why not call it "num" or "val" or when the number has a specific meaning name the variable based on the meaning?

    What is the meaning of:

    delay(5);
    delay(5);
    


    Doesn't delay(10) solve the problem? By the way - have you made sure that your busy-loop delays actually generate reasonable delays? Stupid busy-loop delays written in a high-level language is very dangerous since the compiler does not promise to produce any code that will actually generate the intended delay. In most situations, the compiler could optimize away the delay. And changes to compiler version or optimization levels can result in huge differences in speed.

    If your BCD conversion results in '?' then your input byte was 0xff - so did you actually manage to read out any values from your 0x30 + 15 -> '?'. By the way: Why write 0x30 instead of '0'? Isn't it better that it is clearly visible that you want to add the offset for the ASCII representation of the digit zero?

  • See: www.8052.com/.../162556

    "changes to compiler version or optimization levels can result in huge differences in speed"

    Even without changing tool versions or optimisation settings, many things could still change the duration of your busy loop.

    Even apparently unrelated source code changes could change the duration of your busy loop.

    And, of course, the delay depends upon the clock frequency and whether the CPU has an "accelerated" core - have you checked these things?

  • "i m not getting what type of mistake i am committing plz help me out to resolve this error."

    you can isolate your problem into 3 parts:

    1) the i2c routines: make sure that your i2c routines work;
    2) the ds1307 routines: once you are sure that your i2c routines work, you can try to make sure that the ds1307 related routines do what they are supposed to do;
    3) the lcd routines: this is distinct and separate from the first two parts and you should just load up some charts and make sure that they are displayed correctly on the lcd.

    once you have those individual parts right, you can try to assemble them together. andrew and per are right in that your current routines, on the first glance, don't seem to be right. but your basic structure is good.

  • thank you so much sir and i understood my mistake i.e. the slave address i was giving shouldn't be 0xA0 and 0xA1 but they should be 0xD0 and 0xD1 respectively...

  • But have you understood all the other issues that have been pointed out...?

  • yes, i have understood how to deal with the problem and it is resolved...
    thank you all for helping me..

  • That wasn't what I asked you - was it?!

    I asked if you had understood all the other issues that have been pointed out.

    Apparently not!