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 ;)):
1 | uint16_t current_pos = 0; |
2 | |
3 | while(eeprom_read_byte((uint8_t*)current_pos) == 0xFF) { |
4 | if(++current_pos == 512) { |
5 | current_pos = 0; |
6 | break; |
7 | };
|
8 | };
|
9 | |
10 | while(1){ |
11 | uint8_t value = get_temp(); |
12 | |
13 | eeprom_write_byte((uint8_t*)current_pos, (value == 0xFF ? 0xFE : value)); |
14 | eeprom_write_byte((uint8_t*)(current_pos==511 ? 0 : current_pos+1), 0xFF); |
15 | |
16 | if(++current_pos == 512) |
17 | current_pos=0; |
18 | |
19 | sleep(1hour); |
20 | };
|
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!
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.