0
\$\begingroup\$

I'm tying to use a atmega2560 but can't get the I2C working. When I send the address byte i get never a ack response. Does anyone see what i'm doing wrong i used the code out of the datasheet? I tried it with a logic analyzer and it works so I do know the IC isn't defect.

void i2csend(uint8_t addr, uint8_t reg, uint8_t data){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
   while(!(TWCR & (1<<TWINT)));
   if ((TWSR & 0xF8) != 0x08)//A  START  condition  has  been transmitted
   {
    stopi2c();
    return;
   }
   TWDR = addr;
   TWCR = (1<<TWINT) | (1<<TWEN);
   while(!(TWCR & (1<<TWINT)));
   if ((TWSR & 0xF8) != 0x18)//SLA+W has been transmitted; 
                               ACK has been received
   {
    stopi2c();
    return;
   }    
   TWDR = reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   if ((TWSR & 0xF8) != 0x28)//Data  byte  has  been  transmitted; 
                               ACK has been received
   {
    stopi2c();
    return;
   }    
   TWDR = data;
   TWCR = (1<<TWINT) | (1<<TWEN);
   while (!(TWCR & (1<<TWINT)));
   if ((TWSR & 0xF8) != 0x28)//Data  byte  has  been  transmitted; 
                               ACK has been received
   {
    stopi2c();
    return;
   }    
   stopi2c();
   return;
}
\$\endgroup\$
1
  • 2
    \$\begingroup\$ A possibly good test to make is to sweep all i2c addresses and see if you get any acks. \$\endgroup\$
    – Wesley Lee
    Mar 25, 2017 at 23:31

1 Answer 1

1
\$\begingroup\$

A common problem when using I2C is to forget about shifting the slave address one bit to the left before using it.

An I2C address is just 7-bits left justified with the R/W bit at the bottom.

You don't say what the slave device is? Are you sure the slave address is correct.

I haven't written i2c code for the atmega2560 but I have for other AVR family members. The last one I did for an atmega328 I used the library from Fleury I2C library.

I found it useful to write an I2C scanner that would attempt to read from all i2c addresses and print out the ones where it received an ACK.

\$\endgroup\$
3
  • \$\begingroup\$ i'm using a pca9685 and here is the image from the datasheet i have connected the others to ground. so that is 0x40. [1]: i.stack.imgur.com/PJNyD.png \$\endgroup\$
    – Dylan
    Mar 26, 2017 at 0:33
  • \$\begingroup\$ Your code doesn't say what is the value of "addr"? I agree the SLA of your device is 0x40. variable "addr" should be 0x80 when you left shift and or in the W bit. (0x81 for a read) \$\endgroup\$ Mar 26, 2017 at 0:47
  • \$\begingroup\$ oh dam forgot about that \$\endgroup\$
    – Dylan
    Mar 26, 2017 at 1:08

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.