DS1307 and writing problem into 56 internal ram

Hi people,
I've got a problem:
I need to write a value's flag into ds1307 ram becouse I need that it remain stored if the power goes off.

I searched by google but I've not foud an explain guide about this.

I.E.

flag = 0

I need that this value will be stored inside ds1307

( and so how reed it ? )

How do that ? I reed that is use an Hex address ( 0x68 is for time ) but I don't understand good.

I'm using DS1307.h library
Thanks in advance

Daniel

Can you clarify which library and version? And do you already have code (its much easier to
give concrete examples relating to existing code)

Conceptually the DS1307 looks like a 64 byte non-volatile RAM with special behaviour of the
first 8 addresses. The I2C interface allows specifying a starting address and then writing or reading
consecutive bytes from that point.

Here are some simple functions I wrote to read and write the DS1307 RAM.

#define DS1307_ADDR 0x68
#define RAM_OFFSET 8         //map logical ram addresses (0-55) to physical addresses (8-63)

//write to DS1307 RAM where addr>=0 and addr<56
void dsSramWrite(byte addr, byte *values, byte nBytes)
{
    Wire.beginTransmission(DS1307_ADDR);
    Wire.write(addr + RAM_OFFSET);
    for (byte i=0; i<nBytes; i++) Wire.write(values[i]);
    Wire.endTransmission();    
}

//read from DS1307 RAM where addr>=0 and addr<56
void dsSramRead(byte addr, byte *values, byte nBytes)
{
    Wire.beginTransmission(DS1307_ADDR);
    Wire.write(addr + RAM_OFFSET);
    Wire.endTransmission();  
    Wire.requestFrom( (uint8_t)DS1307_ADDR, nBytes );
    for (byte i=0; i<nBytes; i++) values[i] = Wire.read();
}

//is the DS1307 oscillator running?
boolean dsIsRunning(void)
{
    byte secRegister;        //seconds register, bit 7 is clock halt (CH) bit
    
    Wire.beginTransmission(DS1307_ADDR);
    Wire.write(0x00);        //seconds register is address zero
    Wire.endTransmission();  
    Wire.requestFrom( DS1307_ADDR, 1 );
    secRegister = Wire.read();
    
    return !(secRegister & 0x80);
}
1 Like

Neat functions. What is the purpose of the isrunning function? Must the RTC clock be stopped to write (or read) into the scratch pad ram locations?

Lefty

retrolefty:
Neat functions. What is the purpose of the isrunning function? Must the RTC clock be stopped to write (or read) into the scratch pad ram locations?

Just quick-and-dirty stuff really, but it gets the job done. I don't think it's an absolute requirement, but yes the usual practice is to stop the RTC while setting the time to avoid any unwanted rollover in the time registers. OTOH, just setting the seconds register first would seem to be safe enough in most cases as this also resets the divider chain.

But in this case I was relying on a library to set the RTC. I use the Time library a lot, and because it syncs with a hardware RTC every 5 minutes (by default), an interesting thing happens. When initially powered up, the RTC's clock is halted. Still, the Time library can read the time from it (usually 1/1/2000 00:00) and then the time as returned by the Time library will advance as normal for the next five minutes. When it syncs with the hardware RTC again, the time snaps back to 1/1/2000 00:00.

I had a sketch where I wanted to ensure the RTC was running so as to avoid this, even if the RTC time was wrong. So in setup() I do

    if (!dsIsRunning()) RTC.set(RTC.get());

which basically leaves the RTC time set to the same value as before, but ensures its clock is running. (The library function RTC.set() stops the RTC clock, sets the time, then starts the clock again.)

An alternative library is available at the address in my signature block that also has functions to read and write the registers, as well as most of the other hardware features of the clock chip.

thank you so much marco_c

D