mikrocontroller.net

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


Autor: Dominik (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: bubu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
..hört sich nach Timingproblem an..?!?

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

Autor: Sebastian B. (mircobolle)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dominik (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Elbegucker (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Clemens (Gast)
Datum:

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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Dominik (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Elbegucker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo lag denn nun dein Fehler?

Autor: Andreas Riegebauer (blackpuma)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.