Hallo, Ich bin gerade dabei mit einem Mikrocontroller via SPI einen EEPROM zu beschreiben. Genauer gesagt handelt es sich hierbei um den M95010 EEPROM. Die Kommunikation mit dem EEPROM scheint reibungslos zu verlaufen, da ich auf meine Fragen stets eine Antwort bekomme. Was mich nun verwirrt ist, dass wenn ich an die Adresse 01 einen schreibbefehl sende mit dem Inhalt 00 und diese anschließend auslese, erhalte ich 0x80. Besagtes Beispiel habe ich im Anhang hinzugefügt. Erklärung: 1. Byte = Commandbyte (0x02 = Schreiben, 0x03 = Lesen) 2. Byte = Adressbyte 3. Byte = Databyte Mein Mikrocontroller führt Schreibbefehle aus die Sowohl das Databyte als auch die Adresse jeweils um ein erhöhen. Daraus entstehen die folgenden Werte an Adressen: Adresse Schreibwert Lesewert 0x01.........0x00.........0x80 0x02.........0x01.........0x81 0x03.........0x02.........0x82 ................................ 0x79.........0x7E.........0xFD 0x80.........0x7F.........0xFE 0x81.........0x80.........0x7F 0x82.........0x81.........0x80 ................................ DATA FF wird nie geschrieben + Read DATA wiederholt sich ab 0x80 Ich verstehe nicht so ganz wie dieses Problem zu Stande kommt, da es so scheint als wäre das highest value Bit immer gesetzt aber dann kommt der Ausnahmefall bei Adresse 0x81 wo auf einmal ein Wert von 7F gelesen wird... Falls benötigt kann ich auch Teile meines Codes zeigen, aber da der Schreibwert korrekt funktioniert und der M95010 icht programmierbar ist, sollte das keine mögiche Fehlerquelle sein.
:
Bearbeitet durch User
Mein Glaskugel sagt: Du ignorierst die Pagegrenzen und die Wartezeiten.
Im Datenblatt steht alles nötige. Zuerst mußt Du WREN senden, damit Du schreiben darfst. Dann kannst Du das Statusbyte lesen, ob WEL gesetzt ist.
Hey Peter, Ja klar WREN und Status hab ich natürlich verwendet das hat nur nicht mehr auf den Screenshot gepasst. WEL ist gesetzt wenn ich schreibe. @EAF könntest du das etwas näher erläutern?
Paul Ö. schrieb: > @EAF könntest du das etwas näher erläutern? Bin zwar nicht gefragt worden, antworte aber trotzdem. Nach dem Schreiben tut man (sinngemäss) das hier:
1 | do /* Check EEPROM Busy bit */ |
2 | {
|
3 | SPI_WriteByte (EEPROM_READ_STATUS); |
4 | eep_stat = SPI_ReadByte (); |
5 | } while (eep_stat & 0x01); |
Und Page Boundaries sind zu beachten, wie EAF schon schrub.
Paul Ö. schrieb: > @EAF könntest du das etwas näher erläutern? Ich versuche es..... Paul Ö. schrieb: > Falls benötigt > ..... > sollte das keine mögiche Fehlerquelle sein. Diese Einschätzung.... Angenommen, deine diagnostischen Fähigkeiten wären soweit ausgebildet, dass diese Einschätzung berechtigt ist, dann würdest du diese Frage hier im Forum wohl nicht stellen müssen, sondern könntest das Problem alleine lösen. Das treibt mich zu dem logischen Schluss, dass der Fehler genau in dem steckt, was ausgeblendet wird. Ist nicht zu 100% sicher, aber doch recht wahrscheinlich. EAF schrieb: > Mein Glaskugel sagt: > Du ignorierst die Pagegrenzen und die Wartezeiten. Tipp: Wenn es solche Dinge gibt, sollten sie im Datenblatt erwähnt werden. Da (so ich vermute) dir das unbekannt ist, solltest du das nachholen. Ins besondere dein "fehlerfreies" Schreiben daraufhin kontrollieren.
Ich führe diesen Code nach jedem geschriebenen Byte aus, also sollte der EEPROM idR immer aufnahmefähig sein.
1 | temp = eepromReadStatus(csPin); |
2 | while(temp == 0xFB) |
3 | {
|
4 | temp = eepromReadStatus(csPin); |
5 | };
|
mit den Pagesizes hab ich mich noch nicht groß beschäftigt da werde ich dann gleich mal rein schauen.
:
Bearbeitet durch User
Ich habe den Code mal auf die relevanten Stellen und Funktionen zusammengekürzt.
Paul Ö. schrieb: > mit den Pagesizes hab ich mich noch nicht groß beschäftigt Man macht einmal Write enable, dann schreibt man soviel man braucht bis eine Page-Grenze erreicht ist, dann prüft man das Write-in-progress-Bit bis es gelöscht ist und fängt von vorne an. Innerhalb einer Page musst du nicht dauernd Write enable ausführen, du kannst maximal eine Page mit voller Geschwindigkeit und ohne Handshake schreiben. Deine delay-Routine kommt mir sehr verdächtig vor .... Da gibt es vom Arduino-Framework Besseres.
Was für einen Sinn soll "while(temp == 0xFB)" machen? Es geht doch NUR um das WIP Bit, also fragt man ab, ob (temp & 0x1) wahr oder falsch ist. Am Ende der Schreiboperation werden WIP und WEL automatisch zurückgesetzt, aber ob das gleichzeitig passiert bzw. in welcher Reihenfolge ist nicht spezifiziert. Außerdem sind BP1 und BP0 da irrelvant. Auch die erste Schleife mit "while(temp == 0xF8)" macht keinen Sinn. Entweder ist WEL sofort nach dem Write Enable gesetzt, oder irgendetwas ist schief gelaufen, dann aber weiteres Warten und erneute Statusabfrage sinnlos.
eeprom writer schrieb: > Man macht einmal Write enable, dann schreibt man soviel > man braucht bis eine Page-Grenze erreicht ist, dann > prüft man das Write-in-progress-Bit bis es gelöscht ist > und fängt von vorne an. Ja gut, aber da ich bei jedem Schreibzyklus als erstes Write enable schreibe, sollte ich dieses Problem was ich durch page sizes bekommen könnte umgehen oder verstehe ich da etwas falsch? Klar diese Prozedur kostet Geschwindgkeit aber diese muss ich momentan eh Künstlich drosseln um meinen logic analyser zu nutzen. die delay-Routine wird ausschließlich zur Takt-Synchronisierung verwendet dafür ist es eben wichtig, dass es recht genau ist.
Paul Ö. schrieb: > aber dann kommt der > Ausnahmefall bei Adresse 0x81 wo auf einmal ein Wert von 7F gelesen > wird... Zeige mal deine Schaltung und Aufbau. Da wird wohl noch ein Problemchen versteckt sein. Ein Fehlender Abblock-Kondensator könnte zu solchen "statistischen" zufälligen Fehlern führen.
Seufz, vielleicht war ich oben nicht deutlich genug oder ich habe chinesisch geredet?! Die beiden Abfragen (temp == 0xFB) bzw. (temp == 0xF8) sind einfach grob falsch. BP1 und BP0 im Status Register sind mitnichten '1' und '0'. Das sind die Block Protect Bits, und im Auslieferungszustand i. d. R. beide 0. Das (temp == 0xFB) ist daher NIE richtig, es wird also NIE auf das Ende des Schreibvorgangs gewartet, womit natürlich nur Müll herauskommt.
A. B. schrieb: > Das (temp == 0xFB) ist daher NIE richtig, es wird also NIE auf das > Ende des Schreibvorgangs gewartet .... was durch die sagenhafte delay-Routine noch verschleiert wird. Eigentlich steht's ja schon länger da, aber beratungsresistente Leute sind ja immun gegen solche Hinweise: eeprom writer schrieb: > dann prüft man das Write-in-progress-Bit bis es gelöscht ist
mitlesa schrieb: > Eigentlich steht's ja schon länger da, aber beratungsresistente Ja, sogar mehrfach, aber Lesen ist mittlerweile zur Kunst geworden, die nicht jeder beherrscht. Einfach traurig ... > Leute sind ja immun gegen solche Hinweise:
A. B. schrieb: > Seufz, vielleicht war ich oben nicht deutlich genug oder ich habe > chinesisch geredet?! > > Die beiden Abfragen (temp == 0xFB) bzw. (temp == 0xF8) sind einfach grob > falsch. BP1 und BP0 im Status Register sind mitnichten '1' und '0'. > Das sind die Block Protect Bits, und im Auslieferungszustand i. d. R. > beide 0. > > Das (temp == 0xFB) ist daher NIE richtig, es wird also NIE auf das > Ende des Schreibvorgangs gewartet, womit natürlich nur Müll herauskommt. Wenn du dir den Code mal anschaust wirst du merken dass das im Prinzip Error-Handler sind die das Programm im Fall dass block protect bits gesetzt sind festhalten. Auf diese Art wollte ich sicher gehen, dass das keine Fehlerquelle ist. Außerdem sollte man auf das Ende des Schreibzyklus nicht vor sonder nach dem Schreiben warten was mit delay(writecycle) geschieht :)
:
Bearbeitet durch User
Paul Ö. schrieb: > Wenn du dir den Code mal anschaust wirst du merken ..... Also wir stellen fest: du machst alles richtig, daher kann der Thread ja geschlossen werden.
Hab ich nie gesagt aber ich möchte mich nicht beleidigen lassen für Dinge die das tun was sie sollen.
Paul Ö. schrieb: > Außerdem sollte man auf das Ende des Schreibzyklus nicht vor sonder nach > dem Schreiben warten was mit delay(writecycle) geschieht :) Warum?
Vorrausgesetzt es würde immer ein Writebefehl folgen wäre es egal ob man vor oder nach dem Befehl wartet aber wenn zwischen den Write-Befehlen ein Read-Befehl kommt müsste dieser auch eine Routine aufweisen welche auf die Beendigung eines potentiellen Write-Befehls reagiert. Ist meiner Minung nach etwas umständlich im Vergleich zu einem Warte-Befehl am Ende eines Write-Zyklus
Danke! Ich hatte schon befürchtet, dass die EEPROM-Hardware das braucht.
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.