hallo Forum, ich beschreibe ein 24C256 EEPROM über die I2C Schnittstelle meines Mega8. Ich hab dazu die I2C-Library von Peter Fleury eingebunden. Meine Schreibvorgänge funktionieren allerdings nicht zu 100% richtig. In dem angehängten Beispielcode lasse ich 150 mal die Zeichenkette 0123456789 hintereinander (beginnend bei Speicherstelle 0) auf das EEPROM schreiben. Wenn ich es danach auslese erhalte ich folgenden EEPROM-Inhalt: :10000000 89894567890123456789012345678901 :10001000 23456789012345678901234567890123 :10002000 45678901234567890123456789012345 :10003000 67890123456789012345678901234567 :10004000 67898945678901234567890123456789 :10005000 01234567890123456789012345678901 :10006000 23456789012345678901234567890123 :10007000 45678901234567890123456789012345 :10008000 1B010123456789012345678901234567 :10009000 890123456789012345678989C234621B :1000A000 4846A2297B01132A1164C234626B4846 ..... Zumeist wird also die richtige Zahlenfolge geschrieben. Der erste Fehler ist aber gleich am Anfang in Zeile 1 (8989 statt 01234). Der zweite folgt dann beim Übergang Zeile 4/5 (67678989). Verzweifele schon fast auf der Suche nach dem Fehler Bin für jeden Hinweis dankbar Dominik
Ach ja - kleiner Fehler in meiner Programmbeschreibung - ich schreib die Ziffernfolge natürlich nicht 150mal, sondern nur so oft, bis ich bei Speicherstelle 150 bin. ist aber egal - an meinem Problem ändert das nichts - das besteht nach wie vor Dominik
..hört sich nach Timingproblem an..?!? Probiers mal testweise langsamer! (Ein paar NOPs einbauen..)
hi dominik, mhm, ein schreibzugriff läuft ja eigentlich wie folgt ab: 1. Device Code auf den I²C Bus 2. Gerät sendet ein ACK 3. Du sendet die Bytes des EEPROM Addressbereichs.. 4. Das EEPROM schickt ein ACK 5. du schickst ein Datenbyte das wird an die angegebene Adresse von dir geschrieben... das EEPROM sendet nach jedem Byte ein ACK 6. Du sendest ein STOP... das wars so jetzt zu deinem Fehler: 0123456789 hintereinander (beginnend bei Speicherstelle 0) auf das EEPROM schreiben. bis Adresse 150 es kann gut sein, dass du zu schnell schreibst! Bzw. zu viele Bytes auf einmal versenden willst. Ein normaler Schreibzyklus dauert bei dieser EEPROM Reihe meist 10 ms. Dann gibt es noch den Page-Mode bei dem mehrere (in einer EEPROM Reihe liegende) Bytes in einem Zyklus geschrieben werden können.. die EEPROM Page ist unterschiedlich von 16 Byte, 32 Byte usw ... das ausgerechnet, das Byte an adresse 0x00 falsch ist, ist seltsam... 1234 5678 90.. das sind ja schon mal 10 Byte... Jetzt wäre es interessant wie du schreibst: Schreibst du alles aufeinmal? Oder wartest du jeweils ein ACK für jeden Schreibauftrag ab? Das das SChreiben auf adresse 0 schief geht, kann eigentlich nur daran liegen, dass etwas mit der adressierung schief gegangen ist.. oder während dem schreiben die bytes (durch timining) probleme so "durcheinander" kommen, dass zwischen durch eine "neu adressierung" statt findet.. is aber sehr unwahrscheinlich
>die EEPROM Page ist unterschiedlich von 16 Byte, 32 Byte usw ...
Und an diesen Pages liegt es vermutlich. Alle Bytes
die man hintereinander sendet müssen in einer Page liegen.
Überschreitet man die Pagegrenze rollt der interne Pagezähler
auf 0 ! über. Schon hat man Bytes an der falschen Adresse.
Also entweder du berücksichtigst die Pagegrenzen, oder
du schreibst immer nur ein Byte. Ein paar ms warten
nach i2c_stop könnte auch nicht schaden. Wie ja oben schon
gesagt dauert das schreiben einige ms. Oder ACK-Polling nach i2c_stop.
hallo, vielen Dank erst mal für die vielen hilfreichen Tips - ich hab mal versucht die Anregungen umzusetzen und meine main.c dahingehend geändert: - statt "0123456789" schicke ich jetzt immer nur noch "0123" an das eeprom zum schreiben. Damit schließe ich aus, dass während eines Schreibvorgangs über die Pagegrenze hinweg geschrieben wird. - ich habe an allen erdenklichen Stellen eine _delay_ms(10) Routine eingefügt. - bei der Switch Anweisung geb ich im Default Fall "F" aus. So ganz hauts seltsamerweise immer noch nicht hin, aber mit den Änderungen konnte ich den Fehler vielleicht noch mal eingrenzen. Beim Auslesen des EEPROMs erhalte ich jetzt: :10000000 F0230123012301230123012301230123 :10001000 01230123012301230123012301230123 :10002000 01230123012301230123012301230123 :10003000 01230123012301230123012301230123 :10004000 F0230123012301230123012301230123 :10005000 01230123012301230123012301230123 :10006000 01230123012301230123012301230123 :10007000 01230123012301230123012301230123 :10008000 F0230123012301230123012301230123 :10009000 01230123012301230123012301230123 :1000A000 01230123012301230123012301230123 :1000B000 01230123012301230123012301230123 :1000C000 F0230123012301230123012301230123 .... Ersichtlich ist hier halt besonders, die Regelmäßigkeit der Fehler an Speicherstelle 0,64,128, .... wäre für eine nochmalige Hilfe sehr dankbar Dominik
Hi habe das selbe Problem mit dem 24C512. Ich verwende den Page-write Modus mit 128 Byte. Bei dir müssten das 64 Byte sein. Ich fange jedoch die Daten über den Parallel Port ab und weiss daher nicht genau, ob es daran oder eben an etwas anderem liegt. Ich habe mal meine Hauptschreibroutine angehängt. (In Timer0-Overflow wird später (wenn keine Daten kommen) noch nen Stop gesendet.) first_word_address und seconde_word_address sind am anfang Null Schreib doch mal i2c_write(0x00) i2c_write(0x00) statt i2c_write( (EEpromPosition/256) ); // write hi address i2c_write( (EEpromPosition%256) ); // write lo address
Hast du das EEPROM auch vor dem schreiben gelöscht? Musst du so viel ich weiß!
>Hast du das EEPROM auch vor dem schreiben gelöscht? Musst du so viel ich >weiß! Nö, muss man nicht. > for (unsigned int k = 0; k <= strlen(OutputString); k++) Es muss k < strlen... heissen.
vielen Dank für die zahlreichen tips - hab aus allen Hinweisen was verwendet und nun gehts. Warum er allerdings bei i2c_write( (EEpromPosition/256) ); // write hi address i2c_write( (EEpromPosition%256) ); // write lo address mit EEpromPosition immer so einen Blödsinn gemacht hat kapier ich nicht wirklich - aber egal, jetzt fang ich halt erst bei Speicherstelle 2 mit meiner Datenaufzeichnung an. grüße Dominik
Sorry aber ich hab mir den Post nich ganz durchgelesen aber ich hatte das Problem auch. Das EEPROM braucht zum schreiben (also bis die Daten wirklich drinnen stehen) 5ms. Wenn du nun immer schreibst dann hat es die 5ms nicht das es wirklich drinnen steht. Wenn du viele Daten innerhalb kurzer Zeit schreiben willst dann musst du ein Pagewrite machen. Da schreibst du einen ganzen String auf einmal. Das EEPROM braucht hier aber auch nur 5ms. LG Andreas
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.