Kann mir jemand etwas empfehlen? Ich habe eine Schaltung mit Attiny85, daran ist auch nichts zu ändern. Würde das Teil gerne ab und an was in EEPROM schreiben lassen. Schön wäre es dann, wenn man extern bei Bedarf an die gespeicherten EEPROM Werte ran käme. Wie wäre das bei dem Kleinen anzustellen? Vermutlich könnte ich (habe ich noch nicht probieren können) das EEPROM per Programmer auslesen (AVR ISP MK2). Gibt es in dem Fall ein Tool was mir aus der EEP-Datei dann verständliche Werte erzeugt?
avrdude kann das eeprom auch im Binärformat auslesen. Voraussetzung ist natürlich ein ISP Anschluss. avrdude -c stk500v2 -P COM6 -p attiny85 -U eeprom:r:filename.bin:r Folgende Dateiformate gibt es: i Intel Hex s Motorola S-record r raw binary; little-endian byte order, in the case of the flash ROM data e ELF (Executable and Linkable Format), the final output file from the linker; currently only accepted as an input file m immediate mode; actual byte values specified on the command line, separated by commas or spaces in place of the filename field of the ‘-U’ option. This is useful for programming fuse bytes without having to create a single-byte file or enter terminal mode. If the number specified begins with 0x, it is treated as a hex value. If the number otherwise begins with a leading zero (0) it is treated as octal. Otherwise, the value is treated as decimal. a auto detect; valid for input only, and only if the input is not provided at stdin. d decimal; this and the following formats are only valid on output. They generate one line of output for the respective memory section, forming a comma-separated list of the values. This can be particularly useful for subsequent processing, like for fuse bit settings. h hexadecimal; each value will get the string 0x prepended. o octal; each value will get a 0 prepended unless it is less than 8 in which case it gets no prefix. b binary; each value will get the string 0b prepended. Suche dir eins aus!
Lucas schrieb: > Vermutlich könnte ich (habe ich noch nicht probieren können) das EEPROM > per Programmer auslesen (AVR ISP MK2). Auslesen kann man das auf jeden Fall. > Gibt es in dem Fall ein Tool was > mir aus der EEP-Datei dann verständliche Werte erzeugt? Was sind für die verständliche Werte? Da kommt halt Intel-Hex heraus. Welches Tool soll den da was interpretieren können, schließlich weiß nur der Programmierer, was er in welchem Format abgelegt hat.
Meinte damit, dass wenn ich einen uint8 Variable ablege die den Wert "123" enthält, ich die 123 auch wieder dargestellt bekomme.
Lucas schrieb: > Meinte damit, dass wenn ich einen uint8 Variable ablege die den Wert > "123" enthält, ich die 123 auch wieder dargestellt bekomme. Das wäre dann ein "decimal" format. Ist aber sehr ungewöhnlich, Speicherabzüge in diesem Format auszulesen. Das klappt so auch nur mit 8 Bit Werten. Für alle anderen Inhalte musst du dir selbst ein Programm schreiben, das genau weiß, an welcher Stelle was erwartet wird. Du musst hier zwischen den Auslesen des Speichers und der Interpretation/Darstellung der Daten unterscheiden. Das sind zwei separate Dinge.
Lucas schrieb: > Meinte damit, dass wenn ich einen uint8 Variable ablege die den Wert > "123" enthält, ich die 123 auch wieder dargestellt bekomme. Du bekommst halt 0x7B dargestellt, HEX. Wie soll ein Standardprogramm auch wissen, ob du da uint8, uint32 oder vielleicht einen String abgelegt hast? Wenn du es anders haben willst, wirst du dir einen 'Übersetzter' schreiben müssen. Einfach in einem selbst erstellten PC-Programm den File einlesen und entsprechend interpretieren und im gewünschten Format ausgeben.
Nachtrag: Man kann natürlich auch auf mehreren anderen Wegen irgendwelche Werte ausgeben. - seriell mit einem UART, erweiterbar mit einem RS232-Phy, um direkt an eine serielle SS des PCs zu gehen. Das geht auch mit dem Tinyx5. - parallel an den Ports (beim Tinyx5 hat man dann leider nur 5 Bit) Ich hab mir mal mit einer dreistelligen Anzeige und einem Mega8 eine Hilfe geschaffen, die mir parallel ausgegebene Daten eines µC-Ports anzeigt; wahlweise in DEZ oder in HEX. Das könnte man auch auf UART erweitern, so dass man nur einen Portpin benötigt. Zur Anzeige brauchts nur einen Pin, zur Kommunikation ggf. eben zwei.
Möchte nochmal das Thema aufgreifen. Mittels
1 | uint16_t wert_eep EEMEM |
reserviere ich mir Speicher im EEPROM Ich schreibe auf einem Atmega168P den als decimal lautenden Wert: 448. Klappt soweit, wird beim nächsten Programmstart auch wieder als 448 hervorgeholt. Aber, wenn ich mir das EEPROM aus dem AVR auslese erhalte ich folgendes:
1 | :10000000C001FFFFFFFFFFFFFFFFFFFFFFFFFFFF3D |
2 | :10001000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0 |
3 | :10002000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0 |
4 | :10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0 |
5 | :10004000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0 |
6 | :10005000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0 |
7 | :10006000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0 |
8 | :10007000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90 |
9 | :10008000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80 |
10 | :10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70 |
11 | :1000A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60 |
12 | :1000B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50 |
13 | :1000C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 |
14 | :1000D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF30 |
15 | :1000E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF20 |
16 | :1000F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF10 |
17 | :10010000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
18 | :10011000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF |
19 | :10012000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFDF |
20 | :10013000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFCF |
21 | :10014000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFBF |
22 | :10015000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFAF |
23 | :10016000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF9F |
24 | :10017000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF8F |
25 | :10018000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7F |
26 | :10019000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6F |
27 | :1001A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5F |
28 | :1001B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF4F |
29 | :1001C000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3F |
30 | :1001D000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF2F |
31 | :1001E000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1F |
32 | :1001F000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0F |
33 | :00000001FF |
Wo taucht hier die 488 auf? Müsste als HEX dann ja "1C0" lauten. Wie lese ich das also richtig. Nach meinem Verständnis und Wikipedia zum Thema Intel Hex, müsste der Wert vermutlich in der ersten Zeile auftauchen wo hier "C001" steht.
Lucas schrieb: > Wo taucht hier die 488 auf? Müsste als HEX dann ja "1C0" lauten. > Wie lese ich das also richtig. Nach meinem Verständnis und Wikipedia zum > Thema Intel Hex, müsste der Wert vermutlich in der ersten Zeile > auftauchen wo hier "C001" steht. Das ist er auch. Nur eben in der Form LowByte-HighByte.
LSB 0xc0 = 192 dez MSB 0x01 = 256 dez 192+256=448
Lucas schrieb: > Schön wäre es dann, wenn man extern bei Bedarf an die gespeicherten EEPROM > Werte ran käme. Hast du eine LED da dran, die irgendwelche Betriebszustände anzeigt? Mit der könnte man den EEPROM-Inhalt laufend "rausmorsen". Lucas schrieb: > Müsste als HEX dann ja "1C0" lauten. > auftauchen wo hier "C001" steht. Das kommt davon, dass im IntelHex das LSB verdrehterweise zuerst, ganz links kommt:
1 | Adresse 0 1 2 3 4 5 6 7 8 9 a b c d e f |
2 | :10000000C001FFFFFFFFFFFFFFFFFFFFFFFFFFFF3D |
Wenn du das mal umdrehst, dass wie in Zahlensystemen üblich die niederwertige Zahl rechts ist, dann sieht das anders aus und du findest deine 01C0:
1 | Adresse .... 4 3 2 1 0 |
2 | FF FF FF 01 C0 |
:
Bearbeitet durch Moderator
https://de.wikipedia.org/wiki/Byte-Reihenfolge (little-endian vs. big-endian)
:
Bearbeitet durch User
Lothar M. schrieb: > Das kommt davon, dass im IntelHex das LSB verdrehterweise zuerst, ganz > links kommt: >
1 | > Adresse 0 1 2 3 4 5 6 7 8 9 a b c d e f |
2 | > :10000000C001FFFFFFFFFFFFFFFFFFFFFFFFFFFF3D |
3 | > |
Nein, das kommt davon, dass der avr-gcc tatsächlich die little endian Byteorder verwendet. Intel-Hex ist hier völlig unschuldig. Was auch logisch ist, da der Dump byteweise erfolgt und es somit keinerlei Byte-Order gibt. In Motorola-Hex würde der Dump praktisch genauso aussehen. Aber auch dem avr-gcc kann man hier keine Schuld geben, die Wahl von little endian ist eine sehr weise Wahl. So unschön das auch aus der Sicht unwissender Menschen wirkt, für die Verarbeitung auf der Maschine hat es nur Vorteile. Deswegen benutze ich auch in Asm auf dem AVR8 ausschließlich diese Byteorder, obwohl ich hier die freie Wahl habe und nicht der Vorgabe eines Compilers folgen muss.
Danke, soweit hatte ich das verstanden. Jetzt nochmal ein anderes Beispiel: Im EEPROM habe ich Platz für zwei u_int16 Variablen reserviert. Sieht dann so aus: :1000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFC Ich erwarte nach dem Ausleden die Werte 187dec (0xBB) und 23dec (0x23) zu finden. Die sind auch irgendwie da. Aber woher kommt vorangestellt: 0x18 und 0x38. Ausgelesen: :100000001838BB0023FF7FFFFFFFFFFFFFFFFFFF4D
Lucas schrieb: > Ich erwarte nach dem Ausleden die Werte 187dec (0xBB) und 23dec (0x23) > zu finden. Die sind auch irgendwie da. Aber woher kommt vorangestellt: > 0x18 und 0x38. Intel Hex enthält ADRESSEN und Daten. Wenn du die Daten willst, lese als Binary aus oder konvertiere HEX nach BIN. Dann schaue dir mal einen guten Hex Editor an. Ich nehme gerne HDD Hex Editor Neo. Der kann dir gleich die Daten als Zahl anzeigen, wenn du ihm sagst du erwartest hier eine uint16_t o.ä.
:
Bearbeitet durch User
Beitrag #6888355 wurde vom Autor gelöscht.
Lucas schrieb: > Sieht dann so aus: > > :1000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFC > > Ich erwarte nach dem Ausleden die Werte 187dec (0xBB) und 23dec (0x23) > zu finden. Die sind auch irgendwie da. Aber woher kommt vorangestellt: > 0x18 und 0x38. > > Ausgelesen: > :100000001838BB0023FF7FFFFFFFFFFFFFFFFFFF4D Erst mal ein bißchen Ordnung:
1 | HEX file: |
2 | :10 0000 00 0000 0000 FFFF FFFF FFFFFFFFFFFFFFFF FC |
3 | ^ ^ ^ ^ |
4 | | | | | |
5 | Adr_0 Adr_1 Adr_2 Adr_3 (Gilt für integer) |
6 | | | | | |
7 | Ausgelesenes EEPROM nach programmieren: |
8 | :10 0000 00 1838 BB00 23FF 7FFF FFFFFFFFFFFFFFFF 4D |
Wie du siehst, zeigt EEPROM etwas anderes als es soll. Ich nehme folgendes an: Dein EEPROM dump ist nicht nach programmieren, sondern nach Programmstart entstanden. Den ersten Wert (0xBB) hat dein Programm auf Adresse 0x01 als Integer reingeschrieben. Den zweiten Wert (0x23) hat dein Programm auf Adresse 0x02 als Byte reingeschrieben. Und nur der liebe Gott weiß, was du da auf Adressen 0x00 und 0x03 reingeschrieben hast und warum - ich weiß es nicht.
:
Bearbeitet durch User
c-hater schrieb: > Deswegen benutze ich auch in Asm auf dem AVR8 ausschließlich diese > Byteorder, obwohl ich hier die freie Wahl habe und nicht der Vorgabe > eines Compilers folgen muss. Sowohl die 16-Bit-Pointer in X,Y, Z, als auch der SP und die Operanden und Ergebnisse der 16-Bit-Operationen haben Little Endianess. Ja, man könnte big Endianess nutzen, aber so ganz natürlich ist das dann doch nicht. Oliver
Oliver S. schrieb: > Sowohl die 16-Bit-Pointer in X,Y, Z, als auch der SP und die Operanden > und Ergebnisse der 16-Bit-Operationen haben Little Endianess. Ich stelle mir ein Register als eine Reihe von Schaltern vor. Ist es nicht völlig egal, in welche Reihenfolge diese montiert wurden, weil von außen sowieso niemand hinein schauen kann? Egal ob der Schalter "Bit 0" nun links oder rechts angebracht wurde, es bleibt "Bit 0" mit der selben Funktion. Meiner Meinung nach spielt die Reihenfolge der Bits nur bei serieller Kommunikation eine Rolle.
Marc V. schrieb: > Den ersten Wert (0xBB) hat dein Programm auf Adresse 0x01 als > Integer reingeschrieben. Oder als Byte, gleiches Ergebnis.
Stefan ⛄ F. schrieb: > Meiner Meinung nach spielt die Reihenfolge der Bits nur bei serieller > Kommunikation eine Rolle. Je nun… All die 16-Bit-Register sind ja keine kontextlosen Bitfolgen, sondern stellen aus 2 Byte zusammengesetzten 16-Bit-Adresspointer dar. Dabei spielt die Reihenfolge der Bytes (um die geht es hier) halt doch eine entscheidende Rolle. Oliver
Oliver S. schrieb: > abei > spielt die Reihenfolge der Bytes (um die geht es hier) halt doch eine > entscheidende Rolle. Ach so, du mein Paare wie R25:R24 für eine Adresse. Da leuchtet mir der Unterschied zu R24:R25 ein.
Irgendwie scheint mir das ganze für meine zwei benötigten EEPROM-Werte nicht so recht reproduzuierbar wie erhofft. Mal erhalte ich diese Darstellung: :100000000600BD00FFFFFFFFFFFFFFFFFFFFFFFF39 (erwartet wurde 6 und 189) und mal diese :1000000000002E01FFFFE7FFFFFFFFFFFFFFFFFFE5 (erwartet wurde 0 und 302, aber was macht E7 da?) Egal, kann ich mein Programm zwingen, meine Werte geziehlt an bestimmte Adressen zu schreiben? Damit ich für mich weiß an welcher Adresse ich immer welche Variable erwarten kann. So sieht der Umgang im Programm aus (exemplarisch für einen der beiden Werte):
1 | uint16_t sollwert_eep EEMEM; |
2 | uint16_t sollwert |
3 | sollwert = eeprom_read_word(&sollwert_eep); |
4 | //im Programm irgendwas rechnen und vergeleichen
|
5 | eeprom_update_word(&sollwert_eep, sollwert); |
Lucas schrieb: > Egal, kann ich mein Programm zwingen, meine Werte geziehlt an bestimmte > Adressen zu schreiben? Damit ich für mich weiß an welcher Adresse ich > immer welche Variable erwarten kann. Das könnte man, macht aber wenig Sinn, da die Wahrscheinlichkeit, dass man sich verrechnet, recht groß ist. Ich halt es für klüger, das dem Compiler zu überlassen Natürlich kann man sich dann auch alle Adressen, in Form einer Liste, ausgeben lassen und an die Wand tackern. Die Struktur hat gegenüber EEMEM den Vorteil(?) dass keine ungenutzten Variablen wegoptimiert werden und die Größe/Anordnung bei der Übernahme von AVR zu AVR unverändert erhalten bleibt
1 | struct EepData |
2 | {
|
3 | uint16_t sollwert; |
4 | uint8_t oscal; |
5 | float aref; |
6 | };
|
7 | |
8 | // in einer Funktion dann:
|
9 | uint16_t sollwert = eeprom_read_word(offsetof(EepData,sollwert)); |
10 | //im Programm irgendwas rechnen und vergeleichen
|
11 | eeprom_update_word(offsetof(EepData,sollwert), sollwert); |
Das ist jetzt gnu++17, sollte aber in C fast unverändert zu übernehmen sein.
Das mit dem Struct werde ich versuchen. Geht ja schon in die richtige Richtung.
EAF schrieb: > Das könnte man, macht aber wenig Sinn, da die Wahrscheinlichkeit, dass > man sich verrechnet, recht groß ist. > Ich halt es für klüger, das dem Compiler zu überlassen Wenn ich eine bestimmte Ablage haben will und dise anders ist, als die sich aud den Funktionsmechanismen des Compilers ergebende, dann mache ich was? Es dem Compiler überlassen? Das ist natürlich Bullshit! Denn der liefert ja eben nicht das Gewünschte. Man macht's also selbst. Ist doch easy. Wenn man kein Idiot ist und die Funktionen benutzen kann, die der Compiler (bzw. die Libs) bereitstellen. Aber klar, das Layer8-Problem bleibt bestehen. Wenn der Kerl zu doof ist, die normale Compiler-Ablage sachgerecht auszuwerten, wird er erst recht zu doof sein, eine eigene Ablage nach den eigenen Wünschen zu konstruieren. So oder so: ohne persönliche Aufschlauung durch Lernen ist hier nix zu reissen. Ist nunmal so. Das sollte der TO einfach begreifen und gut isses.
Am Controller 10 cents sparen, anstelle eines ATMega, welcher ein UART hat. Und dafuer Aufwand bis an den Bach runter zum Auslesen... Klopp's in die Tonne. Das wird so nichts mehr.
Purzel H. schrieb: > Am Controller 10 cents sparen, anstelle eines ATMega, welcher ein UART > hat. Und dafuer Aufwand bis an den Bach runter zum Auslesen... Sind wir ehrlich. Der TE hätte mit jedem Verfahren und jedem Controller Probleme. Weil auch bei einem Tiny85 kann ich leicht einen SW-UART implementieren. Auch bereitet das Auslesen direkt über den EEPROM normalerweise keine Probleme. Hier wird aber alles zum Problem, weil das Wissen und die Erfahrung des TE schlicht für die Aufgabe nicht ausreichend sind.
Cyblord -. schrieb: > Probleme. Weil auch bei einem Tiny85 kann ich leicht einen SW-UART Klassischer Vierzeiler, wenns nur ums Auslesen (TxD) geht.
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.