Forum: Mikrocontroller und Digitale Elektronik LPM liest immer nur 0xFF


von Gabber OJ (Gast)


Lesenswert?

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

von Gabber OJ (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

lpm liest aber aus dem flash...

von Conlost (Gast)


Lesenswert?

Hallo,

ich weiß nicht welchen Controller du benutzt,
aber versuche es mal mit 0x0100 statt 0x0060
als RAM Anfangsadresse.

Es grüsst,
Arno

von Marco S (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

Hm - aber bei RAM-Zugriff muss ich doch die Adresse nicht mit 2
multiplizieren...:-)

von Marco S (Gast)


Lesenswert?

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.

von crazy horse (Gast)


Lesenswert?

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." :-)

von mmerten (Gast)


Lesenswert?

je nach AVR ist die 1. verfügbare SRAM-Adresse 0x60, 0x100 oder 0x200.
Näheres regelt im Zweifelsfall das entsprechende Datenblatt.

von Ingo H. (putzlowitsch)


Lesenswert?

Freundlicherweise ist die erste verfügbare RAM-Adresse in den
Includedateien der jeweilgen MCs als SRAM_START bereits definiert.

von Jürgen (Gast)


Lesenswert?

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

von crazy horse (Gast)


Lesenswert?

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.

von GabberOJ (Gast)


Lesenswert?

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.

von TravelRec. (Gast)


Lesenswert?

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.

von Hannes L. (hannes)


Lesenswert?

> 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...

...

von Thomas P. (pototschnig)


Lesenswert?

>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?

von Hagen R. (hagen)


Lesenswert?

>>>
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

von Simon K. (simon) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.