Hallo,
ich habe vor über einen I2C Temperaturfühler mit nem ATMega8 etwa jede
Stunde die aktuelle Temperatur zu messen und anschliessend die Werte im
EEPROM abzuspeichern.
Dazu würde ich gerne das EEPROM, das beim Mega 8 ja 512 Byte groß ist
direkt per Adresse ansprechen. Ich habs mir so gedacht, dass ich an
EEPROM Adresse 0x00 die aktuelle Position speichere an der der "Pointer"
steht. An dieser Position speichere ich dann die Temperatur als Byte (1
Grad Auflösung reicht absolut in einem Bereich von 0 bis 50 Grad).
Anschließend wird der "Zähler" an Adresse 0x00 um 1 erhöht so dass der
Controller nach einem Reset weiß wo die letzte Temperatur geschrieben
wurde.
Also:
Volle Stunde erreicht -> Temperatur per I2C lesen -> aktuellen Zähler
Wert aus dem EEPROM lesen -> Wert an diese Stelle schreiben -> Zähler im
EEPROm erhöhen.
Ist das soweit ok? Und wenn ja, wie spreche ich das EEPROM mit absoluten
Adressen an? Im AVR-GCC Tutorial wird immer mit Variablennamen und
Pointern auf diese gearbeitet - niemals jedoch direkt.
Wäre über Hilfe sehr dankbar.
Eine Lösung (steht auch im Tutorial):
Leg ein 512 byte großes Array ins EEPROM. Auf Index 0 speichertts du die
aktuelle Datenposition. Dann kannst du über den Arrayindex direkt auf
jede einzelne Speicherposition des Arrays, und damit des EEPROMS,
zugreifen.
Oliver
Tim Schneider wrote:
> Volle Stunde erreicht -> Temperatur per I2C lesen -> aktuellen Zähler> Wert aus dem EEPROM lesen -> Wert an diese Stelle schreiben -> Zähler im> EEPROm erhöhen.
Kann man machen, bewirkt aber eine höhere Schreibzyklenbelastung für die
erste Adresse.
Man kann aber auch den EEPROM durchsuchen, bis 0xFF drinsteht, daß ist
dann das erste freie Byte.
> Ist das soweit ok? Und wenn ja, wie spreche ich das EEPROM mit absoluten> Adressen an?
Z.B. so, wie im Datenblatt beschrieben:
Adreßregister laden, Datenregister laden,Schreibimpuls setzen, warten
bis Schreiben fertig.
Peter
Tim Schneider wrote:
> Also:> Volle Stunde erreicht -> Temperatur per I2C lesen -> aktuellen Zähler> Wert aus dem EEPROM lesen -> Wert an diese Stelle schreiben -> Zähler im> EEPROm erhöhen.>> Ist das soweit ok?
Du möchtest anscheinend das Schreiben auf das EEPROM verteilen, damit es
länger hält. Aber was ist bei deinem Szenario mit EEPROM-Speicherzelle
0? Was nützt es, das Schreiben der Daten zu verteilen, wenn jedes
Daten-Schreiben ein zusätzliches Adressen-Schreiben auf immer die selbe
Speicherzelle erzeugt?
> wie spreche ich das EEPROM mit absoluten Adressen an?
/* EEPROM-Speicherzelle 42 auslesen */
data = eeprom_read_byte((uint8_t*)42);
/* EEPROM-Speicherzelle 42 beschreiben */
eeprom_write_byte((uint8_t*)42,99);
@ Peter Dannegger:
> Man kann aber auch den EEPROM durchsuchen, bis 0xFF drinsteht, daß ist> dann das erste freie Byte.
Das funktioniert aber nur max 512 Resets lang. ;-)
Hallo,
danke soweit schonmal für die Antworten :)
Auf die simple Idee ein 512 Byte großes Array anzulegen bin ich bisher
garnicht gekommen...das ist darüber dann natürlich sehr einfach auf die
einzelnen Speicherzellen zuzugreifen.
Ja irgendwie MUSS ich mir wohl oder übel die letze Schreibposition
merken. An Adresse 0 den aktuellen Zähler mitzuschreiben ist wohl
betrachtet auf die Lebensdauer der Speicherzellen wirklich suboptimal.
Alternativ könnte ich mir vorstellen immer ein 0xFF an die übernächste
Position mitzuziehen. Das würde dann die Schreibzugriffe besser
verteilen. Oder halteben ein externes EEPROM mit mehr Speicher nehmen.
Das will ich aber möglichst vermeiden wegen dem Energieverbrauch. Ein
externes EEPROM zieht zwar nicht viel Strom aber doch immer noch etwas.
Im Batteriebetrieb macht sich das bemerkbar denke ich.
VG
Bei ATMEL gibt es eine AppNote, in der ein Verfahren zu gleichmässigen
Auslastung des EEPROMS beschrieben ist. Hab die Nummer gerade nicht
griffbereit, musst halt mal suchen.
Oliver
Du könntest z.B. auch zwei EEPROM-Bytes pro Datenbyte nehmen. Eines
davon als Zähler, und dann erst beim Überlauf des Zählers zur nächsten
2er-Gruppe springen. In EEPROM-Byte 0 könnte dann die Adresse der gerade
aktuellen 2er-Gruppe stehen.
Oliver wrote:
> Bei ATMEL gibt es eine AppNote, in der ein Verfahren zu gleichmässigen> Auslastung des EEPROMS beschrieben ist. Hab die Nummer gerade nicht> griffbereit, musst halt mal suchen.
101
@Stefan Ernst:
Deine Methode mit den zwei EEPROM Bytes pro Datenbyte ist aber nur
einsetzbar wenn man ein einziges Datenbyte speichern will. Mir geht es
ja darum mögichst viele Datenbytes gleichzeitig im EEPROM zu halten.
Ich denke ich komme nicht wirklich daran vorbei eine Speicherzelle immer
wieder als "Zeiger" zu nutzen.
Das Applicaton Note 101 hab ich jetzt schon 5 mal durchgelesen aber es
irgendwie immer noch nicht gecheckt :-D Vielleicht ist es einfach schon
zu spät :)
Tim Schneider wrote:
> Das Applicaton Note 101 hab ich jetzt schon 5 mal durchgelesen aber es> irgendwie immer noch nicht gecheckt :-D Vielleicht ist es einfach schon> zu spät :)
Du packst in das EEPROM zwei Ringpuffer (Funktion ist dir bekannt?),
einen für die Daten und den anderen für einen Zähler. Beide laufen
synchron. Wenn du ein Datenbyte in den Daten-Ringpuffer schreibst,
schreibst du gleichzeitig in den Zähler-Ringpuffer einen fortlaufenden
Wert. Dieser Zählerwert hat mit dem Datenbyte nichts zu tun. Er dient
nur dazu, die aktuelle Position in den Ringpuffern zu markieren. Nach
einem Reset findest du diese Position wieder, indem du im
Zähler-Ringpuffer nach dem größten Wert suchst. Kritisch ist dabei ein
Zählerüberlauf. Damit das auch direkt danach funktioniert, muss der
Zähler-Ringpuffer beim Überlauf einmal komplett genullt werden.
Ah, so einfach kanns also sein, leider schließe ich daraus, dass
natürlich nur die Hälfte das EEPROMS zur Datenspeicherung genutzt werden
kann. Das wären beim MEGA8 dann 256 bytes...könnte eventuell reichen :)
Danke für die Erklärung soweit :-p
Ich würde es einfach so machen, wenn du die Temperatur schreibst, dann
schreib dahinter noch 0xFF, nach einem Reset findest du somit immer die
zuletzt genutzte Position. Dann führst du im Programm noch einen Counter
mit, damit du nicht jedesmal suchen musst.
Natürlich musst du dann noch aufpassen das du bei Byte 512 nicht
versucht 513 mit 0xFF zu beschreiben, aber das ist ja recht easy.
Damit verteilst du die Schreibzugriffe über den ganzen EEPROM bereich.
Bei 24 Werten pro Tag sollte sich die "Abnutzung" in Grenzen halten. ;)
Auch ne gute Idee. Funktioniert aber natürlich nur dann, wenn die
abzulegenden Daten niemals selber 0xFF sind.
PS: Hmm, das ist dann wohl auch das, was Peter Dannegger gemeint haben
könnte. Ich habe ihn da wohl falsch verstanden. ;-)
Ok, 0xFF darf es dann natürlich nicht geben. Je nachdem wie genau du die
Temperaturen willst kannst Du das natürlich "anpassen" ;) So genau sind
die Sensoren sowieso nicht. ;)
Aber das wäre das einzige was mir einfällt um EEPROM-schonend zu
arbeiten und trotzdem den ganzen Bereich zu nutzen.
Grundlegenden würde ich das halt so aufbauen (Nur runtergetippt, keine
Garantie ;)):
Warum macht ihr euch überhaupt Gedanken darüber, den EEPROM-Speicher
"gleichmäßig" auszunutzen? Ein Blick ins Datenblatt verrät, das das
EEPROM 100000 Schreibzyklen verträgt. In der Praxis werden es sogar noch
mehr sein. Wenn also die Werte alle Stunde gespeichert werden müssen, so
sind das pro Jahr(!) nur 8760 Schreibzugriffe. Damit wäre das EEPROM
frühestens nach etwa 11 1/2 Jahren am Ende...
@John Connor: Daran habe ich auch schon gedacht aber es ist ja auch mal
prinzipiell gut sich über solche Dinge Gedanken zu machen!
Ich werde die Variante mit dem 0xFF mitziehen anwenden. So wird bei
dieser Problemstellung der EEPROM optimal genutzt!
Danke an alle hier im Board!