ATmega88 TWI communication with DS3231 not working

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

Hi!

I have a problem with getting my ATmega88 to read time from the DS3231. I am reading the status data through UART on my PC and it seems the MCU sends a repeated start instead of the address to the time register. I have no idea what could be the problem. Could someone point out what am i doing wrong?

I am using USBASP for programming.

Here are the status codes received by the PC:

FF 08 18 10 FE 08 40 D1 D1

FF 40 10 20 FE 20 10 D1 D1

FF 08 18 10 FE 08 40 D1 D1

...

Thank you for any help.

Attachment(s): 

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

Go on.

#define DS3231_ADDRES_WRITE 11010000
#define DS3231_ADDRES_READ 11010001

The DS3231 Slave address is 0xD0 for Write,  0xD1 for Read.  (208 , 209 in decimal)

 

You are using enormous decimal values that are too big for uint8_t.  

 

I suggest that you use a respected library e.g. Fleury's i2cmaster.h

Always use the return values from the library functions.

 

Get your project working.   Then write your own I2C code if you really want.    Personally I would just stick with the "well-written" library.

 

David.

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

Sounds familiar, using 11010000 instead of 0xd0 (or 0b11010000)

https://www.avrfreaks.net/commen...

 

Your other major problem is using

TWCR |=

rather than

TWCR =

 

eg. for start you should do

    TWCR = (1U<<TWINT) | (1U<<TWSTA) | (1U<<TWEN);

for send you should do

    TWCR = (1U<<TWINT) | (1U<<TWEN);

and so on.

 

 

 

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

You also need a i2c_readAck(), and a I2c_readNak() function, as I2C protocol says the master naks the last data byte of a slave read operation, so slave will release the bus to the master.
If you only do readAcks the bus will hang waiting for the slave to send more data it does not have.
Jim

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
get $5 free gold/silver https://www.onegold.com/join/713...

 

 

 

 

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

To use the DS3231, first write the current date and time to the internal registers (be sure that a battery is connected so that this data is not lost when the main power goes off).

This is done with an TWI start, followed by a write of the shifted SLA (0xD0).  The next value sent is the starting register, which is register:0 if you are writing the seconds value and register:01 if you are starting with the minutes.  Seconds, minutes, and hours are in binary-coded-decimal format. 

  Write the second, min, hour, day, date, month, year values and then the configuration value for the alarm and one-second pulse on the SQW pin.

 

To read the time, send TWI start, then write a 0x00 for the seconds register.  Next do an I2C stop and an I2C start with 0xD1.  Now each I2C read will get the data and increment the DS internal register.

 

There should be lots of code examples to do this in either the Projects section or on the web.  There are several working Arduino libraries.  I use the one from Gee Labs which creates an object with all the DS3231 data in about 20 SRAM bytes.