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