AVR-ASM: 16bit-Wert ins SRAM speichern

Gast #3636469
Lesenswert?

Hallo Leute,
ich stehe gerade etwas auf dem Schlauch: Ich möchte einen 16Bit-Wert ins 
SRAM speichern und weiß jetzt gerade nicht wie ich das anstellen soll.

Ich definiere im Programm-Anfang ein 16Bit Wert als variable, diese wird 
in das Register-Paar Temp1 bzw. Temp2 zur Weiterverarbeitung geladen und 
ich möchte nun diesen 16Bit-Wert an einer späteres Stelle ins SRAM 
speichern.

Also etwa so:

.equ maxVADJ_Default=2765

ldi temp1, HIGH(maxVADJ_Default)
ldi temp2, LOW(maxVADJ_Default)

... und nun sollen die 2 Register zusammengefasst im SRAM abgelegt 
werden, z.B. in SRAM_maxVADJ

Bei einer reinen 8-Bit Variablen würde ich das so realisieren:

sts SRAM_maxVADJ, maxVADJ_Default

Aber wie kann ich das mit einer 16Bit Zahl machen? Ich möchte aus 
Übersichtsgründen ungern die Zahl als getrenntes Highbyte und Lowbyte 
speichern.

Im DSEG habe ich die SRAM_maxVADJ-Speicherzelle als 2Byte-Wert 
definiert:
SRAM_maxVADJ: .BYTE   2

Danke schonmal :-)
Gast #3636493
Lesenswert?

Hi

>Aber wie kann ich das mit einer 16Bit Zahl machen? Ich möchte aus
>Übersichtsgründen ungern die Zahl als getrenntes Highbyte und Lowbyte
>speichern.

Muss du aber. Der RAM ist nur 8 Bit breit.

>Bei einer reinen 8-Bit Variablen würde ich das so realisieren:

>sts SRAM_maxVADJ, maxVADJ_Default

dann mach es so:
ldi temp1, HIGH(maxVADJ_Default)
ldi temp2, LOW(maxVADJ_Default)

sts SRAM_maxVADJ,   temp1
sts SRAM_maxVADJ+1, temp2

MfG Spess
Moderator (Firma: Titel) Persönliche Seite #3636497
Lesenswert?

Daniel schrieb:
> Aber wie kann ich das mit einer 16Bit Zahl machen? Ich möchte aus
> Übersichtsgründen ungern die Zahl als getrenntes Highbyte und Lowbyte
> speichern.
Das Interface zum RAM (aka. Datenbus) ist nur 8 Bit breit. Auch wenn es 
mit nur einem Assemblerbefehl ginge: der Prozessor müsste sowieso 
jeden 16-Bit Zugriff in 2 8-Bit Zugriffe über den 8 Bit Datenbus 
auflösen.
Gast #3636513
Lesenswert?

Okay, danke für eure Antworten.

Also ein No-Go ist das mit dem getrennten Lowbyte und Highbyte im SRAM 
nicht, ich hätte den Wert nur gern zusammengefasst in einem "Register" 
stehen.

Aber das werde ich mal ausprobiere:

sts SRAM_maxVADJ,   temp1
sts SRAM_maxVADJ+1, temp2

Was macht das +1 genau?
Dann müsste beim laden aus dem SRAM das so aussehen, richtig?

lds temp1, SRAM_maxVADJ
lds temp2, SRAM_maxVADJ+1
#3636516
Lesenswert?

Daniel schrieb:
> sts SRAM_maxVADJ,   temp1
> sts SRAM_maxVADJ+1, temp2
>
> Was macht das +1 genau?
"SRAM_maxVADJ" ist die Adresse des Low Bytes im Ram, "SRAM_maxVADJ+1" 
ist die Adresse + 1 und also die Adresse fürs High Byte.

Wenn die Adresse ("SRAM_maxVADJ") z.B: 0X125 ist, dann wird "temp1" in 
die RAM-Zelle 0x125 und "temp2" in die RAM-Zelle 0x126 geschrieben.
Gast #3636530
Lesenswert?

Max H. schrieb:

> "SRAM_maxVADJ" ist die Adresse des Low Bytes im Ram, "SRAM_maxVADJ+1"
> ist die Adresse + 1 und also die Adresse fürs High Byte.
>
> Wenn die Adresse ("SRAM_maxVADJ") z.B: 0X125 ist, dann wird "temp1" in
> die RAM-Zelle 0x125 und "temp2" in die RAM-Zelle 0x126 geschrieben.


Alles klar, vielen Dank!
#3636543
Lesenswert?

Daniel,

mach Dir doch ein Macro, z.B.

.macro _stsw @0 @1
     sts @0,high(@1)
     sts @0+1,low(@1)
.endmacro

Wenn Du das macro aufrufst, musst Du als ersten Parameter den Beginn des 
reservierten 2-Byte-Speicherbereichs angeben, als zweiten die zu 
speichernde 16-Bit Zahl, also z.B.:

...
     _stsw SRAM_maxVDAJ 0xABCD
...

Fertig ist die Laube. Vorteil solcher Macros ist, dass man beliebige 
Speicherstellen verwenden kann, und die Zahlen immer nach demselben 
Schema gespeichert werden.

Ciao,
mare_crisium
#3636555
Lesenswert?

Eine andere Möglichkeit: Du baust ein Macro.

In diesem Fall eine neuen Befehl stsw mit zwei Parametern (Adresse im 
SRAM und 16Bit Konstante)
1
.MACRO stsw                  ;ein Macro mit Namen stsw 
2
  push  r16                  ;temoräres Register sichern
3
  ldi  r16,low(@1)           ;Lowbyte des zweiten Parameter holen
4
        sts  @0,r16          ;nach SRAM (erster Parameter) sichern
5
  ldi  r16,high(@1)          ;Highbyte des zweiten Parameter holen
6
        sts  @0+1,r16        ;nach SRAM (erster Parameter plus eins) sichern
7
  pop  r16                   ;Register restaurieren
8
.ENDMACRO
9

10
.equ maxVADJ_Default=2765
11

12
//so wird dieses Macro verwendet
13
        stsw   SRAM_maxVADJ, maxVADJ_Default
#3636617
Lesenswert?

Max,
ja, hab' nicht aufgepasst :-(. Detlef hat die richtige Methode gepostet. 
Man bekommt eine noch flexiblere Lösung, wenn man Registerinhalte 
speichert. Dann könnte man das z.B. folgendermassen machen:

.equ AL = r16         ; diese Art der Bezeichnung stammt von Elm Chang
.equ AH = r17

.macro _stsw          ; Aufruf: _stsw @0,@1
     sts @0,@1L
     sts @0+1,@1H
.endmacro

Beispiel:
...
    ldi AL,0xCD
    ldi AH,0xAB       ; in r17:r16 steht jetzt der Wert 0xABCD
    _stsw SRAM_maxVDAJ,A

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren