I2C en atmega328p

1

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 usando un osciloscopio, incluida la frecuencia del SCL [50Khz]. el registro de estado TWI ** en la final si la declaración es ** 0x20 en lugar de 0x18

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

    
pregunta Engine

1 respuesta

2

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 se debe verificar es si la dirección es válida (no un error de bit off-by-one e incluye el bit R / W correcto). Eventualmente, si el esclavo está configurado correctamente para comunicaciones I2C, no se suspende, etc.

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

    
respondido por el Martin

Lea otras preguntas en las etiquetas