Ich versuche, Bit-Banging i2c zu implementieren, um zwischen dem GPIO eines Atmega128A und einem SHT21 zu kommunizieren (I2C-Bus wurde für einige andere Geräte verwendet). Die erste Aufgabe besteht darin, eine Schreibsequenz an das SHT21 zu senden. Mit einem Oszilloskop kann ich sehen, dass die vom Atmega gesendete Sequenz das richtige Startsignal, die richtige Reihenfolge der Bits, das richtige Stoppsignal und die Signalpegel richtig sieht. Der serielle Analysator aus dem Oszilloskop liest die korrekte I2C-Nachricht aus: S80W~A (SHT21-Adresse ist 0x80, Schreiben, also letztes Bit ist 0). Es gibt jedoch keine ACK-Antwort vom SHT21. SDA und SCL werden beide über 6,7-K-Widerstände auf 3,3 V hochgezogen.
Ich brauche wirklich Hilfe, um herauszufinden, was falsch ist.
Code, der das erste Byte wiederholt sendet, wenn kein ACK empfangen wird:
i2c_start();
while(!i2c_send(0x80)){
i2c_stop();
i2c_start();
}
Code des i2c-Protokolls:
void i2c_start ()
{
// Pull data high and sck low to ensure transition of start sequence
DATA_HIGH ();
SCK_HIGH ();
DATA_LOW ();
SCK_LOW ();
}
void i2c_stop ()
{
DATA_LOW ();
SetBit (DDRD, 7);
//pull data high while clck is high to end transmission.
SCK_HIGH ();
DATA_HIGH ();
}
uchar i2c_send (uchar command)
{
uchar i;
for (i = 0; i < 8; i++) // Send command
{
if ((command & 0x80) == 0x80)
DATA_HIGH ();
else
DATA_LOW ();
SCK_LOW ();
SCK_HIGH ();
SCK_LOW ();
command = command << 1;
}
Delay(5);
ClrBit (DDRD, 7); // Change Data Direction
//SetBit (PORTD, 7); // Turn on internal pull-up
//SCK_LOW ();
SCK_HIGH ();
if (!CheckBit (PIND, 7)) // Read ACK
{
SCK_LOW ();
SetBit (DDRD, 7);
return 1;
}
else
{
SCK_LOW ();
SetBit (DDRD, 7);
return 0; // NO ACK
}
}
Laut Ihrem Kommentar sind Ihre GPIO-Pins kein Open-Collector, sondern erzwingen sowohl High als auch Low. I2C erfordert Open-Collector sowohl auf der Takt- als auch auf der Datenleitung. Ohne dies kann der Slave beispielsweise nicht bestätigen, indem er die Datenleitung auf Low zieht (da der Master sie aktiv auf High zieht).
Wenn Sie den Open-Collector-Modus nicht einstellen können, besteht eine andere Möglichkeit darin, das Ausgangsdatenbit niedrig zu lassen und den Pin-Modus zwischen Ausgang (niedrig) und Eingang (effektiv Open-Collector) umzuschalten.
Ignacio Vazquez-Abrams
Benutzer3421560
Nick Alexejew
DoxyLover
Benutzer3421560
Passant
Nick Alexejew