Hallo zusammen, ich hab ein kleines Problem bzw. eine Frage und hab dazu hier oder im Datenblatt nichts gefunden... was nicht heisst, dass da kein Brett vorm Kopf sein kann ;-) Ich schreibe ein Programm, das Daten im EEPROM des ATTiny85 speichern und bei Gelegenheit wieder auslesen soll. So weit, so primitiv. Hab den Beispielcode aus dem Datenblatt kopiert, leicht angepasst, ein Testscript geschrieben und lösche beim Aufspielen des Flash auch gleich das EEPROM auf 0x00 (weil 0xFF als Default im Programm zu Problemen führen würde). Dann mache ich folgendes: 200x ein Byte Daten hintereinander ins EEPROM speichern --> EEPROM sollte so aussehen: 0x00,0x01,0x02,0x03...,0xc7, dann nur noch Nullen 200x diese EEPROM-Daten Byte für Byte auslesen, als Code bitweise auf LED ausgeben, in die nächsten 200 EEPROM-Speicherplätze schreiben --> EEPROM sollte so aussehen: 0x00,0x01,0x02,0x03...,0xc7,0x00,0x01,0x02... Die Bytes werden von der LED sehr nett ausgegeben, stimmen alle mit der Erwartung überein. Der Code scheint also genau das zu machen, was er soll. ABER wenn ich jetzt das EEPROM mit avrdude auslese: avrdude -c avr910 -p t85 -P /dev/ttyUSB0 -U eeprom:r:IR_RemoteData.hex:h dann sieht das File IR_RemoteData.hex so aus: 0x00,0x01,0x00,0x03,0x00,0x05...,0xc7,0x00,0x00,0x02,0x00,0x04,0x00,0x06 ... Das heisst, es wird nur jedes zweite Byte ausgelesen. Ich sehe auch hier am "Frameshift" von erster zu zweiter Sequenz, dass die Daten da sind (sonst könnte das 0x02 von der zweiten Sequenz nicht da sein, es wurde ja direkt von der ersten Sequenz kopiert), aber eben - jedes zweite Byte fehlt. Das ist sowohl beim Format Hex (Format-Code h) als auch bei Intel Hex (Format-Code i) der Fall, daran liegt's nicht... Diese Situation ist fürs Debugging blöd und ich würde die Daten auch aus Interesse gern auslesen... Weiss jemand, was hier schiefgeht? Viele Grüsse und danke schonmal, Simon
Gast
#6585103
Zeig mal deinen Code...
Meine Glaskugel sagt, daß Du als "byte" int16 definiert hast.
Code in Prosa, wie kommt man nur darauf? Glaskugel sagt, Du speicherst als int.
Hallo zusammen, es geht hier gar nicht um den Code. Wie gesagt: Die Daten werden korrekt ins EEPROM geschrieben, korrekt ausgelesen und neu geschrieben (jeweils mit LED überprüft). Was nicht klappt, ist das Auslesen mittels avrdude. Ich programmiere in Assembler, habe also keine Probleme mit den Datentypen... Viele Grüsse, Simon
Gast
#6585143
> es geht hier gar nicht um den Code Nun ja, so steht es im Betreff: "... avrdude ...". > Daten werden korrekt ins EEPROM geschrieben, korrekt ausgelesen Avrdude kenne ich nicht, gebe aber zu bedenken, dass es noch eine andere Möglichkeit gibt, dass nämlich der 'Assembler-Code' sowohl beim Schreiben wie beim Lesen den selben Versatz hat. Also wäre das Programm vielleicht doch von Interesse, zumindest solange nicht ein Avrdude-Kenner das Fehlverhalten bestätigt.
Simon E. schrieb: > Ich programmiere in Assembler, habe also keine Probleme mit den > Datentypen... Na gut, dann schau Dir mal Zeile 42 an.
...und in welchem Format wird denn in den EEPROM geschrieben? 1 Byte?? Oder 2 Byte?? Fragen über Fragen - die alle hier schon gestellt wurden, nur mit anderen Worten. Und mit dem avrdude hat das erstmal herzlich wenig zu tun.
Problem gelöst - danke an S. Landolt für den entscheidenden Hinweis! Fürs Protokoll: Ich lag mit meiner Analyse daneben, der avrdude funktioniert einwandfrei. Asche auf mein Haupt und ja, es wäre schneller gegangen, wenn ich den Code einkopiert hätte... auch wenn ich nach wie vor nicht weiss, was genau logisch/mathematisch falsch war. Hab eine (in meinen Augen funktional identische) Alternative ausprobiert und schwupps, klappt alles. Vielleicht weiss das ja jemand? (Diesmal mit Code.) Ich habe in r17 den Wert, der ins EEPROM soll, in r18 und r19 die low/high-Bytes der Adressen (und nein, sie sind nicht vertauscht). Ich inkrementiere die Adresse in jedem Schritt so (Snippet aus dem alten Code):
1 | |
2 | |
3 | |
Das führt dazu, dass jedes ZWEITE Byte an die richtige Stelle im EEPROM geschrieben wird und jedes ANDERE ZWEITE Byte sehr viel weiter hinten (oberhalb von Position 256, nicht exakt - die genaue Stelle weiss ich nicht mehr). r18/r19 scheinen also immer hin und her zu springen. Ich verstehe nicht warum. Alternativ hab ich folgendes probiert, das einwandfrei funktioniert:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
Nach dieser Erkenntnis wäre es vermutlich sinnvoll, wenn ich meinen EEPROM_write und EEPROM_read auf die Nutzung von ZH/ZL umschreiben würde, dann spar ich mir die Kopiererei... Weiss jemand, wo das mit der Werte-Obergrenze beim adiw dokumentiert ist? Viele Grüsse, Simon
Gast
#6585284
> Weiss jemand, wo das mit der Werte-Obergrenze > beim adiw dokumentiert ist? Na, im 'AVR® Instruction Set Manual'.
Gast
#6585371
Übrigens ist im vorliegenden Fall subi plus sbci sinnvoll - deutlich kürzer und schneller.
Stimmt. Danke!
Gast
#6585484
Mir ist ohnehin nicht klar, was sich Atmel bei den Befehlen adiw und sbiw gedacht hat - nie schneller als subi sbci, und nur im Fall 0..63 kürzer.
Gast
#6585764
S. Landolt schrieb: > Mir ist ohnehin nicht klar, was sich Atmel bei den Befehlen adiw und > sbiw gedacht hat - nie schneller als subi sbci, und nur im Fall 0..63 > kürzer. Naja, früher(tm) gab es die Instruktionen überhaupt nur für den Immediate-Bereich 0..63. Ist das heute anders? Und der Vorteil der adiw, subiw war natürlich wirklich die Ersparnis von Flashspace. Das, was die C-ler als "Zeigerarithmetik" betiteln, läßt sich damit bezüglich des Platzbedarfs wirklich ganz ordentlich eindampfen, aber auch der Zugriff auf Datenstrukturen im Flash, denn leider gibt es für (e)lpm ja keine indizierte Adressierung mit Offset, da ist man zur exzessiven Nutzung von "Zeigerarithmetik" von Haus aus gezwungen.
Gast
#6585792
Ihr erster Absatz ist mir völlig unverständlich. "Datenstrukturen im Flash": wenn ich solche wirklich umfangreich nutzen wollte, würde ich sie innerhalb von 256-Byte-Blöcken anordnen und mit subi ZL arbeiten (was auch noch jeweils 1 Takt spart).
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.
