Hallo. Bin gerade angefangen was mit yP zu machen... habe jetz was geschrieben im AVR Studio 3.56. Eigentlich klappt alles bis auf die Sache mit LPM. Also. Ich wandle zuerst eine 10bit Binär Zahl in Dezimal um. Die Routine dafür habe ich auch aus diesem Forum. ... ldi decH, high(10000) ldi decL, low(10000) rcall bin2digit ldi decH, high(1000) ldi decL, low(1000) rcall bin2digit ... usw kommt dem einen oder andern sicher bekannt vor. So. jetz zu meinem Problem. Ich will die Werte die diese Routine berechnet im SRAM speichern. Dazu mach ich folgendes st Z+, digit ;wobei in digit die jeweilige Dezimalziffer steht Z hab ich vorher initialiesiert mit ldi ZH, HIGH(0x60*2) ldi ZL, LOW(0x60*2) mal 2 wegen "ist einfach so" im Simulator schreibt er auch brav nacheinander ab (0x60*2)=0x00C0 bis 0x00C3 den Wert von digit. In meinem Fall steht im Memory-Fenster das hier: 0x00C0 01 00 02 01 00 00 00...usw Dann will ich die Werte wieder lesen mit LPM. Und zwar so ldi ZH, HIGH(0x60) ldi ZL, LOW(0x60) lpm mov r16, r0 adiw ZL, 1 ... aber im Register-Fenster sieht man wie zuerst R0 auf 0x01 gesetzt wird und danach auch r16 auf 0x01 geht. Auch Z-Register wird schön um 1 erhöht. Soweit so gut. Beim nächsten LPM steht aber 0xD0 in R0, danach 0x08. Also irgendwelche(?) Werte. Was mach ich falsch??? Habe auch schon mal anstelle 0x60 überall 0x0060 geschrieben. auch einfach mal mit (0x60*2) initialisieren probiert. immer das gleiche. Nur die Werte ändern sich. zum beispiel 0xFF anstatt 0x01
Oben ist en Tippfehler drin. Sorry. Habe natürlich immer wenn ich (0x60*2) initialisiert habe auch unten wieder mit (0x60*2) geladen und umgekehrt
Hallo, ich weiß nicht welchen Controller du benutzt, aber versuche es mal mit 0x0100 statt 0x0060 als RAM Anfangsadresse. Es grüsst, Arno
Wie bereits gesagt greift der lpm-Befehl auf den flash-speicher zu. Aus dem SRAM liest du mit ld... ldi ZH, HIGH(0x60*2) ldi ZL, LOW(0x60*2) ld r16, z+ Gruß Marco
Hm - aber bei RAM-Zugriff muss ich doch die Adresse nicht mit 2 multiplizieren...:-)
Die Adresse 0x60*2 scheint willkürlich gewählt zu sein. Wenn man dahin schreibt, sollte man auch von da lesen. Ich selbst würde den RAM-Anfang wählen, halt möglichst weit weg vom Stack.
nö, die ist nicht willkürlich gewählt, sondern das ist die 1.Adresse das RAMs. "Ich selbst würde den RAM-Anfang wählen, halt möglichst weit weg vom Stack." :-)
je nach AVR ist die 1. verfügbare SRAM-Adresse 0x60, 0x100 oder 0x200. Näheres regelt im Zweifelsfall das entsprechende Datenblatt.
Freundlicherweise ist die erste verfügbare RAM-Adresse in den Includedateien der jeweilgen MCs als SRAM_START bereits definiert.
Der Anfang des RAMs ist nicht zwingend die beste Wahl, wenn es daurum geht dem Stack nicht in die Quere zu kommen.Es gibt nämlich auch Compiler, die den Stack am Anfang des RAMs anlegen
naja - von Compilern redet hier eigentlich keiner. Hier gehts um reine Assembler-Programmiererei. Und wenn ich einen Compiler verwende, halte zumindest ich mich völlig aus den absoluten Adressen heraus - soll sie doch der Compiler die Variablen oder Konstanten hinlegen, wo er will. Hauptsache, die Zuordnung ist eindeutig und fehlerfrei. Und das kann er besser als ich.
Jo. Danke ers mal für die ganzen Antworten. Hab also anscheinend den falschen Befehl benutzt. Werd ich zuhause mal testen. Ich hab ers mal alles im Simulator gemacht und mit ner ATMega8 .inc datei. Noch nix davon in die Praxis umgesetzt.
LPM liest FLASH LDS liest RAM (direkt) STS schreibt RAM (direkt) LD liest RAM (über Pointer) ST schreibt RAM (über Pointer) Die RAM Adresse wird immer direkt angegeben und nicht mit 2 multipliziert. ATMEL hat ein schönes und ausführliches Dokument auf der Website, welches die AVR-Instruktionen super übersichtlich erklärt.
> ATMEL hat ein schönes und ausführliches Dokument auf der Website, > welches die AVR-Instruktionen super übersichtlich erklärt. Das macht die Onlinehilfe (F1-Taste) in AVR-Studio auch... ;-) Gruß aus der fast abgesoffenen Elbaue... ...
>Der Anfang des RAMs ist nicht zwingend die beste Wahl, wenn es daurum >geht dem Stack nicht in die Quere zu kommen.Es gibt nämlich auch >Compiler, die den Stack am Anfang des RAMs anlegen An den Anfang des RAMS anlegen? Und der wächst dann in die Register rein?
>>> Der Anfang des RAMs ist nicht zwingend die beste Wahl, wenn es daurum geht dem Stack nicht in die Quere zu kommen.Es gibt nämlich auch Compiler, die den Stack am Anfang des RAMs anlegen <<< Das ist dummpfsinn, sorry. Der Stack expandiert auf Grund der Hardwaregegebenheiten auf dem AVR und eigentlich auf allen CPUs die ich kenne von der höchsten Speicherstelle zur niedrigeren, deswegen nennt man es ja auch Stack. Da ändert ein Compiler nichts dran, und auch kein Assembler, es sei denn man möchte ins Regfile schreiben. Gruß Hagen
Schließe mich Hagen an. push/pop sind so implementiert, dass die Ramadresse beim Pushen um eins erniedrigt wird und beim poppen wieder erhöht.
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.