Bad DS1307?

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was working on my project happily when all of a sudden I stopped being able to read hours from my DS1307.  The return is always 0.  Seconds and minutes works flawlessly.  

 

To troubleshoot I created a quick test project of the following - "Fleury library"  This is the write to registers part that runs on startup,

 

{
    //hours
    i2c_start_wait(RTCDevice+I2C_WRITE) ;    
    i2c_write(0x02);                       
    i2c_write(0b00000000);      
    i2c_stop();

    //minutes
    i2c_start_wait(RTCDevice+I2C_WRITE) ;  
    i2c_write(0x01);                        
    i2c_write(0b00000000);      
    i2c_stop();
    
    //Seconds
    i2c_start_wait(RTCDevice+I2C_WRITE) ;  
    i2c_write(0x00);                       
    i2c_write(0b00000000);      
    i2c_stop();
    
    //Years
    i2c_start_wait(RTCDevice+I2C_WRITE) ;   
    i2c_write(0x06);                      
    i2c_write(0b00000000);      
    i2c_stop();
}

 

Then I just keep reading in the loop using -

 

int GetYearData ()
   {
	    i2c_start_wait(RTCDevice+I2C_WRITE) ;    // set device address and write mod
	    i2c_write(0x06);                        // write address = 5
	    i2c_rep_start(RTCDevice+I2C_READ);       // set device address and read mode
	    DataReturn = i2c_readNak();                    // read one byte from EEPROM
	    i2c_stop();
		return (DataReturn - 6 * (DataReturn >> 4));
   }

int GetSecondsData ()
   {
		i2c_start_wait(RTCDevice+I2C_WRITE) ;    // set device address and write mod
	    i2c_write(0x00);                        // write address = 5
	    i2c_rep_start(RTCDevice+I2C_READ);       // set device address and read mode
	    DataReturn = i2c_readNak();                    // read one byte from EEPROM
	    i2c_stop();
		return (DataReturn - 6 * (DataReturn >> 4));
   }

int GetMinutesData ()
{
	i2c_start_wait(RTCDevice+I2C_WRITE) ;    // set device address and write mod
	i2c_write(0x01);                        // write address = 5
	i2c_rep_start(RTCDevice+I2C_READ);       // set device address and read mode
	DataReturn = i2c_readNak();                    // read one byte from EEPROM
	i2c_stop();
    return (DataReturn - 6 * (DataReturn >> 4));
}

int GetHoursData ()
{
	i2c_start_wait(RTCDevice+I2C_WRITE) ;    // set device address and write mod
	i2c_write(0x02);                        // write address = 5
	i2c_rep_start(RTCDevice+I2C_READ);       // set device address and read mode
	DataReturn = i2c_readNak();                    // read one byte from EEPROM
	i2c_stop();	
    return (DataReturn - 6 * (DataReturn >> 4));
}

 

 

 

 

 

 

 

With this, seconds and minutes work fine.  Hours will never progress.

 

 

Thoughts?

Last Edited: Fri. Jan 17, 2020 - 04:12 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is that piece of code supposed to tell us about your problem? The comments aren't exactly correct. Besides, why do you write each individual register? You can do it in one i2c transaction.

How do you read the data from the rtc?

 

[edit] you just posted extra code.....

 

 return (DataReturn - 6 * (DataReturn >> 4));

How is this supposed to work?? Surely it should be:

 return (DataReturn & 0xf + ((DataReturn >> 4) * 10));

 

Last Edited: Fri. Jan 17, 2020 - 04:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Originally I tried it in one i2c transaction but I split it up during troubleshooting when it didn't work.  Ignore the comments, somehow they did not align properly.

 

The original problem (from above) is that the hours register never progresses.  I am reading and writing to the chip correctly, that is what the code is supposed to tell you about the problem.  You may have posted before I updated the post with the read part of the code.

 

(edit)

that is the math for BCD conversion, and works correctly.  The only part that doesn't work is hours register returns 0.  

 

It used to work fine, then as I kept programming it suddenly stopped, then I wrote this as a test.  Even if the math is wrong (it works fine) the register still returns 0, which is the real problem, not the math.

 

Seems odd that a single register in the chip would suddenly stop responding.

Last Edited: Fri. Jan 17, 2020 - 04:28 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Change your default real-time register values to hours = 1, minutes = 59, and seconds = 50.  Now after ten seconds, see if the hours goes to 2, goes to 0, or stays at 1.

 

How do you handle the 12/24 hour bit?

Last Edited: Fri. Jan 17, 2020 - 07:07 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Post your complete project.  e.g. ZIP up the AS7.0 project.   Attach the ZIP.

 

As Simonetta has suggested,   set the registers to 23:59:00 on 31 Dec 2020.

Then you can observe both time and date changing.

 

Quite honestly,  it is easier to read all 6 registers in a single burst.

 

Oh,   and I had never thought of bcd2bin() like that.

 

There is little point in bcd2bin() unless you are performing maths.

If you are just displaying the registers

printf("%02x:%02x:%02x %02x.%02x.20%02x", hour, min, sec, date, month, year);

David.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I’ve tried writing as decimal and I’ve tried the suggestion of writing the time as above.

Keep in mind I’ve written all 0s previous and waited several hours before trying to do the read.

All the results are the same. Seconds and minutes work as expected, hours returns 0.

I’m leaning on the chip somehow being bad, remembering it DID work at some point.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just simply write, then read all registers (something other than default values). One register at a time, or as a group. If you can write/read to all registers with values other than default values you can probably assume your communication is working ok. If they all work except the hours, then I guess that may indicate an internal problem. Not sure how useful this would be, but it may provide more info and would be easy enough to do. Maybe it all works ok, but the hours still does not advance, then there may not be much left to do except to see what another ds acts like with the same code/setup.

 

>but I split it up during troubleshooting when it didn't work

 

One thing to keep in mind, and you probably already know this, is the register values are copied to temp registers on a start condition so you get copies of all registers at a point in time without having to worry about a time change in the read process.  If you ever decide to split up the reads for some reason, then you are in charge of checking whether the seconds has changed while getting all the values you wanted.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've done all of that.  Same result.  Interestingly I also wrote to all of the ram addresses, and some of them return 0 as well.

 

Tomorrow I will swap the chip and report back.