I2C en atmega328p

Estoy tratando de conectarme con un IC usando I2C, para inicializar la comunicación I2C estoy usando la siguiente función:

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");
}

el cableado es bueno. He medido cada pin con un osciloscopio, incluida la frecuencia del SCL [50Khz]. el registro de estado TWI ** en la declaración if final es ** 0x20 en lugar de 0x18

¿Alguna pista de lo que estoy haciendo mal aquí?

Por qué no está utilizando una frecuencia estándar como 100kHz o 400kHz. Algunos dispositivos I2C tienen tiempos de espera y no responden correctamente si el reloj es demasiado lento.
Porque estoy usando el uC con 1MHZ
@Engine, ¿con qué IC estás tratando de comunicarte?
¿Cómo estás usando printf? ¿Este código está en el uC o en una aplicación de consola de escritorio para hablar con el uC? Un chip atmel no tiene salida estándar en caso de que no lo supieras.
Bueno, 0x20 solo significa "datos transmitidos, NACK recibidos". ¿Está seguro de que su dispositivo está listo para recibir comandos I2C? ¿Y la dirección de su dispositivo es realmente correcta? Tal vez debería decir qué dispositivo es y/o publicar sus oscilogramas.
@crowie "stdout" es una propiedad conceptual de un entorno de software, no física de un chip. Se puede hacer una configuración típica alrededor de avr-gcc con una pequeña cantidad de pegamento para enviar stdout a un UART de ATmega, y esa es a menudo la forma más efectiva (o al menos común) de averiguar qué está pasando en un dispositivo de este tipo, ya que la interfaz del depurador para el ATmega es patentada oscura.
@ChrisStratton Me doy cuenta de eso, pero necesita redefinirlo en su propio código. No veo cómo ha hecho esto. Quizás esto sea parte del problema al que se enfrenta.
@crowie: tampoco veo un "principal ()". Es bueno que el póster haya incluido solo el código relevante . Y no, eso podría no ser relevante: el cartel informa resultados, por lo que claramente tienen una forma de obtener resultados, ya sea desde el printf() que parece enviarlo, o desde algún otro mecanismo.
@ChrisStratton Le pregunto cómo está usando printf() porque existe la posibilidad de que usar UART o SPI al mismo tiempo que usa I2C (TWI) pueda causar conflictos o errores. He oído hablar de esto antes.

Respuestas (1)

El estado 0x20 es perfectamente válido y normal cuando ningún dispositivo responde a la dirección enviada. Por lo tanto, lo primero que debe verificar es si la dirección es válida (no un error de un bit e incluye el bit R/W correcto). Eventualmente, si el esclavo está configurado correctamente para la comunicación I2C, no se suspende, etc.

¿Qué ves en la línea SDA usando un alcance? ¿El último bit (reconocimiento) es bajo o alto? (Es decir, ¿el AVR no ve un ACK válido o el dispositivo esclavo no reconoce la dirección?) ¿Utiliza la dirección esclava correcta? (es decir, no de un bit debido a la falta de coincidencia entre los formatos de dirección de 7 bits y 8 bits)

Esto no es una respuesta. Recomiendo encarecidamente leer el Tour
Lo siento, estaba pensando un poco en esto, pero 1) la pregunta original pregunta sobre qué hacer (creo que verificar dos veces la dirección y qué lado genera el problema es bastante sobre el tema), y 2) uno no puede comentar la pregunta con menos de 50 puntos (¿por qué?), así que era esto o nada. También puedo eliminar esta publicación, pero me pregunto si mejorará la situación...
en el SDA veo 0x20
Cada bloque tiene una longitud de 9 bits (incluido el bit ACK), ¿qué quiere decir exactamente con 0x20 entonces? Debería haber 0b01110000x en la línea SDA (dirección 0x70 enviada + bit ACK de vuelta).
Otra pista: se está dirigiendo al dispositivo esclavo en modo de 'escritura'. ¿Es correcto? ¿Es válido escribir datos en el dispositivo?
@CHendrix: He reformulado mi publicación para que sea más similar a una respuesta, ¿mejor ahora? Me encantaría comentar sobre la pregunta original, pero uno no puede sin puntos.