Ich bin sehr neu im Konzept von I2C und hatte einige Probleme bei der Verbindung von I2C zwischen 2 Atmega32 (s).
Ich habe einen Atmega32 als Master, an den ein LCD-Bildschirm angeschlossen ist, und einen anderen I2C als Slave, an den ein LM35 angeschlossen ist, und beide Atmega wurden mit den SDA- und SCL-Leitungen verbunden.
Obwohl ich Daten auf dem an den
Master angeschlossenen LCD-Bildschirm erhalte, erhalte ich nicht die richtigen Werte. Als wäre die Temperatur hier 28 Grad Celsius, aber das LCD, das mit dem Master verbunden ist, wiederholt
aus irgendeinem Grund ständig 65280. Kann mir jemand sagen, wo ich falsch liege? Der Code für die Master- und Slave-Geräte wurde
unten veröffentlicht.
Der Mastercode:
int main(void)
{
unsigned int xx=0x00;
unsigned char yy;
DDRA=0xff;
I2C_init(); //I2C initialization
lcd_init(); //LCD initialization
while(1)
{
for (int i=0;i<4;i++) //Getting unsigned int data from slave, so
{ //broke data into 4 parts and receiving
if (i==0) //one byte at a time.
{
I2C_start(0x01); //I2C start along with the address of the slave
yy=I2C_read_ack(); //Read slave data along with an acknowledgment
xx |= (yy << 8);
I2C_stop(); //I2C stop function.
}
else if (i>0)
{
I2C_start(0x01+1); //don't know any particular reason
yy=I2C_read_ack(); //behind this, but if i don't do 0x01+1
xx |= (yy << 8); //then the master ends up reading the
I2C_stop(); //address as a data packet.
}
}
lcd_num(xx); //lcd function to display unsigned int data.
}
}
Der Slave-Code:
Der Slave-Code wiederholt nur eine Funktion immer wieder, also poste ich nicht den ganzen Code, sondern nur die Schnipsel dazwischen.
int main(void)
{
xx=adc_read(0); //reading from ADC0 of the Atmega.
toTransfer = (5.0 * xx * 100.0) / 1024; //calibrating the temperature
if (byte == 1) //send packet 1
{
toSend = toTransfer & mask; //sending the first 8 bits of data.
toTransfer = toTransfer >> 8;//right shift so that the next function will take the 8-16 bits of data.
TWI_match_write_slave(); //I2C function to verify address
TWI_write_slave(toSend); //I2C function to write data on to master
byte = 2;
}
/*Repeating this till byte 4*/
else if (byte == 4) //send packet 4
{
toSend = toTransfer & mask;
toTransfer = toTransfer >> 8;
TWI_match_write_slave();
TWI_write_slave(toSend);
byte = 1;
//initialization for next turn
mask = 0xFF;
toSend = 0;
}
}
Update: Ich habe dies ohne Glück versucht:
unsigned int xx; //I just wrote it here so that you don't have to refer the code again-
unsigned char yy; //-not present in the main loop.
I2C_start(0x01); //yy is receiving data one byte at a time from the slave
yy = I2C_read_ack();
xx = (xx|yy);
xx<<8;
I2C_stop();
Ähnlich verhält es sich mit der else-Anweisung in dem ursprünglich von mir geposteten Code.
Welchen Wert ich auch immer sende, das LCD auf der Empfängerseite zeigt 255 an.
ES KLAPPT!! Nachdem ich also bemerkt hatte, dass das LCD nur 255 und sonst nichts druckt, habe ich mich hingesetzt und darüber nachgedacht. Dann wurde mir klar, dass 255 hexadezimal 0xff ist, was bedeutete, dass die SCL-Leitung nicht lange genug gehalten wurde, damit der Slave Daten übertragen konnte. Also habe ich einfach eine kleine Verzögerung von 100 ms nach der Lesefunktion gesetzt und es hat funktioniert. :D
I2C_start(0x01);
yy = I2C_read_ack();
_delay_ms(100);
getdata=yy; //getdata is just another unsigned char variable. I thought that maybe yy
yy=0; //isn't getting refreshed or something, so i made a small reset sort of thing here.
xx = getdata&zz;
xx<<8;
I2C_stop();
xx<<8;
bringt überhaupt nichts. Wenn Sie xx <<= 8;
es verwenden, wird xx um 8 Bits nach links verschoben.
brhans
brhans
Rohan Narlanka
brhans
Pedro Quadro
Alexxx
Rohan Narlanka
Rohan Narlanka
Rohan Narlanka
Rohan Narlanka
Adithya