Hallo, Ich betreibe ein 24LC01 an einem LPC1751 per I2C und habe Schwierigkeiten damit. Wenn ich per Debugger durch den Code steppe funktioniert jeder Schreibzugriff auf das EEPROM. Lasse ich jedoch das Programm ganz normal durchlaufen, welches mehrere Dutzend Bytes versucht zu schreiben, gibt es Probleme. Der alte Wert bleibt einfach im EEPROM erhalten. Lesen scheint ganz gut zu funktionieren. Jedenfalls wird immer der korrekte Wert gelesen, wenn ich vorher mittels Debugger das Schreiben ausgelöst habe. Wo ist das Problem? Ich habe mir Haltepunkte an den Endlosschleifen gesetzt, damit ich sehe, wo es eventuell hängen könnte, doch alle Statuscodes scheinen korrekt. Viele Grüße, Lars
>Lasse ich jedoch das Programm ganz normal durchlaufen, welches mehrere >Dutzend Bytes versucht zu schreiben, gibt es Probleme. Und wenn du eine Pause zwischen den Bytes machst?
Hallo, 2 Dinge darfst du nicht machen (sind mir vor ein paar wochen passiert): 1) schreibe bei Page-Write nie über eine Blockgrenze hinaus (bei 24LC01 liegen die bei modulo 128 Byte) 2) warte zwischen zwei Schreibzuriffen mindesten diese ominöse "typical write cycle time" unabhängig davon wieviele Bytes du geschrieben hast. (bei 24lC01 sind das 2 msec) falls jetzt bei I2C kein Fehler ist dann sollte alles gut gehen !!! Eine Anmerkung noch: diese zeilen mit " for (;;); " sind nicht schön !! wenn du auf eine Bedingung triffst nach der sowas steht solltest du die Funktion mit einem Error-Code (z.B. -1) verlassen. (vorher noch ein i2c_stop) Gruss Klaus
Klaus schrieb: > 2 Dinge darfst du nicht machen (sind mir vor ein paar wochen passiert): > > 1) schreibe bei Page-Write nie über eine Blockgrenze hinaus > (bei 24LC01 liegen die bei modulo 128 Byte) Ich schreibe immer nur einzelne Bytes, da die Zugriffsreihenfolge mehr oder weniger zufällig ist. > 2) warte zwischen zwei Schreibzuriffen mindesten diese ominöse "typical > write cycle time" unabhängig davon wieviele Bytes du geschrieben > hast. > (bei 24lC01 sind das 2 msec) Gut, danke für den Hinweis, das werde ich versuchen. Ich melde mich dann wieder. > falls jetzt bei I2C kein Fehler ist dann sollte alles gut gehen !!! Im Datenblatt steht, dass man den Controller durch Polling abfragen kann. Aber auch innerhalb von wenigen us nach dem Schreibzugriff gibt das EEPROM offenbar ein ACK zurück. Sehr seltsam. > Eine Anmerkung noch: > > diese zeilen mit " for (;;); " sind nicht schön !! > > wenn du auf eine Bedingung triffst nach der sowas steht solltest du die > Funktion mit einem Error-Code (z.B. -1) verlassen. (vorher noch ein > i2c_stop) Natürlich. Ich habe diese Zeilen ja aber auch nur deshalb eingefügt, dass ich dort einen Breakpoint im Debugger setzen kann. Ich hatte mir erhofft, so dem Fehler auf die Spur zu kommen.
Ich habe es nun zum Laufen bekommen dank des Tipps Wartezeiten einzufügen. Zusätzlich habe ich den Takt des I2C-Bus auf 10 kHz reduziert. Aber irgendwie bin ich von dem Ganzen noch nicht so wirklich überzeugt, denn das Lesen geht ja schließlich auch ohne diese Wartezeiten. Zumal das Schreiben nun in jedem Falle funktioniert. Ich habe zwar bis zu fünf Wiederholungen für den Fall vorgesehen, dass nachher immer noch der falsche Wert im EEPROM steht, aber bei meinen Tests klappte es immer direkt beim ersten Mal. Auch die I2C-Statuscodes stimmten bei jedem meiner Versuche... Mir erscheint dies aber ziemlich unprofessionell, wer weiß Rat?
Hallo, lese mal ein paar Datenblätter und auch sonstige Informationen zu EEPROM. Dort siehst du dass das Auslesen von EEPROMs keine zeitlichen Probleme macht. Aber das Schreiben: - zuerst kommt alles in einen Puffer (alles IC intern) - dann muss die Speicherstelle gelöscht werden - und dann wird sie neu programmiert und weil das alles für ein einzelnes Byte viel zu aufwändig ist wird das (chip intern) immer für einen ganzen Block gemacht unabhängig wieviel du von dem Block verändert hast. Das Alles daaaaaauuuuuuuuert !!!! Gruss Klaus
Noch was vergessen: Der Takt spielt keine Rolle, den kannst du auf das Maximum 400kHz stellen sofern es deine Harware zulässt (kurze Leitungen, wenig Kapazität etc.)
Klaus schrieb: > lese mal ein paar Datenblätter und auch sonstige Informationen zu > EEPROM. Ich bitte dich, das ist das Erste, was ich tue. Im Datenblatt steht, dass der "Self-timed write cycle" beginnt, sobald das I2C-STOP nach dem Schreibbefehl erkannt wurde. Während das EEPROM dann mit dem Schreiben beschäftigt sei, würde es nicht auf seine Geräteadresse reagieren, deshalb könne man den Datendurchsatz durch Polling maximieren. Und dies ist eben nicht der Fall! Das EEPROM reagiert unmittelbar nach Absetzen des Schreibbefehls auf seine Geräteadresse mit einem ACK und deshalb lässt es sich nicht pollen. Ich kannte den I2C eigentlich immer so, dass ein IC die Taktleitung auf Masse gezogen hält, so lange es noch beschäftigt ist. Dies wäre auch okay, dann bekäme ich einen Fehler beim Versuch ein I2C-START auszugeben. Dies würde sich auch gut abfragen lassen. Aber so? Ich könnte hier vielleicht einen Timer auf 5 ms aufziehen und den nächsten Schreibbefehl erst ausgeben, wenn diese Zeit abgelaufen ist, aber dies gefällt mir eigentlich nicht. Im Datenblatt steht auch nichts davon, dass man sogar Pausen zwischen den einzelnen Bytes machen muss. Andere serielle EEPROM wie das 93LC46 machen solche Probleme nicht: Die halten ihre Ausgabeleitung auf "low" so lange sie schreiben und das Chip Select-Signal anliegt. Sobald das Schreiben fertig ist, geht dann die Ausgabeleitung wieder auf "high". Dies ist auch okay und lässt sich wunderbar abfragen. Verstehe mich bitte nicht falsch, ich sehe ja, dass es auch so funktioniert. Aber ich würde eigentlich erwarten, dass es irgendwie möglich ist, dieses Teil zu pollen. Bloß wie?
Klaus schrieb: > Noch was vergessen: > > Der Takt spielt keine Rolle, den kannst du auf das Maximum 400kHz > stellen sofern es deine Harware zulässt (kurze Leitungen, wenig > Kapazität etc.) Im Datenblatt steht, dass 400 kHz nur bei 5 Volt Versorgungsspannung erlaubt seien. In meinem Falle wird das EEPROM mit 3,3 Volt versorgt. Laut Datenblatt ist hierbei bereits bei 100 kHz Schluss. So viel zum Thema Datenblatt.
Hallo, ich bin leider ein vergesslicher Mensch und weiss nicht mehr wie es mit 24LC01 war. Der letzte IC mit dem ich gearbeitet hab war der 24LC256 vor etwa einem halben Jahr und der zeigte ziemlich das gleiche Verhalten das du bemängelst. Wie das aber ganz genau war weiss ich auch nicht mehr ! Dass er den Bus nicht blockiert (weder SDA noch CLK auf LOW) wenn er beschftig ist gut. Nur er sollte (auch laut Datenblatt) bei jeden "Request" (ob lesen oder schreiben) die "Slave Adresse" mit NACK beantworten wenn er beschäftigt ist. Jetzt hab ich mal in meinem letzten Programm nachgeschaut. Dieses Programm läuft auf einem LPC2148, der offensichtlich eine identische I2C Einheit besitz wie der LPC1751. Du solltest in deinem Status Register nach einem Request entweder >case 0x20: /* MT, SLA+W has been transmitted; NOT ACK has been received. */ oder >case 0x48: /* MR, SLA+R has been transmitted; NOT ACK has been received. */ vorfinden und das ist OK. So steht das in meinem Interrupt-Handler! MT steht für "Master Transmitt" bzw MR für "Master Receive" In beiden Fällen sollte/muss die Übertragung mit I2C_stop abgebrochen werden und der Bus freigegeben werden. Dem nächsten Versuch etwas später steht dann nichts im Weg. Gruss Klaus
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.