Forum: Mikrocontroller und Digitale Elektronik Schreiben auf EEPROM - Wo liegt mein Fehler?


von Dominik (Gast)


Angehängte Dateien:

Lesenswert?

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

von Dominik (Gast)


Lesenswert?

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

von bubu (Gast)


Lesenswert?

..hört sich nach Timingproblem an..?!?

Probiers mal testweise langsamer! (Ein paar NOPs einbauen..)

von Sebastian B. (mircobolle)


Lesenswert?

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

von holger (Gast)


Lesenswert?

>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.

von Dominik (Gast)


Angehängte Dateien:

Lesenswert?

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

von Elbegucker (Gast)


Angehängte Dateien:

Lesenswert?

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

von Clemens (Gast)


Lesenswert?

Hast du das EEPROM auch vor dem schreiben gelöscht? Musst du so viel ich 
weiß!

von holger (Gast)


Lesenswert?

>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.

von Dominik (Gast)


Lesenswert?

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

von Elbegucker (Gast)


Lesenswert?

Wo lag denn nun dein Fehler?

von Andreas R. (blackpuma)


Lesenswert?

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
Noch kein Account? Hier anmelden.