mikrocontroller.net

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


Autor: Rainer B. (guitero)
Datum:

Bewertung
0 lesenswert
nicht 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.
.def y_pointer = r18

ldi     YH,HIGH(sdata)
ldi     YL,LOW(sdata)                  

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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rainer B. (guitero)
Datum:

Bewertung
0 lesenswert
nicht 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.
ldi     YH,HIGH(sdata)
ldi     YL,LOW(sdata)

mov     temp, yl

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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.
>
>
> ldi     YH,HIGH(sdata)
> ldi     YL,LOW(sdata)
> 
> mov     temp, yl
> 
> .DSEG
> 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?

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

 ldi     YH,HIGH(sdata)
 ldi     YL,LOW(sdata)
 
 sts     pointer, YL
 sts     pointer+1, YH
 
 .DSEG
 pointer: .BYTE 2  ; Zeiger auf sdate
 
 

Gruß aus Berlin
Michael

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rainer B. (guitero)
Datum:

Bewertung
0 lesenswert
nicht 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.
ldi     YL,LOW(sdata)  

;hier kommen z.B. Daten über UART an
in      data, UDR0                                  
st      y+, data
;Endpunkt merken
sts     pointer, yl

.DSEG
pointer: .Byte 1
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rainer B. (guitero)
Datum:

Bewertung
0 lesenswert
nicht 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:
;bei der Initialisierung
ldi  YH,HIGH(sdata)
ldi     YL,LOW(sdata)                  
    
sts   sPointer, yl      ;Start-Adresse merken
sts   sPointer+1, yh

;während des Uart-Interrupts
in    data, UDR1                                                
st    y+, data              
sts   endP, yl          ;End-Adresse merken      
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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
   sbiw YH:YL,1
   sts   endP, yl          ;End-Adresse merken      
   sts   endP+1,yh

MfG Spess

Autor: Rainer B. (guitero)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Ansonsten ist das Vorgehen aber in Ordnung?

Ja.

MfG Spess

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.