1

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?

Engine
  • 669
  • 2
  • 13
  • 29
  • 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. – auoa Feb 10 '17 at 12:08
  • Because I'm using the uC with 1MHZ – Engine Feb 10 '17 at 12:10
  • @Engine what IC are you trying to communicate with? – CHendrix Feb 10 '17 at 12:47
  • 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. – crowie Feb 10 '17 at 13:43
  • 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. – mic Feb 10 '17 at 13:49
  • @crowie "stdout" is a conceptual property of a software environment, not a physical one of a chip. A typical setup around avr-gcc can with a small amount of glue be made to send stdout to an ATmega's UART, and that's often the most effective (or at least common) way to figure out what is going on in such a device, since the debugger interface to the ATmega is proprietarily obscure. – Chris Stratton Feb 10 '17 at 16:21
  • @ChrisStratton I realise that but you need to redefine it in you own code. I don't see how he has done this. Perhaps this is part of the problem he is facing. – crowie Feb 11 '17 at 07:37
  • @crowie - I don't see a "main()" either. It's a *good* thing that the poster has included only the *relevant* code. And no, that *could not* be relevant - the poster is reporting results, so clearly they have a way of getting output, either from the printf() that appears to send it, or from some other mechanism. – Chris Stratton Feb 11 '17 at 17:05
  • @ChrisStratton I am asking how he is using printf() because there is a possibility that using either UART or SPI at the same time as using I2C (TWI) can cause conflicts or errors. I have heard of this happening before. – crowie Feb 12 '17 at 00:46

1 Answers1

2

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)

Martin
  • 1,054
  • 5
  • 10
  • 3
    This is not an answer. I highly suggest reading through the [Tour](http://electronics.stackexchange.com/tour) – CHendrix Feb 10 '17 at 12:57
  • 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 ... ? – Martin Feb 10 '17 at 13:03
  • in the SDA I see 0x20 – Engine Feb 10 '17 at 13:08
  • 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). – Martin Feb 10 '17 at 13:16
  • Another hint: you are addressing the slave device in 'write' mode. Is it correct? Is it valid to write data into the device? – Martin Feb 10 '17 at 13:17
  • @CHendrix : I have reformulated my post to be more answer-like, better now? I'd happily comment on original question, but one can not without points. – Martin Feb 10 '17 at 13:31