La bandera TWINT nunca sube

Quiero establecer una conexión I2C entre dos atmega2560. El primero trabaja como amo y el segundo como esclavo. El maestro funciona en modo transmisor y el esclavo funciona como receptor.
En el lado del Maestro: el Maestro parece funcionar correctamente, porque todo el código proviene de la hoja de datos. El maestro puede enviar la condición de inicio. Al escribir la dirección del Esclavo, recibe un NACK del esclavo. Cuando eso sucede, el maestro intenta comenzar desde el principio.

En el lado del esclavo: el esclavo no puede reconocer la condición de inicio y el indicador TWINT nunca se activa. Es por eso que el registro de estado esclavo TWSR nunca se actualiza y es igual a 0xF8 .

Estoy usando el esquema eléctrico de la hoja de datos, 2 resistencias pull-up de 10kOm . Así que tal vez mi código de esclavo no sea correcto.

esquemático

simular este circuito : esquema creado con CircuitLab


La hoja de datos dice

Esto ocurre entre otros estados y cuando el TWI no está involucrado en una transferencia en serie.

¿Entonces eso significa que el esclavo ni siquiera está conectado a las líneas TWI?

Sucedieron cosas interesantes cuando intenté conectar el maestro a un RTC D1307. El maestro puede enviar la dirección y los datos del esclavo, y el esclavo puede recibirlos. Pero solo N veces. La transmisión es así: el maestro envía SLA_R, recibe ACK, envía datos, recibe ACK. Y en el primer intento, el maestro solo puede enviar 5 veces y luego la línea SDA baja. En el segundo intento, puede enviar solo 2 veces, SDA baja, 1 vez, SDA baja, 15 veces, SDA baja. Y eso continúa repetidamente.

void master(){
//init master
DDRC = 0xff;

TWSR = (1<<TWPS0);                  //TWPS = 4
TWBR = 40;                          //F_SLAVE > SCL * 16
TWCR = (1<<TWEN);

uint8_t seconds;
uint8_t minutes;
uint8_t hours;
uint8_t day;
uint8_t date;
uint8_t month;
uint8_t year;
uint8_t address = 0b1101000;        //Slave address

//_delay_ms(2000);
while(1){
    TWIStart();
    if (TW_STATUS == TW_START){
        PORTC ^= 1<<0;
    }

    TWIWrite((address << 1) | READ);
    switch (TW_STATUS) {            
        case TW_MR_SLA_ACK: {
            PORTC ^= 1<<1;              //LEDs for indicating status
            break;
        }
        case TW_MR_SLA_NACK: {
            PORTC ^= 1<<2;
            break;
        }
        default:{
            PORTC ^= 1<<3;
        }
    }


    seconds = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC ^= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC ^= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    minutes = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    hours = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    day = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    date = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    month = TWIRead();
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }
    year = toDec(TWIRead());
    switch (TW_STATUS)
    {
        case TW_MR_DATA_ACK:{
            PORTC |= 1<<4;
            break;
        }
        case TW_MR_DATA_NACK:{
            PORTC |= 1<<5;
            break;
        }

        default:{
            PORTC = 0x00;
        }

    }


    if(year == 15){
        PORTC |= 1<<7;
    }

    TWIStop();
    _delay_ms(1000);
}
Se necesita SU código para ver.

Respuestas (1)

El problema estaba en el direccionamiento del esclavo, olvidé mover la dirección a la izquierda en el registro TWAR . Es por eso que mi esclavo nunca me envía un bit ACK, y también es la razón por la cual el indicador TWINT en el esclavo nunca sube.

PD La pregunta no se hizo correctamente.