Forum: Mikrocontroller und Digitale Elektronik Anfangs-und Endzeiger für SRAM


von Rainer B. (guitero)


Lesenswert?

Hallo zusammen,

ich lese mit einem AtMega162 verschiedene Daten ins SRAM ein. Nun möchte 
ich mir den Anfangs- bzw. Endpunkt der Strings im SRAM merken.Bisher 
habe ich das so gemacht, dass ich die SRAM-Adressen in Registern 
gespeichert habe.
1
.def y_pointer = r18
2
3
ldi     YH,HIGH(sdata)
4
ldi     YL,LOW(sdata)                  
5
6
mov     y_pointer,yl

Ist dieser Weg überhaupt praktikabel? Wenn ich jetzt verschiedene Daten 
im SRAM ablegen möchte (bei mir sind es drei verschiedene Strings) gehen 
mir irgendwann die Register aus in denen ich die Anfangs und Endpunkte 
speichern kann ohne diese zu überschreiben. Kann mir jemand sagen, wie 
man das lösen würde, bzw. ein Beispiel dazu geben.

Viele Grüße,

guitero

von spess53 (Gast)


Lesenswert?

Hi

>Ist dieser Weg überhaupt praktikabel?

Wenn du mit praktikabel, sinnvoll meinst, dann nein.

Reserviere doch im Ram einen Bereich, in dem du die Zeiger ablegst. 
Soviel kann es ja nicht sein, da du nur YL sicherst.

MfG Spess

von Rainer B. (guitero)


Lesenswert?

spess53 schrieb:
> Hi
>
>>Ist dieser Weg überhaupt praktikabel?
>
> Wenn du mit praktikabel, sinnvoll meinst, dann nein.

Ja, das meine ich. Da ich mir alles selbst beibringe möchte ich mich 
manchmal vergewissern ob das ganz großer Blödsinn ist was ich so mache.

> Reserviere doch im Ram einen Bereich, in dem du die Zeiger ablegst.
> Soviel kann es ja nicht sein, da du nur YL sicherst.

Tja, und wie geht das genau.
1
ldi     YH,HIGH(sdata)
2
ldi     YL,LOW(sdata)
3
4
mov     temp, yl
5
6
.DSEG
7
pointer: .BYTE 1

Jetzt habe ich die Startadresse von sdata in temp gespeichert. Wie kann 
ich diese Adresse jetzt an "pointer" übermitteln ohne dass es unnötig 
kompliziert wird?

Gruß,

guitero

von Karl H. (kbuchegg)


Lesenswert?

Rainer B. schrieb:

> Jetzt habe ich die Startadresse von sdata in temp gespeichert. Wie kann
> ich diese Adresse jetzt an "pointer" übermitteln ohne dass es unnötig
> kompliziert wird?

Es wird Zeit für das ... ta ta ..... Tutorial. Speziell:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_SRAM

von Michael U. (amiga)


Lesenswert?

Hallo,

Rainer B. schrieb:
> spess53 schrieb:
>> Hi
>>
>>>Ist dieser Weg überhaupt praktikabel?
>>
>> Wenn du mit praktikabel, sinnvoll meinst, dann nein.
>
> Ja, das meine ich. Da ich mir alles selbst beibringe möchte ich mich
> manchmal vergewissern ob das ganz großer Blödsinn ist was ich so mache.
>
>> Reserviere doch im Ram einen Bereich, in dem du die Zeiger ablegst.
>> Soviel kann es ja nicht sein, da du nur YL sicherst.
>
> Tja, und wie geht das genau.
>
>
1
> ldi     YH,HIGH(sdata)
2
> ldi     YL,LOW(sdata)
3
> 
4
> mov     temp, yl
5
> 
6
> .DSEG
7
> pointer: .BYTE 1
8
> 
9
>
>
> Jetzt habe ich die Startadresse von sdata in temp gespeichert. Wie kann
> ich diese Adresse jetzt an "pointer" übermitteln ohne dass es unnötig
> kompliziert wird?

was soll die in temp? Die Adresse ist 16 Bit (zumindest in Deinem 
Beispiel), belegt also 2 Byte.

1
 ldi     YH,HIGH(sdata)
2
 ldi     YL,LOW(sdata)
3
 
4
 sts     pointer, YL
5
 sts     pointer+1, YH
6
 
7
 .DSEG
8
 pointer: .BYTE 2  ; Zeiger auf sdate

Gruß aus Berlin
Michael

von spess53 (Gast)


Lesenswert?

Hi

>Jetzt habe ich die Startadresse von sdata in temp gespeichert. Wie kann
>ich diese Adresse jetzt an "pointer" übermitteln ohne dass es unnötig
>kompliziert wird?

Das temp kennst du dir sparen:

 sts pointer,YL

fertig.

Dir ist aber bewusst, das du mit deiner Methode (nur den Low-Teil der 
Adresse speichern) nur 256 Byte adressieren kannst. Und die können bei 
1k Ram nur bei $0000-$00FF, $0100-$01FF, $0200-$02FF oder $0300-$03FF 
liegen. Den letzte Bereich solltest du auf jeden Fall meiden, da dort 
der Stack liegt.

MfG Spess

von Rainer B. (guitero)


Lesenswert?

Guten Morgen zusammen,

spess53 schrieb:
> Dir ist aber bewusst, das du mit deiner Methode (nur den Low-Teil der
> Adresse speichern) nur 256 Byte adressieren kannst.

Das ist mir zwar bewusst,aber ich verstehe irgendwie nicht warum genau 
ich mehr adressieren sollte.
Beispiel: Ich reserviere mir 12 Byte im SRAM(sdata). Wozu brauche ich 
den HIGH-Teil wenn ich auch mit dem Low-Teil schon 256 Byte adressieren 
kann.
1
ldi     YL,LOW(sdata)  
2
3
;hier kommen z.B. Daten über UART an
4
in      data, UDR0                                  
5
st      y+, data
6
;Endpunkt merken
7
sts     pointer, yl
8
9
.DSEG
10
pointer: .Byte 1
11
sdata: .Byte 12

Wie man merkt ist mir die Speicherverwaltung nicht ganz klar. Das 
Tutorial habe ich gelesen, aber warum ich unbedingt eine 16Bit 
Adressierung brauche ist mir nicht klar geworden.

Wäre nett wenn mir das jemand erläutern könnte.
Viele Grüße,

sharth

von Karl H. (kbuchegg)


Lesenswert?

Rainer B. schrieb:
> Guten Morgen zusammen,
>
> spess53 schrieb:
>> Dir ist aber bewusst, das du mit deiner Methode (nur den Low-Teil der
>> Adresse speichern) nur 256 Byte adressieren kannst.
>
> Das ist mir zwar bewusst,aber ich verstehe irgendwie nicht warum genau
> ich mehr adressieren sollte.

Wenn du einen Brief schreibst, musst du die Adresse draufschreiben.
Lebt der Adressat in einer Strasse mit 100 Bewohnern (0-99) und du 
schreibst bei der Hausnummer nur die Einerstelle, dann hat der Postbote 
Schwierigkeiten das richtige Haus zu finden.

> Beispiel: Ich reserviere mir 12 Byte im SRAM(sdata).

Diese 12 Bytes liegen an den Adressen
   0x01D, 0x01FE, 0x01FF, 0x0200, 0x0201, 0x0202, 0x0203 ....

> Wozu brauche ich
> den HIGH-Teil wenn ich auch mit dem Low-Teil schon 256 Byte adressieren
> kann.

Aber nur dann, wenn du bei 0 anfängst.

Im Moment magst du vielleicht damit durchkommen, weil du 10 Strings a 20 
Bytes reservierst. Alles funktioniert perfekt. 10*20 = 200, passt.

In 2 Monaten kommst du drauf, oder dein Kunde hätte gerne dass die 
Stringlänge von 20 auf 30 Bytes angehoben wird. Oder anstelle von 10 
benötigst du 15 Strings. 15*20 = 300, 10*30 = 300.  Oops

Oder du benötigst noch andere Variablen im SRAM. Die schiebst du vorne 
ein, deine Strings wandern nach hinten, bis, ja bis einer davon die 265 
Byte Grenze überschreitet.

Der springende Punkt ist: jetzt kostet es dir nichts, das gleich richtig 
zu machen. Bei Änderungen bist du flexibel. In 2 Monaten denkst du nicht 
mehr daran, das komplette Programm durchzusehen, wie sich diese 
Änderungen auswirken.

> Wie man merkt ist mir die Speicherverwaltung nicht ganz klar. Das
> Tutorial habe ich gelesen, aber warum ich unbedingt eine 16Bit
> Adressierung brauche ist mir nicht klar geworden.

Weil dein Speicher >256 Bytes gross ist und du mit 8Bit Adressen nicht 
auskommst. Du verhältst dich wie jemand, der auf einen Brief 
grundsätzlich nur die Einerstelle der Strassenadresse draufschreibt, 
weil heute in dieser Strasse nur 10 Häuser existieren und weigerst dich 
beharrlich zu akzeptieren, dass sich das ändern kann.

von Rainer B. (guitero)


Lesenswert?

Hallo,

Karl heinz Buchegger schrieb:
> Du verhältst dich wie jemand, der auf einen Brief
> grundsätzlich nur die Einerstelle der Strassenadresse draufschreibt,
> weil heute in dieser Strasse nur 10 Häuser existieren und weigerst dich
> beharrlich zu akzeptieren, dass sich das ändern kann.

Okay,okay. Hab's verstanden. Danke für die ausführliche Erklärung. Ich 
schreibe im Moment relativ kleine Übungsprogramme und da erschien es mir 
nicht so sinnvoll immer den Umweg über 16Bit zu gehen obwohl es nicht 
nötig ist. Danke für die mehr als deutliche Darstellung.

Jetzt noch mal zum Vorgehen, wenn ich mir den Anfangs- und Endpunkt 
eines Strings merken möchte:
1
;bei der Initialisierung
2
ldi  YH,HIGH(sdata)
3
ldi     YL,LOW(sdata)                  
4
    
5
sts   sPointer, yl      ;Start-Adresse merken
6
sts   sPointer+1, yh
7
8
;während des Uart-Interrupts
9
in    data, UDR1                                                
10
st    y+, data              
11
sts   endP, yl          ;End-Adresse merken      
12
sts   endP+1,yh

Ist das eine einigermaßen gute, einfache und gängige Lösung oder immer 
noch Mist?
Sorry für die vielen Fragen, aber finde zu dem Thema sonst nichts was 
mir weiter hilft.

Viele Grüße,
sharth

von spess53 (Gast)


Lesenswert?

Hi

>in    data, UDR1
>st    y+, data
>sts   endP, yl          ;End-Adresse merken
>sts   endP+1,yh

Damit speicherst du aber nicht die Adresse des letzen Bytes, sondern die 
darauf nachfolgende Adresse.

'st    y+, data'  speichert data und erhöht Y um 1.

Um die letzte Adresse zu erhalten:
1
   sbiw YH:YL,1
2
   sts   endP, yl          ;End-Adresse merken      
3
   sts   endP+1,yh

MfG Spess

von Rainer B. (guitero)


Lesenswert?

Hallo,

> Damit speicherst du aber nicht die Adresse des letzen Bytes, sondern die
> darauf nachfolgende Adresse.

Das hatte ich berücksichtigt. Danke für den Tipp! Ansonsten ist das 
Vorgehen aber in Ordnung?

Gruß,

sharth

von spess53 (Gast)


Lesenswert?

Hi

>Ansonsten ist das Vorgehen aber in Ordnung?

Ja.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Wobei man sich oft nicht die Endadresse direkt merkt (ausser als 
Startadresse wo der nächste String abgelegt werden kann), sondern im 
String irgendwie anders markiert, dass er jetzt zu Ende ist. zb mit 
einem 0-Byte
Die Weiterverarbeitung ist dann um einiges einfacher.

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.