I2C-EEPROM-Bit-Banging: Schreibt gut, aber nur, wenn das erste Bit nicht gesetzt ist

9

Ich arbeite derzeit an einem I2C-EEPROM-Projekt, bei dem Bit-Banging zum Ansteuern der SDA- und SCL-Leitungen verwendet wird.

Meine Lesefunktion funktioniert einwandfrei, aber wenn ich ein Byte mit einer führenden "1" schreibe, lese ich FF immer zurück. auch wenn das Byte zuvor mit etwas anderem programmiert wurde. Führende "0" ist perfekt. Es ist nicht meine Leseroutine; Wie ich auf dem Bereich sehen kann, gibt es FF zurück.

Ich suche nach Vorschlägen, warum dies sein könnte. Gibt es irgendwelche offensichtlichen Fehler, die das Problem verursachen könnten? [Ich kann den Code nicht posten - Firma vertraulich ... :(]

Jede Wellenform, die ich betrachte, entspricht genau der Spezifikation. Ich entkopple das EEPROM. Meine Klimmzüge sind 2,2k, also innerhalb der Spezifikation. Ich takte in diesem Prototyp mit ungefähr 500 Hz. Der Chip sendet ACKs an jedes meiner Bytes, damit er sie erkennt. Aber es funktioniert einfach nicht ...

Ich benutze einen Microchip 24LC256 .

Vereinfachter Schreibalgorithmus für ein Byte:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

Vereinfachter Lesealgorithmus für ein Byte:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte
Thomas O.
quelle
1
@Justin - Ich denke, er sagt, dass das Schreiben des Werts 0x7F in eine beliebige Adresse funktioniert, aber das Schreiben von 0x80 in eine beliebige Adresse nicht funktioniert.
Raketenmagnet
1
Es sind solche Sachen, die mich dazu bringen, I2C zu hassen.
Raketenmagnet
1
Ich habe eine verrückte Ahnung. Sind Sie in Ihrem für jeden Bitcode versehentlich vorzeichenerweiternd mit einer Rechtsverschiebungsoperation? Wenn Sie dann sind, wird Ihr führender Sie nach 7 Schichtoperationen schließlich mit einem 0xFF verlassen.
Vicatcu
3
Die Ironie ist hier der "vertrauliche Unternehmenscode". Es ist für sie wertvoll. Alle anderen hier teilen Code, der funktioniert. Was den Code dieses Unternehmens von den anderen unterscheidet, ist, dass er nicht funktioniert.
Gbarry
2
Es ist schwer vorstellbar, warum ein Unternehmen so dringend I2C-Bit-Banging-Code vertraulich behandeln muss. Es gibt so viel davon im Internet.
Raketenmagnet

Antworten:

4

Sie lesen die Daten, nachdem die Uhr wieder niedrig ist. Sie müssen das tun, um die Uhr hoch und niedrig zu stellen. Nachdem die Uhr niedrig ist, darf der Slave die Datenleitung ändern, nicht solange sie hoch ist.

Geben Sie hier die Bildbeschreibung ein

Das Lesen sollte also so sein:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte
stevenvh
quelle
Das ist ein guter Punkt; Ich werde das beheben. Meine Daten werden jedoch immer noch als All-One (FF) in meinem Bereich
Thomas O
3

Das Problem am Ende stellte sich heraus, dass ich unter bestimmten Bedingungen versehentlich eine STOP-Bedingung gesendet habe, weil das Timing verstümmelt war. Ich gab die Verwendung des Oszilloskops auf, holte den Logikanalysator heraus und konnte das Problem in 15 Minuten beheben, da es den STOP hervorhob, der nicht hätte vorhanden sein dürfen. Ich werde anhand der hilfreichsten Antwort auswählen, wem das Kopfgeld gegeben werden soll. Vielen Dank für alle Lösungen.

Thomas O.
quelle
3
Ich habe dir gesagt, dass dies durch Betrachten der Wellenform gelöst werden würde.
Raketenmagnet
@Rocketmagnet Ich habe immer auf die Wellenform geschaut, sie aber noch nie bemerkt.
Thomas O
Ja, aber Sie haben uns die Wellenform nicht gezeigt , obwohl wir Sie wiederholt danach gefragt haben. Sie hätten dieses Problem schon vor Tagen lösen können.
Raketenmagnet
@ Rocket - ich stimme zu. Ich wünschte, ich hätte damals eine Kamera zur Verfügung. Der von mir verwendete Tek DPO hatte ein Diskettenlaufwerk, aber keine Diskette. Ich hätte ein Bild gepostet, wenn ich hätte.
Thomas O
2

OK, Ihr Bereich beweist, dass das erste Byte, das in den PIC eingeht, schlecht ist, es ist also nicht die PIC-Lesefunktion.

Haben Sie überprüft, ob der Schreibzeitpunkt auf der Empfangsseite in Ordnung ist?

Schlägt dies in beiden Modi unten fehl?

- Byte mode sequential
- Page mode Sequential

Die Spezifikation zeigt "Das wichtigste Bit (MSB) 'b7' wird zuerst gesendet". Dies fällt auch zusammen, wenn b7 = 1 ist, dass das gesamte Byte als FF zurückgelesen wird. Entweder wird es nicht geschrieben und nur gelöscht (Fehlerbedingung), wenn b7 = 1 ist, oder es wird ungeachtet des vorherigen Inhalts schlecht als FF zurückgelesen. Da jedes Schreiben ein byteweites Löschen vor dem Schreiben ist, kann es sich dennoch um ein schlechtes Schreiben oder ein schlechtes Lesen handeln oder das Timing des 1. Bytes ist unterschiedlich.

Vorschlag: Überprüfen Sie das PTC-Signal während eines Schreib- / Lesevorgangs, um den normalen Betrieb sicherzustellen. Geben Sie hier die Bildbeschreibung ein

Es besteht die Möglichkeit, einen externen Takt zum Timing der Länge eines E / W-Zyklus mithilfe von PTC zu verwenden. Haben Sie versucht, dies zu verwenden?

tE / W-Zykluszeit

  • interner Oszillator 7ms typ
  • externe Uhr 4 ~ 10 ms min ~ max

Besteht es diese Kriterien?


quelle
1

Klingt so, als könnten es ein paar Dinge sein:

  1. Was ist noch im Bus? Könnte es einen Buskonflikt mit einem anderen Gerät geben, das zurückgesetzt oder nicht initialisiert wird?
  2. Ändern Sie die Richtung des E / A-Pins korrekt? Wenn es im Ausgangsfall einwandfrei funktioniert, haben Sie möglicherweise versehentlich vergessen, die Richtung des Pins zum Eingang zu ändern, und lesen immer 0xFF. Der Pin könnte als Ausgang für den Bus übrig bleiben, während Sie daraus lesen.
  3. Haben Sie interne Klimmzüge am Pin selbst und / oder an den E / A-Leitungen? Mikrocontroller geben normalerweise einen Widerstandsbereich und keinen festen Wert an. Möglicherweise möchten Sie die Klimmzüge am Mikro deaktivieren und nur die diskreten am Bus verwenden, da Sie mit diskreten Komponenten einen genaueren Klimmzugwiderstand erzielen können.
  4. Taktpolarität - Sind Sie sicher, dass Sie an der rechten Kante / Phase zwischen Takt / Daten messen? Sie könnten ausstempeln, was für Sie im Bereich großartig aussieht, aber wenn die Phase außerhalb der Linie liegt, wird in Ihrem EEPROM nur s 0xFFangezeigt (und es wird höchstwahrscheinlich dasselbe zurückgegeben, da es sich wahrscheinlich um einen ungültigen Befehl / eine ungültige Bedingung handelt).
Joel B.
quelle
1. Nur das EEPROM und die MCU. 2. Ja, ich glaube schon, da das EEPROM in der Lage ist, den SDA / SCL niedrig zu halten. 3. Auf der Platine neben dem EEPROM befinden sich 2,2.000 Klimmzüge mit 5%.
Thomas O
Sind Sie für # 2 sicher, dass das EEPROM dasjenige ist, das den Bus niedrig hält? Hat das EEPROM im Datenblatt Bedingungen, unter denen alle 0xFFs zurückgegeben werden? Siehe auch meine Änderungen oben.
Joel B
# 4. Das EEPROM "ACK" meine Anfragen und arbeitet mit einigen Worten, aber nicht allen.
Thomas O
0

Ich habe dies oben als Kommentar eingereicht, aber mein Vertrauen in die Antwort ist in den tiefen Nischen meines Geistes leise gewachsen, so dass ich es zu einer Antwort mache.

Ich habe eine verrückte Vermutung, dass dies mit ziemlicher Sicherheit ein Softwarefehler auf niedriger Ebene ist, der sich auf die Signiertheit einiger Variablen bezieht. Sind Sie in Ihrem für jeden Bitcode versehentlich vorzeichenerweiternd mit einer Rechtsverschiebungsoperation? Wenn Sie dann sind, wird Ihr führender Sie nach 7 Schichtoperationen schließlich mit einem 0xFF verlassen.

Steven hat in einem Kommentar darauf hingewiesen, aber haben Sie die Heiligkeit Ihrer Schreibvorgänge auf einem Osilloskop gesehen, oder nehmen Sie nur an, dass sie funktionieren, wenn die Hälfte der Rücklesungen gut aussieht? Wenn Sie nicht versucht haben, die Schreiboperation des Werts 0xAA zu betrachten, ist dies möglicherweise eine gute Sache.

Wenn Sie den tatsächlichen Code Ihrer inneren Schleife und die zugehörigen Variablendeklarationen angeben können, können wir möglicherweise einen Fehler erkennen.

vicatcu
quelle
Meine Schriften sind gut; Ich kann das am Umfang sehen. Eine weitere Verrücktheit: Adressen mit führenden MSB sind in Ordnung. Nur Daten verursachen Probleme! Ich denke darüber nach, den Code bald zu veröffentlichen.
Thomas O
1
Zur Unterstützung dieser Antwort: Wenn dies C-Code ist, ändern Sie alle 'char'-Deklarationen in' unsigned char 'und versuchen Sie es erneut.
Wouter van Ooijen