Hallo zusammen. Ich habe vor einiger Zeit eine kleine Motorsteuerung entwickelt (für einen Dieselmotor, doch das sollte hier nicht relevant sein). Auf dem Board verwende ich ein EEPROM von Microchip (via I2C) und als uC habe ich einen 8051er von SiLabs. Manchmal habe ich das Problem, dass sich Einstellungen, die im EEPROM abgelegt sind verändern. Grundsätzlich lese ich die Einstellungen immer dann, wenn die Steuerung gestartet wurde. Geschrieben werden sie, bei einer Änderung (über Display-Menu). oder wenn der Motor ausgeschaltet wurde (für die Betriebsstunden) - also ca. 2 bis 20 Schreibvorgänge pro Tag. Ich bin ziemlich erfahren in der Softwareentwicklung und kann somit sagen, dass es kein Interrupt-Problem ist. Auch sonst wird es nicht an einer Software-Fehlfunktion liegen. Ich schreibe jeweils nur ein Byte alle 5ms. Natürlich kann ich die Einstellungen über Redundanz und Checksummen abspeichern. Aber ich möchte gerne wissen, wieso die Datenfehler überhaupt auftreten. Der Controller hat einen internen VDD-Monitor, den verwende ich. Kann mir jemand sagen, woran dies evtl. liegen kann? Besten Dank im Voraus!
Wenn du alle 5ms das gleiche Byte im EEPROM änderst, sind das in der Sekunde 200 Änderungen, in der Stunde schon 720.000, und am Tag 17.280.000 Änderungen! Lies mal im Datenblatt nach, wie oft du ein Byte im EEPROM ändern kannst/darfst, bist es "kaputt" ist.
Benjamin Meier schrieb: > Auf dem Board verwende ich ein EEPROM von Microchip (via I2C) Bei vielen PICs ist der EEPROM mit 1Mio Zyklen spezifiziert. > Ich schreibe jeweils nur ein Byte alle 5ms. D.h. nach ca. 1,5 Stunden hast du die 1Mio erreicht. Typischerweise ist noch etwas Reserve zu den garantierten Werten und es hält etwas länger, trotzdem kann es ist es keine Lösung häufig auf den EEPROM zu schreiben. Daher wird normalerweise der Wert im RAM gepuffert und z.B. beim abschalten geschrieben.
Sorry, hab mich wohl nicht korrekt ausgedrückt. Ich schreibe die gesamten Einstellungen ca. 1 mal am Tag. Das sind evtl. 300 Bytes. Wenn ich diesen Block schreibe, dann werden die 300 Bytes mit einem Abstand von 5ms geschrieben, weil das EEPROM nicht alle Bytes auf einmal schreiben kann.
Benjamin Meier schrieb: > Wenn ich diesen Block schreibe, dann werden die 300 Bytes mit einem > Abstand von 5ms geschrieben, weil das EEPROM nicht alle Bytes auf einmal > schreiben kann. Wartest du immer exakt 5ms oder fragst du ab ob das EEPROM auch fertig ist mit dem Schreiben?
Ich warte immer genau 5ms. Kann man das EEPROM fragen, ob es geschrieben hat?? War mir jedenfalls nicht bekannt!
Das dürfte ein Problem sein, denn im Datenblatt steht bestimmt (ich habe jetzt nicht nachgeschaut) typ. 5ms und nicht max. 5ms. Die Abfrage ist ganz einfach: Das EEPROM ansprechen, meldet es sich mit Ack, ist es fertig, ansonsten kommt ein NAK.
Benjamin Meier schrieb: > Geschrieben werden sie, bei einer Änderung (über > Display-Menu). oder wenn der Motor ausgeschaltet wurde (für die > Betriebsstunden) Ist die Spannungsversorgung noch ausreichend lange (hier 2) stabil? Wird der Chip innerhalb seiner Spezifikation bzg. Temperatur und Betriebsspannung betrieben? Können EMV Einstrahlungen ausgeschlossen werden? Gerade beim abschalten fallen einige Relais ab, die Spannungsspitzen verursachen können. > Ich bin ziemlich erfahren in der Softwareentwicklung und kann somit > sagen, dass es kein Interrupt-Problem ist. Auch sonst wird es nicht an > einer Software-Fehlfunktion liegen. Warum kannst du das ausschließen? Funktioniert es mit anderer Hardware?
OK. Das ACK überprüfe ich, auch um Fehler in der Kommunikation auszuschliessen. Laut Datenblatt ist das Timing auf Max 5ms! Ich sage euch: An der Schreibgeschwindigkeit liegt es sicher nicht!
Ok, dann hast du Glück. Die meisten EEPROMs haben nämlich 10ms max. Da ein EEPROM üblicherweise nicht so einfach zu beschreiben ist (man muss die Adresse des EEPROMs senden usw.) ist es recht unwahrscheinlich, dass der Fehler am EEPROM selbst liegt (v.a. da diese auch diverse Schutzfunktionen integriert haben um sowas zu verhindern, wie z.B. eine Unterspannungserkennung). Viel wahrscheinlicher ist ein Fehler in der Software. Als Workaround könntest du den WriteProtect Pin verwendet, dann hast du einen zusätzlichen Schutz gegen versehentliches Beschreiben.
Als einzige mögliche Probleme sehe ich nocht die Versorgungsspannung, dass das EEPROM Probleme erhält, wenn sich der Glättungs-Elko beim ausschalten entlädt, oder halt EMV. So ein Dieselmotor kann beim Starten schon ziemliche EM-Felder erzeugen. Spitzen von Spulen werden jedoch mit Rücklaufdioden korrekt abgefangen. Einen Fehler in der Software kann ich wohl ausschliessen. Die Daten werden in einen Überlaufgesicherten Ringbuffer geschrieben und von dort im 5ms-Takt abgearbeitet (habe auch schon mit 15ms gearbeitet, machte aber keinen Unterschied). Zudem bin ich, wie gesagt, ziemlich erfahren Punkto Software! Der Datenverlust tritt auch nicht regelmässig auf, Grössenordnung alle 6 Wochen.
Am besten du postest mal Schaltplan und Code, sonst kann dir auch keiner mehr sagen.
Also im Anhang die beiden Codefiles, die die Einstellungen und die Kommunikation mit dem EEPROM abarbeiten. Und das Schema des EEPROM-Teils.
> Spitzen von Spulen werden jedoch mit Rücklaufdioden korrekt abgefangen.
Hast du die Moeglichkeit, dir mit einem Oszi beim Ein- und
Ausschaltvorgang die Spannungsverlaeufe am EEPROM anzusehen? Besonders
die peaks sind dabei natuerlich von Interesse.
Ja die Möglichkeit habe ich sicher wiedermal. Das ganze Gerät ist halt normalerweise im Einsatz, ich mus jeweils warten, bis es zum Service kommt.
Der VDD-Monitor sorgt zwar für einen Neustart der SW bei Unterschreitung eines Spannunglevels, er kann aber nicht einen begonnenen EEPROM-Schreibzugriff in jedem Fall "sauber" beenden. Zwei Möglichkeiten fallen mir ein: 1. Der VDD-Monitor schlägt beim Aussschalten zu und versaut Dir den Schreibzugriff. Es gibt manchmal ein Bit im Controller, wo man herausfinden kann ob es ein Power-on Reset war oder ein VDD-Monitor Reset. Dann könnte man per LED oder ähnlich nachforschen. 2. Der Controller macht einen Reset, dein externes EEPROM aber nicht. Eine angefangene I2C Nachricht kann dann quasi steckenbleiben. Das Problem hatte ich mal mit einem Low-Voltage-fähigen EEPROM. Kann man eigentlich nur lösen, indem man beim Programmstart 20..30 Dummyclocks ausgibt (SDA=1). Dann wird eine Stop-Bedingung erzwungen und man kann sauber starten.
Danke für den Tipp! Werde das bei gelegenheit mal ausprobieren. Das EEPROM kommt tatsächlich bereits mit 1.8V aus, also könnte etwas in der Art (beim Einschalten) der Fall sein. Wobei... Der Schreibzugriff erfolgt eigentlich nie beim Ausschalten des Controllers. Zuerst wird der Motor ausgeschaltet, anschliessend werden die Einstellungen gespeichert, dann dauert es sicher noch min 60s bis die Speisung ausgeschaltet wird!
Interessant ist vor allem die Spannungsversorgung. Ist es im Auto? Dort treten recht heftige Störspitzen auf.
Schau mal im Datenblatt, wo die 1.8V Typen einen internen Power-on Reset machen. Meist ist das im Bereich von etwas über 1V. Und dann messe mal, wie lange VCC auf einem Wert größer dieser Spannung verharrt. Wir hatten mal das Phänomen, das eine Steuerung sozusagen immer eine Ruhepause von 15 min vor dem Neueinschalten brauchte, sonst funktionierte es nicht immer. Das war im Nachhinein betrachtet die Zeit, wo die VCC soweit absank, dass das EEPROM einen Reset der internen State-machine machte. Die Lösung lag in der Verwendung der besagten Dummyclocks. Die Alternative wäre ein Wechsel auf ein anderes EEPROM gewesen, das war in der Serie aber nicht möglich.
Im Datenblatt finde ich nur:
>The WP pin must be connected to either VSS or VCC.
Aber nix von einem internen Pulldown.
In meinem Microchip Dtaenblatt steht das so drin: 2.4 WP This pin can be connected to either Vss, Vcc or left floating. An internal pull-down resistor on this pin will keep the device in the unprotected state if left floating.
In einem Atmel Datenblatt: WRITE PROTECT (WP): The write protect input, when tied to GND, allows normal write operations. When WP is tied high to VCC, all write operations to the memory are inhibited. If left unconnected, WP is internally pulled down to GND. Switching WP to VCC prior to a write operation creates a software write protect function.
Es gibts viele solcher kleinen Unterschiede rund um den WP Pin. Manche Hersteller bauen Pullups/Downs ein, andere nicht. Bei einigen kann man das komplette EEPROM damit schützen, bei anderen nur einen Teil. Wenn das ganze schon in einer derart gestörten Umgebung eingesetzt wird, würde ich mich nicht auf den Pulldown verlassen und stattdessen den Pin ordentlich anschließen. Alleine schon um Probleme auszuschließen, falls die EEPROMs mal von einem Hersteller ohne Pulldown sein sollten. Bzw. ich würde den Pin sogar mit dem µC ansteuern und nur zum Schreiben den Schreibschutz deaktivieren.
Gibt es da verschiedene Versionen von dem IC? hab hier geschaut: http://ww1.microchip.com/downloads/en/DeviceDoc/21189Q.pdf
Sind es genau 300 Bytes die du schreibst? Das passt nämlich sonst nicht mit den internen Puffergrenzen, welche (je nach Typ) ein vielfaches von 32, 64 oder 128 sind. Ich hatte mich schon mal ziemlich lange über die falschen Werte gewundert, die mein EEPROM speichert und hatte diese Blockgrenzen nicht beachtet. Eventuell liegt es bei dir ja auch daran. Sven
> Sind es genau 300 Bytes die du schreibst? Das passt nämlich sonst nicht > mit den internen Puffergrenzen, welche (je nach Typ) ein vielfaches von > 32, 64 oder 128 sind. Ich hatte mich schon mal ziemlich lange über die > falschen Werte gewundert, die mein EEPROM speichert und hatte diese > Blockgrenzen nicht beachtet. Eventuell liegt es bei dir ja auch daran. Ich schreibe ja nicht blockweise, und im Controller verwende ich einen Ringbuffer, dem ist es egal, wie viele Bytes er abarbeiten muss. Sollte also kein Problem sein. > Wenn das ganze schon in einer derart gestörten Umgebung eingesetzt wird, > würde ich mich nicht auf den Pulldown verlassen und stattdessen den Pin > ordentlich anschließen. Ich glaube ehrlich auch nicht, dass es am WP liegt. Der darf nach Datenblatt (ich verwende wie erwähnt das EEPROM von Microchip) offen gelassen werden. Die Störeinflüsse sollten so gross auch nicht sein, der Print liegt quasi in einer Aluminium-Schale, die auf Masse geschlossen ist. Doch wenn der WP das Problem wäre, würde das doch heissen, dass bestimmte Bytes einfach nicht verändert würden. Doch der Effekt, den ich beobachten konnte ist anders: Einzelne Einstellungen (vermutlich nur wenige Bytes) waren plötzlich auf Null (FFh mag auch vorgekommen sein, bin aber nicht sicher). Es ist so, dass die Einstellungen eingentlich nie verändert werden. Sie werden jedoch beim Speichern immer überschrieben und beim Start der Steuerung jeweils gelesen. Möglich wäre, dass beim Lesen ein Fehler auftaucht, den ich nicht bemerke und somit falsche Daten gelesen werden. Dass es ein unvollständiger Schreibvorgang ist, erscheint mir auch wenig wahrscheinlich... Das WP wird jeweils nur einmal pro Write-Zyklus abgefragt. Und die Maschine wird grundsätzlich nie ausgeschaltet. Also werden die Einstellungen nur äusserst selten neu geladen. Die Wahrscheinlichkeit, dass ein Schreibvorgang während dem trennen der Batterie aktiv ist, ist quasi null! Möglicherweise werde ich von nun an jedes Byte mehrfach abspeichern und die einzelnen Kopien unterschiedlich codieren. Diese nach dem Schreiben doppelt kontrollieren und beim Laden der Einstellungen jeweils alle Kopien mehrfach lesen und anschliessend vergleichen. Eine andere Lösung fällt mir zur Zeit nicht ein. Ich werde wohl mal einen Test laufen lassen, bei dem ich das EEPROM über längere Zeit testen kann.
Hallo, so wie Ralf schon zum WP schrieb steht im Microchip Datenblatt: 2.4 Write-Protect (WP) This pin must be connected to either VSS or VCC. If tied to VSS, write operations are enabled. If tied to VCC, write operations are inhibited but read operations are not affected. Wenn du genau den hast, dann MUSS der PIN angeschlossen sein. Und das steht im Datenblatt von Microchip zum 24LC64. Aber alle Vermutungen helfen nicht wenn es nicht getestet ist. Es ist zwar interessant zu sagen, dass es etwas anderes sein müsste und du glaubst, dass es am einen oder anderen nicht liegt, aber es sind eben nur Vermutungen. Mach Dir einen Plan oder Notizen wie du die einzelnen Fehlermöglichkeiten ausschliesen kannst und teste dann. Das führt wahrscheinlich schneller zum Erfolg als von vornherein Dinge auszuschließen ohne zu wissen dass man sie auschließen kann. Nach Murphy sind es eben Fehler die bei 1Mio Stück von Geräten nie auftreten und dann bei einem zum bösen Erwachen führen.
Ich kenne die 24Cxx als sehr störfest, das Schreibprotokoll ist ja recht komplex, daß es kaum ne CPU versehentlich erzeugt, auch bei Unterspannung. Ich vermute ein Softwareproblem. Häng doch an die Daten ne CRC16 ran, das kostet nicht viel. Kann es sein, daß Pakete unvollständig geschrieben werden? Man könnte z.B. 2 Pakete abwechselnd schreiben und als letztes eine aufsteigende Paketnummer. D.h. das mit der höchsten Nummer wurde als letztes und vollständig geschrieben Und vor dem Schreiben der Paketnummer ein Verify der geschriebenen Daten. Ich habe in meinen Projekten bisher nichts davon gemacht und keine Probleme. Ich benutze allerdings den Pagemodus (32 Byte), damit das Schreiben schneller geht. Intern schreibt der EEPROM auch im Bytemodus ne ganze Page, d.h. 31 Byte ungeändert. Peter
>> This pin can be connected to either Vss, Vcc or left floating. > Ich glaube ehrlich auch nicht, dass es am WP liegt. Glauben (und daraus resultierend: Hoffen) haben in der Elektronik eigentlich nichts verloren. Für mich gilt (nach entsprechend schlechter Erfahrung): Niemals ein offener Eingangspin. Aber der WP-Pin dürfte hier nicht dein Problem sein. Du kannst ja noch programmieren, das EEPROM ist nicht blockiert... > Einzelne Einstellungen (vermutlich nur wenige Bytes) waren plötzlich > auf Null (FFh mag auch vorgekommen sein, bin aber nicht sicher). 0x00 ist sehr seltsam, der "gelöschte" Zustand einer EEPROM-Zelle ist 0xFF. Da müsste also nachträglich noch eine 0x00 reinprogrammiert worden sein. Warum bist du so sicher, dass es kein SW-Problem ist? BTW: > Ich bin ziemlich erfahren in der Softwareentwicklung Und dann verwendest du auf einem uC lauter longs :-o
1 | if ((Milliseconds - t_LastWritten) >= 15) |
Da sind schonmal 2 Fehler: 1. Da t_LastWritten nirgends geschrieben wird, läuft Deine Wartezeit nur einmal nach Programmstart ab. 2. Ich nehme mal an, das Milliseconds durch nen Interrupt gesetzt wird und 32bittig ist. Dann mußt Du den Zugriff atomar klammern. Peter
> Die Daten werden in einen Überlaufgesicherten Ringbuffer geschrieben und > von dort im 5ms-Takt abgearbeitet (habe auch schon mit 15ms gearbeitet, > machte aber keinen Unterschied). Laeuft das Schreiben im selben Kontext wie das Einreihen in den Ringbuffer? Wenn nein, der Schreibvorgang ist nicht atomar. Und nach dem geposteten code stimmt das mit dem Ueberlaufschutz auch nicht. Und das mit den 5ms hast du im Griff? Deine Schreibversuche machen keinerlei Fehlerhandling (Fehlercodes zurieckgeben und ignorieren zieht nicht). > Zudem bin ich, wie gesagt, ziemlich erfahren Punkto Software! Nein bist du noch nicht. Cheers, Roger
Dann speichere doch z.B. am Anfang und Ende die Uhrzeit mit ab um genauere Hinweise auf den Fehlerzeitpunkt/Tatort zu bekommen. Es gab schon Leute, die ihr Auto wegen Störstrahlungen aus dem Hafen in Venedig schieben mußten...
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.