0
\$\begingroup\$

The following code sets the initial state of the RTC sensor:

void DS_setval(void){ // Function to set the time and date
 I2C_start();
 I2C_address(DS1307_ADDR);
 I2C_write(0x00); // Move pointer to 00h register
 //****************************************************************************************************************************************
 //****************************************************************************************************************************************
 // Change according to the time you want to set
 I2C_write(0x80); // Stop the clock don’t write seconds
 I2C_write(decimal2bcd(30)); // Setting minuite = 30
 I2C_write(decimal2bcd(11)); // Setting hour = 11
 I2C_write(decimal2bcd(3)); // Setting day of week = Tuesday
 I2C_write(decimal2bcd(4)); // Setting date = 4
 I2C_write(decimal2bcd(6)); // Setting month = 6
 I2C_write(decimal2bcd(21)); // Setting year = 2021
 I2C_stop();
 msDelay(1);
 I2C_start();
 I2C_address(DS1307_ADDR);
 I2C_write(0x00); // Move pointer to 00h
 I2C_write(decimal2bcd(24)); // Setting seconds = 24
 I2C_stop();
}

In line 55, we shift the pointer to 0x80. Why so? I checked the datasheet of the RTC, and found the following table:

enter image description here

Source: https://pdf1.alldatasheet.com/datasheet-pdf/view/226599/MAXIM/DS1307.html

According to the above table, if we need to assign a value for minute, we need the pointer to be pointing to 0x01H address. Why is it that the code has pointed to 0x80 instead?

Also, why do we assign seconds afterwards? Why not assign it together with the rest of the data?

PS: My university professor gave me this code, I currently cannot contact him regarding this.

SamGibson
18.5k5 gold badges42 silver badges65 bronze badges
asked Oct 15, 2023 at 14:32
\$\endgroup\$
1
  • \$\begingroup\$ Writing 0x80 = Stop the clock. I didn't read the whole datasheet ... Can you update the RTC registers with the clock stopped? \$\endgroup\$ Commented Oct 15, 2023 at 17:04

2 Answers 2

1
\$\begingroup\$

The DETAILED DESCRIPTION section of the DS1307 datashseet contains:

The DS1307 operates as a slave device on the I2C bus. Access is obtained by implementing a START condition and providing a device identification code followed by a register address. Subsequent registers can be accessed sequentially until a STOP condition is executed.

From the question:

According to the above table, if we need to assign a value for minute, we need the pointer to be pointing to 0x01H address. Why is it that the code has pointed to 0x80 instead?

Annotating comments to the start of your code:

I2C_start();
I2C_address(DS1307_address);
I2C_write(0x00); // Sets the register address to 0x00
I2C_write(0x80); // Writes the value 0x80 to register address 0x00 for seconds,
 // and increments the register address to 0x01
I2C_write(decimal2bcd(30))); // Writes the value of decimal2bcd(30) to
 // register address 0x01 for minutes,
 // and increments the register address to 0x02

I haven't annotated comments on all the code, but have tried to explain how registers can be written sequentially in a single I2C data transfer.

answered Oct 15, 2023 at 14:48
\$\endgroup\$
0
\$\begingroup\$

The pointer is not set to 0x80. Pointer is 0x00 and the 0x80 is data.

It simply writes 0x80 to register 0x00.

And this just sets CH bit to 1 and zeroes out seconds.

The code also continues on to write the other time registers sequentially.

answered Oct 15, 2023 at 14:49
\$\endgroup\$
5
  • \$\begingroup\$ How is 0x00 a register address, while 0x80 a piece of data? How do we differentiate ? And how does the compiler do so as well? \$\endgroup\$ Commented Oct 15, 2023 at 16:16
  • 1
    \$\begingroup\$ @MaheshNamboodiri The Slave Receiver Mode (Write Mode) section in the DS1307 datasheet contains After the DS1307 acknowledges the slave address + write bit, the master transmits a word address to the DS1307. This sets the register pointer on the DS1307, with the DS1307 acknowledging the transfer. The master can then transmit zero or more bytes of data with the DS1307 acknowledging each byte received. The register pointer automatically increments after each data byte are written. . The order of I2C_write calls in a transfer differentiates a register address .vs. a piece of data. \$\endgroup\$ Commented Oct 15, 2023 at 17:03
  • 2
    \$\begingroup\$ It's not about the compiler. That is the protocol defined by the RTC chip how to send data to it, and that's how it must be sent. \$\endgroup\$ Commented Oct 15, 2023 at 18:17
  • \$\begingroup\$ Okay. Then in the code I gave, how is the write bit sent ? I don't see it anywhere, explicitly sent. I have edited the body to add the function definition of I2C_Write (), for reference. @ChesterGillon \$\endgroup\$ Commented Oct 16, 2023 at 4:04
  • \$\begingroup\$ @MaheshNamboodiri As per the I2C standard the write bit is sent after the 7-bit slave address. From the DS1307 datasheet The slave address byte contains the 7-bit DS1307 address, which is 1101000, followed by the direction bit (R/W), which for a write is 0. After receiving and decoding the slave address byte, the DS1307 outputs an acknowledge on SDA. After the DS1307 acknowledges the slave address + write bit, the master transmits a word address to the DS1307 \$\endgroup\$ Commented Oct 16, 2023 at 23:04

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.