Archiv verlassen und diese Seite im Standarddesign anzeigen : EEPROM spinnt
mikro-VIIV
19.02.2009, 20:31
Hallo alle zusammen.
Da ich noch einen alten 24C01 mit 128 Byte Speicher rumliegen hatte, wollte ich mal testen, ob ich den zu laufen bekommen. Ich ahbs schon geschaft Daten zu schreiben und zu lesen.
Es kommt nur leider irgendwie nicht so richtig das raus, was ich auch hineingeschrieben habe.
Mein Quelltext sieht wie folgt aus:
$regfile = "m16def.dat"
$crystal = 16000000
$baud = 38400
Config Sda = Portc.1
Config Scl = Portc.0
Config I2cdelay = 10
Dim A As Byte
Dim B As Byte
Dim Lesen As Byte
Dim I As Byte
Do
'---- schreibe in EEprom ----
For A = 1 To 16
I2cstart
I2cwbyte &HA0
I2cwbyte A
For I = 1 To 8
I2cwbyte A
Next I
I2cstop
Waitms 10
Next A
'--- lesen vom EEprom ----
For B = 1 To 16
I2cstart
I2cwbyte &HA0
I2cwbyte B
I2cstart
I2cwbyte &HA1
For I = 1 To 7
I2crbyte Lesen , Ack
Printbin Lesen
Next I
I2crbyte Lesen , Nack
Printbin Lesen
I2cstop
Waitms 50
Next B
Wait 2
Loop
End
Ich schreibe also jeweils acht mal hintereinander die binären werte von 1 bis 16 in das EEPROM.
Raus bekomme ich aber folgendes:
007 007 007 007 007 007 007 015 007 007 007 007 007 007 015 015 007 007 007 007 007 015 015 015 007 007 007 007 015 015 015 015 007 007 007 015 015 015 015 015 007 007 015 015 015 015 015 015 007 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 015 016 015 015 015 015 015 015 016 016 015 015 015 015 015 016 016 016 015 015 015 015 016 016 016 016 015 015 015 016 016 016 016 016 015 015 016 016 016 016 016 016 015 016 016 016 016 016 016 016 016 016 016 016 016 016 016 016
Das ist ja nun nicht ganz das, was ich mir vorgestellt hatte. Sieht irgendwie recht wild aus.
Hab vielleicht jemand ne Ahnung woran das liegen könnte. Ich muss zugeben, dass ich zum ersten mal mit nem EEPROM arbeite. Ist da eventuell ein Fehler in meinem Quelltext? Es kommt immer nur das richtige raus, wenn ich 128 mal den selben Wert ins EEPROM lade.
Ich bin euch für jeden Tipp dankbar!
Ich sehe jetzt nichts was auffällig wäre das da was falsch wäre.
Ich wüsste jetzt auch nicht ob die 10ms schreibzugriff für jeden geschriebenen Byte zählt.
Versuch doch erstmal die Bytes einzeln zu schreiben
$regfile = "m16def.dat"
$crystal = 16000000
$baud = 38400
Config Sda = Portc.1
Config Scl = Portc.0
Config I2cdelay = 10
Dim A As Byte
Dim B As Byte
Dim Lesen As Byte
Do
'---- schreibe in EEprom ----
For A = 1 To 16
I2cstart
I2cwbyte &HA0 ' Adressieren
I2cwbyte A ' Speicheradresse
I2cwbyte A ' Databyte
I2cstop
Waitms 10
Next A
'--- lesen vom EEprom ----
For B = 1 To 16
I2cstart
I2cwbyte &HA0
I2cwbyte B
I2cstart
I2cwbyte &HA1
I2crbyte Lesen , Nack
Printbin Lesen
I2cstop
Waitms 50
Next B
Wait 2
Loop
End
mikro-VIIV
20.02.2009, 17:57
hm... ok, hab ich probiert.
jetzt kommen zumindest schon mal die Werte von 1 bis 16 raus.
Aber ich würde doch ganz gern das gesamte EEPROM beschreiben.
Ich habe jetzt mal alle 8 Byte aller 16 auf 0 gesetzt und dann ausgelesen. Es kamen lauter Nullen.
Dann habe ich das erste Byte jeder Page auf A(siehe Quelltext) gesetzt und jeweils zwei Byte pro Page ausgelesen. Es hätte also 1 0 2 0 3 0 usw. rauskommen müssen. Es kam aber wieder nur Mist raus.
Könnte das vielleicht daraufhinweisen, dass in der Routine zum Auslesen vielleicht ein Fehler steckt?
mikro-VIIV
23.02.2009, 17:42
Hmm... da keiner einen Fehler im Code zu finden scheint und da vielleicht auch gar kein Fehler steckt, ist das zwar einerseits gut, bringt mich aber der Lösung meines Problems leider nicht näher.
Ist es eventuell möglich, dass der EEPROM selber defekt ist? Aber würde sich dann nicht gar nichts mehr tun?
Ich hab auch leider grad keinen anderen da, dass ich es mit einem anderen probieren könnte.
An der Verbindung mit dem AVR kanns nicht liegen oder? Ich hab SCL und SDA über je einen 4,7k Widerstand mit +5V verbunden. Der Widerstand passt doch so oder?
Ansonsten würde mir echt nicht mehr einfallen, woran es noch liegen könnte.
mikro-VIIV
02.03.2009, 20:17
Hallo.
Ich habe mir jetzt einen anderen EEPROM besorgt. Bei diesem habe ich exakt das selbe Problem.
Ich versteh einfach nicht, warum da immer so ein Mist rauskommt und nicht die werte, die ich gespeichert habe.
Irgendwie scheint beim Lesen oder schreiben ein Fehler zu liegen, so dass der Chip immer in ne falsche Page springt oder so.
Ich verzweifle hier bald. Es will und will einfach nicht funktionieren und ich finde absolut keinen Fehler.
Hat von euch noch jemand einen schlauen Einfall, woran es liegen könnte? Was mache ich falsch?
sechsrad
03.04.2009, 14:07
Prüf mal die Pageeinstellung gemäss Datenblatt.
Diese Inner-Schleife:
For I = 1 To 8
I2cwbyte A
Next I
wird da nicht funktionieren.
pacer_one
03.04.2009, 15:04
Wenn kein Fehler im Quelltext, dann schaue mal ob BrownOutDetection in den Fusebits gesetzt ist.
Scheint ein beliebter Fehler zu sein.
mikro-VIIV
03.04.2009, 20:28
Danke für den Tipp, aber leider hat auch das Setzen des Fusebits für die BrownOutDetection keinerlei Verbesserung gebracht.
Prüf mal die Pageeinstellung gemäss Datenblatt.
Diese Inner-Schleife:
For I = 1 To 8
I2cwbyte A
Next I
wird da nicht funktionieren.
Wie meinst du das, ich seh da keinen Fehler. Lasse mich natürlich gern eines besseren belehren.
Hallo!
Ich habe mich vor zig Lahren mit beschreiben von EPROMs und EEPROMs beschäftigt und kann mir nur errinern, dass jedes Byte nach dem Schreiben durchs Lesen verifiziert werden soll und das Schreiben des Bytes so lange wiederholt werden muß, bis die Verifizierung erfolgreich ist.
Das nächste Byte soll erst nach erfolgreicher Verifizierung ins EEPROM geschrieben werden. Die maximale Anzahl der Schreibfersuche (25?) soll nach dem Datenblatt festgelegt werden um die fehlerhafte Bausteine zu erkennen.
Im Code habe ich vereinfachten PAD (Programmablaufdiagramm) skizziert.
Sollte sich in der Zwischenzeit etwas geändert haben, ist mein Beitrag hinfällig.
MfG
Adresse festlegen
Byte festlegen
+-----------------> V
| +-----> Byte Schreiben
| | Byte lesen
| +---|---< j Geschriebenes=Gelesenes?
| | | n
| | | V
| | +---< n Anzahl der Schrebbefehle=Max.? j -> fehlerhaft
| |
| +---------> Nächste Adresse
| Adresse=Max? j -> fertig
| n
| V
| Nächstes Byte
+-----------------< V
sechsrad
04.04.2009, 19:15
Du musst beim Schreiben evtl Pausen dazwischen setzen gemäss Datenblatt.
mfg
mikro-VIIV
05.04.2009, 10:55
Ich hab es jetzt mit Pausen versucht, aber auch das änderte überhaupt nichts. Ich glaube auch nicht, dass beim Lesen oder Schreiben Fehler auftreten, dass also falsche Werte ins EEPROM geschrieben oder gelesen werden.
Hir nochmal mein aktueller Quellcode:
$regfile = "m16def.dat"
$crystal = 16000000
$baud = 38400
Config Sda = Portc.1
Config Scl = Portc.0
Config I2cdelay = 20
Dim A As Byte
Dim B As Byte
Dim Lesen(8) As Byte
Dim I As Byte
Dim X As Byte
Dim Schreiben(8) As Byte
Dim Temp As Byte
I2cinit
Do
X = 1
'---- schreibe in EEprom ----
For A = 1 To 16
I2cstart
Waitms 5
I2cwbyte &HA0
Waitms 5
I2cwbyte A
Waitms 5
For I = 1 To 8
I2cwbyte X
Waitms 5
Incr X
Next I
I2cstop
Waitms 20
Next A
'--- lesen vom EEprom ----
For B = 1 To 16
I2cstart
Waitms 5
I2cwbyte &HA0
Waitms 5
I2cwbyte B
Waitms 5
I2cstart
Waitms 5
I2cwbyte &HA1
Waitms 5
For I = 1 To 7
I2crbyte Lesen(i) , Ack
Waitms 5
Next I
I2crbyte Lesen(8) , Nack
Waitms 5
I2cstop
Waitms 50
For I = 1 To 8
Temp = B * 8
Temp = Temp - 8
Temp = Temp + I
Schreiben(i) = Temp
Next I
'Printbin Schreiben(1)
Printbin Lesen(1)
Next B
Wait 2
Loop
End
Und hier mal das, was ich dann beim lesen erhalte: (jede Zeile entspricht einer Page zu je 8 Byte)
051 052 053 054 055 056 049 114
052 053 054 055 056 049 114 115
053 054 055 056 049 114 115 116
054 055 056 049 114 115 116 117
055 056 049 114 115 116 117 118
056 049 114 115 116 117 118 119
049 114 115 116 117 118 119 120
114 115 116 117 118 119 120 113
115 116 117 118 119 120 113 121
116 117 118 119 120 113 121 122
117 118 119 120 113 121 122 123
118 119 120 113 121 122 123 124
119 120 113 121 122 123 124 125
120 113 121 122 123 124 125 126
113 121 122 123 124 125 126 127
121 122 123 124 125 126 127 128
Für mich sieht das so aus, als würde der EEPROM beim Lesen oder Schreiben "verrutschen". Wie finde ich denn heraus, ob der Fehler beim Lesen oder beim Schreiben liegt, oder ob möglicherweise beide Routinen fehlerhaft sind?
Ich danke euch für eure bisherige Hilfe, auch wenn der Fehler noch immer nicht beseitigt ist.
Bin auch weiterhin für jeden Tipp dankbar.
Zugegeben, mit BASCOM-AVR habe ich mich noch nicht groß beschäftigt, aber bereits länger mit BASCOM 8051. Da gab es Probleme, wenn innerhalb der I2C-Routine etwas anderes gemacht wurde. Deswegen ist es vielleicht den Versuch wert, die Adress- und Werteberechnungen vor i2cstart ablaufen zu lassen. Auch ist meines Wissens nur nach der kompletten Übertragung eine Pause von 10 ms nötig, nicht zwischendurch. Viel Erfolg
dolivo
Suggarman
06.04.2009, 08:17
Ich habe mich kürzlich mit dem Lesen/Schreiben auf ein 24LC256 beschäftigt und ähnliche Probleme gehabt. Das Schreiben im Page-Write-Modus hat einwandfrei funktioniert. Das Lesen jedoch nicht. Mit bascom habe ich es nicht geschafft, ein Byte über I2C zu lesen und direkt auf dem LCD darzustellen (inzwischen klarer, ich nutze nämlich ein I2C-LCD).
Ich lese nun die gesamte page in eine indizierte variable ein und lasse sie dann anzeigen. Das funktioniert einwandfrei:
I2cstop
I2cstart
I2cwbyte Sollwegspeicherwr
I2cwbyte 32
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte Sollwegspeicherrd
For I = 1 To 40
I2crbyte Ascizeichen(i) , Ack
Next
I2cstop
For I = 1 To 40
Lcd Chr(ascizeichen(i) )
Next
mfg
Stefan
mikro-VIIV
07.04.2009, 20:14
Hallo Suggarman,
Danke für den Tipp. Trotzdem ist mir dein Code etwas unklar.
So wie ich das verstehe Schreibst du eine 0 in die 32. Page und ließt dann die ersten 40 Zeichen der Page aus.
Die Ausleseroutine scheint mir aber laut Datenblatt nicht so ganz zu stimmen.
Müsste es nicht in etwa so aussehen:
I2cstop
I2cstart
I2cwbyte Sollwegspeicherwr
I2cwbyte 32
I2cwbyte 0
I2cstop
I2cstart
I2cwbyte Sollwegspeicherwr
I2cwbyte 32
I2cstart
I2cwbyte Sollwegspeicherrd
For I = 1 To 40
I2crbyte Ascizeichen(i) , Ack
Next
I2cstop
For I = 1 To 40
Lcd Chr(ascizeichen(i) )
Next
Korrigiert mich bitte, wenn ich da falsch liegen sollte.
Suggarman
08.04.2009, 11:04
Das 25LC256 besitzt 32768 byte Speicher oder 512 Pages a 64 byte.
Zur Adressierung muss man erst das highbyte und dann das lowbyte übertragen. 32/0 ist also 32*256+0 = 8192 oder 8192/64 = Page 128. Das ist also eine beliebige Adresse des Speichers. Der Code ist so in Ordnung.
mfg
Stefan
mikro-VIIV
09.04.2009, 09:03
Ok, danke Stefan. Da lag ich wohl falsch.
Ich habe meinen Code nun genauso gestaltet wie deine Vorgabe, doch es hat sich nichts geändert. Ich erhalte weiterhin exakt die selbe Ausgabe.
Ich weiß einfach nicht, wo ich noch nach dem Fehler suchen soll.
Ich danke euch riesig für eure Unterstützung bei der Lösung des Problems.
Suggarman
09.04.2009, 12:59
Ich weiß einfach nicht, wo ich noch nach dem Fehler suchen soll.
Mal abgesehen davon, dass das Teil für´s Museum ist.... :-)
Ich habe mir gerade mal das Datenblatt angesehen. Dieser Baustein wird nicht über eine Adresse angesprochen und funktioniert bestimmt nicht richtig mit anderen I2C-Bausteinen zusammen.
Das Teil kann nur 128 byte speichern. Deine Adresse "A0" ist schon außerhalb des Bereiches. Außerdem kann das Ding nur einen "4-byte-page-write", du versuchst aber mehr hineinzuschreiben.
Mein Rat: Deckel auf, Baustein rein, Deckel zu :-)
Kauf dir für kleines Geld einen neuen I2C-Speicher.
mfg
Stefan
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.