2
\$\begingroup\$

I want to establish I2C connection between two atmega2560. First one is working as a master, and second as slave. Master works on a transmitter mode, and Slave works as receiver.
On Master side: Master seems to work correctly, because all code comes from the datasheet. Master is able to send Start condition. When writing the Slave address, it receives a NACK from slave. When that happens, master tries to start from the beginning.

On Slave side: Slave is not able to recognize start condition, and TWINT flag never goes up. Which is why slave status register TWSR never updates and equals to 0xF8.

I'm using electrical schematic from datasheet, 2 pull-up resistors 10kOm. So maybe my slave code is not correct.

schematic

simulate this circuit – Schematic created using CircuitLab


Datasheet says

This occurs between other states, and when the TWI is not involved in a serial transfer.

So that means that slave is not even connected to the TWI lines?

Interesting things happened when I tried to connect master to a RTC D1307. Master is able to send slave address and data, and slave is able to receive them. But only N times. Transmition goes like this: Master sends SLA_R, receives ACK, sends Data, receives ACK. And on first try master only can send 5 times and then SDA line goes low. On second try it can send only 2 times, SDA goes low, 1 time, SDA goes low, 15 times, SDA goes low. And that continues repeatedly.

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);
}
\$\endgroup\$
  • \$\begingroup\$ YOur code is needed to see. \$\endgroup\$ – Passerby Aug 6 '15 at 3:47
2
\$\begingroup\$

Problem was on slave addressing, i forgot to move address to the left in TWAR register. That is why my slave never send me an ACK bit, and also this is the reason why TWINT flag on slave never goes up.

P.S. Question was not correctly asked.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.