Hi,
I've written a code with CodeVision, so that two AT90CAN128 can
communicate together via TWI. One is the master and the other is
slave, which is interrupt-driven. But something is wrong with it, when I
send a message to the slave he should ACK it. When I disconnect the SDA
line there is no ACK and the code should say Error_write = 1 so that I
know that there has been no communikation. But Error_write is "0" so I
can't be shure, that the communikation is OK or not.
Sorry, that I post the code in this message, but I don't know how to
attach it.
Thanks,
Andreas
Here's the code for the master:
char I2C_Master_Transmitter (char I2C_Adresse, char *msg, char msgsize)
{
char temp = 0x00;
wdt_reset();
Error_write=0x00;
Abbruch = 0x0000;
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
if ((TWSR & 0xF8) != 0x08) // a start condition
transmitted
{
TWDR = I2C_Adresse;
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
if ((TWSR & 0xF8) == 0x18)
{
TWDR = msgsize; // Anzahl der zu sendenden Bytes
soll gesendet werden
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
firsttime = 1;
TIMSK1=0x01; // jetzt erst wird Timer1
freigegeben => erst jetzt blinkt auch die LED CPU_OK
clear_LED_Messtop;
Abbruch = 0x0000;
}
if ((TWSR & 0xF8) == 0x28)
{
for (temp=0;temp<(msgsize-1);temp++)
{
TWDR = msg[temp]; // Anzahl der zu sendenden
Bytes soll gesendet werden
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
} // Ende von for (temp=0;temp<(msgsize-1);temp++)
TWDR = msg[temp++]; // schicken des letzten
Bytes und anschließende Stop-condition
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_write = 1;
goto I2C_write_end;
}
}
Abbruch = 0x0000;
Merker_Komm_Fehler = 0;
}
I2C_write_end:
}
return Error_write;
}
char I2C_Master_Receiver (char I2C_Adresse, char *msg, char msgsize)
{
char i=0x00;
wdt_reset();
Error_read=0x00;
Abbruch = 0x0000;
TWCR = ((1<
initialisieren und abschicken
while (!(TWCR & (1<
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
TWDR = I2C_Adresse;
TWCR = ((1<
while (!(TWCR & (1<
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
while (msgsize > 1)
{
TWCR = ((1<
while (!(TWCR & (1<
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
msg[i] = TWDR;
Merker_Komm_Fehler = 0;
Zaehler_Komm_Fehler = 0;
i++;
msgsize--;
}
TWCR = ((1<
abschicken
while (!(TWCR & (1<
Bestätigung
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 2;
goto I2C_read_end;
}
}
Abbruch = 0x0000;
msg[i] = TWDR;
Merker_Komm_Fehler = 0;
Zaehler_Komm_Fehler = 0;
TWCR = ((1<
I2C_read_end:
return Error_read;
}
And this is the code for the interrupt-driven slave:
// 2 Wire bus interrupt service routine
interrupt [TWI] void twi_isr(void)
{
switch (TWSR & 0xF8)
{
case 0x60: // Own SLA+W received, Ack has been returned
{
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_read_end;
}
}
Abbruch = 0x0000;
M_Read_Size = 1;
M_Komm_Fehler = 0x00;
Zaehler_Komm_Fehler = 0;
break;
}
case 0x80: // Previously adressed with own SLA+W, data
received, ACK returned
{
if (M_Read_Size == 1)
{
temp = TWDR;
M_Read_Size = 0;
i = 0x00;
}
else
{
if (i < temp)
{
I2C_read[i] = TWDR;
i++;
}
}
TWCR = ((1<
}
case 0xA0: // A Stop condition or repeated Start condition has
been received while still adressed as slave
{
TWCR = ((1<
I2C_slave_read_end:
break;
}
/////////////
//Slave Transmitter
////////////
case 0xA8: // Own SLA+R received, ACK has been returned
{
TWDR = I2C_send[0];
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
M_Komm_Fehler = 0x00;
Zaehler_Komm_Fehler = 0;
}
case 0xB8: // Data Byte in TWDR transmitted, ACK has been
received
{
TWDR=I2C_send[1];
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
TWDR = I2C_send[2];
TWCR = ((1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
goto I2C_slave_write_end;
}
}
Abbruch = 0x0000;
}
case 0xC0: // Data Byte in TWDR transmitted, NACK has been
received
{
TWCR = ((1<
j=0x00;
Sende_Daten_2 = 0x00;
}
case 0xC8: // ERROR: Last Data Byte in TWDR transmitted (TWEA
= 0), ACK has been received
{
break;
}
case 0x00:
{
TWCR = ((1 << TWSTO) | (1 << TWINT) | (1<
while (!(TWCR & (1<
{
Abbruch++;
if (Abbruch > I2C_Abbruch)
{
Error_read = 3;
break;
}
}
Abbruch = 0x0000;
}
I2C_slave_write_end:
}
}

(You need to be a member of avrclub -- send a blank email to avrclub-subscribe@yahoogroups.com )