I'm trying to get connect with an IC using I2C, to initialize the I2C communication I'm using the following function :

void init_i2c(void ) {
 uint8_t   twst;
 TWSR = 0;                         // no prescaler
 TWBR = ((F_CPU/SCL_CLOCK)-16)/2; 
 TWCR = (1<<(TWINT))|(1<<TWSTA )|(1<<TWEN);

 printf("TWCR 0x%x \n",TWCR);
 while(!(TWCR & (1<< TWINT)));
 printf(" Start condition has been transmitted \n");
 if( (TWSR&0xF8) != TW_START){
     printf(" Error  at TWSR start 0x%x\n",TWSR);
 // Setting Address 
 TWDR = 0x70; 
 // cleating TWCR 
 TWCR = (1<<TWINT) |(1<<TWEN);
 while (!(TWCR & (1<<TWINT)));
if ((TWSR & 0xF8) != TW_MT_SLA_ACK){
     printf(" Error at TWSR   0x%x    SLA_ACK  0x%x \n", TWSR, TW_MT_SLA_ACK);  // here is the problem !!!!!!!!!  TWSR value should be 0x18
}else {
    printf(" tell now is good \n");

the wiring is good I've measured every pin using an oscilloscope, including the frequency of the SCL[50Khz]. the TWI status register ** at the final if statement is **0x20 instead of 0x18

Any hint what I'm doing wrong here?

  • \$\begingroup\$ Why you are not using a standard frequency like 100kHz or 400kHz. Some I2C devices have timeouts and don't answer properly if the clock is too slow. \$\endgroup\$
    – auoa
    Feb 10, 2017 at 12:08
  • \$\begingroup\$ Because I'm using the uC with 1MHZ \$\endgroup\$
    – Engine
    Feb 10, 2017 at 12:10
  • \$\begingroup\$ @Engine what IC are you trying to communicate with? \$\endgroup\$
    – CHendrix
    Feb 10, 2017 at 12:47
  • \$\begingroup\$ how are you using printf? Is this code on the uC or a desktop console app to talk to the uC? An atmel chip has no stdout just in case you didnt know. \$\endgroup\$
    – crowie
    Feb 10, 2017 at 13:43
  • \$\begingroup\$ Well, 0x20 just means "data transmitted, NACK received". Are you sure your device is ready to receive I2C commands? And your device address is really correct? Maybe you should tell what device it is and/or post your oscillograms. \$\endgroup\$
    – mic
    Feb 10, 2017 at 13:49

1 Answer 1


Status 0x20 is perfectly valid and normal when no device does respond to the address sent. Thus, first thing to check would be if the address is valid (not off-by-one bit error and including correct R/W bit). Eventually if slave is correctly configured for I2C comm, not suspended etc.

What do you see on SDA line using a scope? Is the last bit (acknowledge) low or high? (That is, does AVR not see valid ACK or does slave device fails to acknowledge the address?) Do you use correct slave address? (ie not one-bit-off because mismatch between 7bit and 8bit address formats)

  • 3
    \$\begingroup\$ This is not an answer. I highly suggest reading through the Tour \$\endgroup\$
    – CHendrix
    Feb 10, 2017 at 12:57
  • \$\begingroup\$ Sorry, I was thinking about this a bit, but 1) original question is asking about hint what to do (I believe double checking address and which side generates the problem is quite on the topic), and 2) one can not comment question with less than 50 points (why?), so it was either this or nothing. I can as well delete this post, but I wonder if it makes situation better ... ? \$\endgroup\$
    – Martin
    Feb 10, 2017 at 13:03
  • \$\begingroup\$ in the SDA I see 0x20 \$\endgroup\$
    – Engine
    Feb 10, 2017 at 13:08
  • \$\begingroup\$ Each block is 9 bit long (including ACK bit), what exactly do you mean by 0x20 then? There should be 0b01110000x on SDA line (address 0x70 sent + ACK bit back). \$\endgroup\$
    – Martin
    Feb 10, 2017 at 13:16
  • \$\begingroup\$ Another hint: you are addressing the slave device in 'write' mode. Is it correct? Is it valid to write data into the device? \$\endgroup\$
    – Martin
    Feb 10, 2017 at 13:17

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.