www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 16 Bit Werte aus dem Speicher lesen


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich möchte mittels Z-Pointer Werte aus dem Speicher lesen aber ich 
schaffe es nicht ganz an das High-Byte des Wortes zu kommen. Kann mir 
jemand sagen was ich falsch mache?

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm temp, Z
  ldi ZL, LOW(pwmValue)
  ldi ZH, HIGH(pwmValue)
  lpm temp1, Z
  rjmp main
.DSEG
pwmValue:
.dw 0x11FF

Er läd mir in beide Register 0xFF hinein ... anscheinend hab ich das mit 
der Multiplikation mit 2 noch nicht so richtig verstanden ....

Danke schonmal für die Hilfe

gruß Christian

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:
> ... anscheinend hab ich das mit
> der Multiplikation mit 2 noch nicht so richtig verstanden ....
So sieht es aus. Die Multiplikation brauchts, weil LPM mit Byte-Adressen 
arbeitet, Adressen im Programmspeicher an sich aber Wort-Adressen sind.

Wenn die zwei Bytes des 16-Bit-Wertes im Speicher hintereinander liegen, 
dann liegt das eine Byte an der Byte-Adresse pwmValue*2 und das andere 
an der Adresse pwmValue*2 + 1. Und jetzt überlege mal, wie Du wohl an 
das zweite Byte drankommst...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zwei kleine Tips noch am Rande:
Du hast den Wert im Flash mit .dw erzeugt. Die AVRs sind little-endian, 
d.h. das High-Byte steht im Speicher "hinter" dem Low-Byte (also bei der 
höheren Adresse).

Außerdem gibt es (falls Dir das noch nicht bekannt sein sollte) den 
Befehl adiw, der u.a. mit den Pointer-Registern funktioniert und der 
maßgeschneidert ist für solche Anwendungen...

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm temp, Z+   ; lädt (Z) nach temp und erhöht anschließen Z üm 1
  lpm temp1, Z
  rjmp main

.DSEG
pwmValue:
.dw 0x11FF

Gruß aus Berlin
Michael

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Michael:
Hmmm, das wäre ja die ganz elegante Methode... Hab glaub ich zu lange 
nicht mehr in Assembler programmiert.

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
lpm temp, Z+ gibts aber nicht auf allen Controllern, wenn nicht, wird 
der Assembler schon meckern :-)

Autor: Michael U. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

dann käme:

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm temp, Z   ; lädt (Z) nach temp und erhöht anschließen Z üm 1
  adiw Z,1
  lpm temp1, Z
  rjmp main

adiw gibt esa uch nicht auf allen, also dann

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm temp, Z
  subi ZL,-1
  sbci ZH,0
  lpm temp1, Z
  rjmp main

oder

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm temp, Z
  inc ZL
  brne m_0

  inc ZH

m_0:
  lpm temp1, Z
  rjmp main

alle können auch lpm nicht in beliebige Register, also noch:

main:
  ldi ZL, LOW(pwmValue*2)
  ldi ZH, HIGH(pwmValue*2)
  lpm
  mov temp,r0
  subi ZL,-1
  sbci ZH,0
  lpm
  mov temp1,r0
  rjmp main

Fehlt noch was? ;-)

Gruß aus Berlin
Michael

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. wrote:
> Fehlt noch was? ;-)
Vermutlich nicht...

Autor: Obelix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal eine allgemeine Frage, da ich nicht mit den AVRs arbeite.
Haben die AVRs nicht alle den selben Befehlssatz?

Autor: crazy horse (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ein klares Jein.
Es gibt den ganz alten Befehlssatz, den haben alle nach wie vor. Ist dan 
aber im Laufe je nach Entwicklungsrichtung was dazugekommen.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zunächst mal gibt es Befehle, die bestimmte Hardware-Eigenschaften 
voraussetzen. Das sind v.a. die Multiplikationsbefehle. Die AVRs der 
ATMega-Reihe waren die ersten, die einen Hardware-Multiplier hatten, und 
dementsprechend sind die entsprechenden Befehle auch nur für diese µCs 
relevant.

Außerdem gibt es Befehle, deren Einsatz von der Größe des Speichers 
(Adressraum) abhängt. So haben alle AVRs mit bis zu 8 KiB Flash nur 
relative Sprung- und Call-Befehle, weil sich mit der Adressbreite von 
rjmp und rcall der Speicher komplett ansprechen lässt und 
dementsprechend die absoluten Befehle, die mehr Platz im 
Programmspeicher brauchen, unsinnig wären. Erst ab 16 KiB Flash gibt es 
die absoluten Befehle jmp und call, die einen größeren Adressbereich 
zulassen, aber auch zwei Worte breit sind (rjmp und rcall nur ein Wort).

Autor: Frankl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie addiere ich jetzt zum Pointer eine Variablen. adiw unterstüzt doch 
nur Konstante.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frankl wrote:
> Wie addiere ich jetzt zum Pointer eine Variablen. adiw unterstüzt doch
> nur Konstante.
Da musste auf die Ochsentour ran. In der Befehlssatz-Dokumentation steht 
aber, wie's geht (bei add bzw. adc).

Autor: Wolfram Quehl (quehl)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest 
aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder 
habe ich da was falsch verstanden?

mfg

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Wolfram Quehl (quehl)

>ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest
>aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder
>habe ich da was falsch verstanden?

Das siehst du sehr richtig.

AVR-Tutorial: SRAM
AVR-Tutorial: Speicher

MFg
Falk

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Dann funktioniert das:

.DSEG
pwmValue:
.dw 0x11FF

auch nicht.

MfG Spess

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wolfram Quehl wrote:
> ich denke, daß die o.g. Programmteile so nicht funktionieren. LPM liest
> aus dem Flash. Die Adresse liegt jedoch im stat. RAM ( .DSEG ). Oder
> habe ich da was falsch verstanden?
Autsch. Da hab ich gar nicht so genau hingeschaut. Klar, das kann nicht 
funktionieren. Muss natürlich entweder ein .cseg hin oder das lpm macht 
keinen Sinn.

spess53 wrote:
> Dann funktioniert das:
>
> .DSEG
> pwmValue:
> .dw 0x11FF
>
> auch nicht.
Richtich. .dw geht nur in .eseg und .cseg.

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

autsch... gilt auch für mich:
Wer lesen kann, ist klar im Vorteil...

wenn es im Ram stehen soll, muß es das Programm erstmal irgendwo 
hingeschrieben haben.

Dort wäre es nur eine Reservierung des Platzes

.org 0x060  ; erste SRAM-Adresse

pwmVALUE: .db 2  ; Reserviere 2 Byte

Der lesende Zugriff wäre dann z.B.

  lds temp,pwmVALUE
  lds temp1,pwmVALUE+1

Gruß aus Berlin
Michael

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael U. wrote:
> .org 0x060  ; erste SRAM-Adresse
>
> pwmVALUE: .db 2  ; Reserviere 2 Byte
>
> Der lesende Zugriff wäre dann z.B.
>
>   lds temp,pwmVALUE
>   lds temp1,pwmVALUE+1
Auch nicht. Wie oben schon gesagt: .db und .dw gehen nur in Flash und 
EEPROM, also in .cseg oder .eseg. Im SRAM (.dseg) geht das Reservieren 
von Speicher nur mit .byte. Und dann muss noch der Wert 
hineingeschrieben werden, was nur das Programm kann.

EDIT:
Es ist ein oft gesehener Irrtum, dass man ins SRAM, wie in die 
nichtflüchtigen Speicher auch, irgendwelche vordefinierten Werte 
schreiben kann, die bei Programmstart automatisch ins SRAM übernommen 
werden. Dem ist aber nicht so! Das SRAM ist nunmal flüchtig und nach 
einem Reset zunächst mal mit irgendwas gefüllt. Definierte Werte 
hineinschreiben kann nur das Anwenderprogramm.

Die Direktiven .db und .dw sind zur Definition konstanter Werte 
vorgesehen, die beim Programmieren direkt in den betreffenden Speicher 
geschrieben werden können, und das geht nunmal nur mit nichtflüchtigem 
Speicher.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo kommt ein bischen verspätet, aber danke für alle Antworten ....
Ihr habt  mir  sehr geholfen

gruß Christian

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.