-         

Ergebnis 1 bis 4 von 4

Thema: Adressierung mit Displacment

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    08.01.2005
    Ort
    Germany
    Beiträge
    55

    Adressierung mit Displacment

    Anzeige

    Hallo

    Wie kann ich eine Adressierung mit Offset bewerkstelligen?
    Optimal und kurz wäre eine Adressierung mit Displacment. Was ist das Displacment eigentlich? Kann ich dafür nur eine Zahl einsetzen oder geht es auch über eine Variable? Eine Zahl ist etwas festes und für meinen Zweck nicht brauchbar.
    Letztendlich sind es doch alles nur Zahlen für den Prozessor.

    Mein Problem:
    .dseg
    Modulblock:
    Prog1: .byte 4 ;jeweils 4 Byte reservieren
    Prog2: .byte 4
    Prog3: .byte 4
    ...

    Nachdem die Werte eingetragen wurden, sieht es im Speicher dann z.B. so aus:
    ab Adr. Prog1: 0 1 2 255 (entsprechend r,g,b,255)
    ab Adr. Prog2: 1 2 0 255
    ab Adr. Prog3: 2 1 0 255
    ...

    Auf den Blockanfang möchte ich einen festen Zeiger haben (Modulblock). Dies ist kein Thema.
    Nun habe ich einen Zeilen- und einen Spaltenoffset. Diese werden addiert und sollten in ldd R,Z+q als Displacment q dienen.
    Bei allen anderen Ladebefehlen würde sich die Adresse jedesmal ändern, da ich den Offset jedesmal hinzuaddieren müßte. Dagegen ändert sich die Adresse bei dem Displacmentbefehl nicht, es wird nur mit Offset zugegriffen. Darum erscheint mir dieser am geeignetsten.

    Nun hatte ich schon verschiedene Möglichkeiten probiert und komme auf keine kurze Lösung. Der einzig gangbare Weg war bisher die Offsets zu addieren und diese Summe anschließend zur Grundadresse hinzuaddieren. Dazu mußte diese vorher immer ge'push't und nach dem Zugriff wieder ge'pop't werden.
    Gibt es nur diesen Weg oder kann man dies noch anders hinkriegen?

    mfg Roger

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von wkrug
    Registriert seit
    17.08.2006
    Ort
    Dietfurt
    Beiträge
    1.892
    Mit

    LDS r16,(Prog1)
    LDS r17,(Prog1+1)
    LDS r18,(Prog1+3)
    ...

    gehs nicht ?

    Bei den Klammern bin ich mir jetzt nicht ganz sicher ob die stimmen, ne # reinkommt, oder gar nichts, aber ansonsten...

  3. #3
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    10.12.2004
    Ort
    LEV
    Beiträge
    505
    Hallo,

    Der Offset q beim LDD Rd,Y+q Befehl kann max. +-32 groß sein.
    Er ist fest in dem OPcode eingebaut, kann also leider
    nicht aus einem Register kommen.
    Mein Vorschlag wäre den LD Rd,Z zu benutzen.
    "Push" und "Pop" würde ich dabei aber lassen, das kostet zuviel Zeit.
    Stattdessen die Grundadresse lieber in einem Registerpaar halten
    und von dort mit MOVW Rd,Rd holen.

    z.B.
    ;Einmal bei Programmstart:
    CLR R2 ;null nach Register 2
    LDI R4,low(Grundaddr<<1)
    LDI R5,high(Grundaddr<<1)

    ;Jetzt der Zugriff später im Prog:
    MOVW Z,R4 ;R4 und R5 halten die Grundadresse
    ADD ZL,R6 ;R6 enthält Offset1
    ADC ZH,R2 ;R2 enthält 0
    ADD ZL,R7 ;R7 enthält Offset2
    ADC ZH,R2
    LD R8,Z ;Lesen aus der Grundadresse+Offset1+Offset2

    Das Berechnen des Offset inkl. Holen der Grundadresse dauert so 5 Taktzyklen

    Gruß Jan

  4. #4
    Benutzer Stammmitglied
    Registriert seit
    08.01.2005
    Ort
    Germany
    Beiträge
    55
    Danke erst mal für den Feedback.
    Im ersten Beitrag ist ja der klassische Weg, den ich so nicht wollte. Ich Suche nach einer Möglichkeit wie:

    .dseg
    index: .byte

    .cseg
    loop:
    ...
    ldd temp1,Z+index
    ...
    Die Adresse von index steht in Y
    ...
    ld temp2,Y
    inc temp2
    st Y,temp2
    ...
    rjmp loop
    ...

    Wenn das Displacment fest im Opcode eingebaut ist, hat sich der Fall für mich erledigt und ich muß den Umweg über Registeraddition zur Adresse machen. Da ich alle Adreßregister verplant habe, muß ich mich mit einer Doppelnutzung begnügen, wo ich dann kurz zwischensichern muß.

    Die Zeit spielt keine allzu große Rolle. In einem 5ms-Abstand bei 8MHz hat man reichlich Takte zur Verfügung. Die Hauptarbeit wird über PWM gemacht und den Timer habe ich nur zum Aufwachen genommen. Dann springt das Programm wieder in die Bearbeitungsroutine damit die Leistung der Led's wieder einen Tick mehr nach oben oder unten geregelt wird und danach pennt er weiter. Hätte auch den Wachhund nehmen können, aber bei dem weiß ich im Fehlerfall unter Umständen nicht so genau woher der Sprung zu Reset kommen könnte, vom Watch Dog oder Programmfehler. Darum nehme ich ihn nicht so gern.

    Jan, danke für den Tip mit dem Opcode. Auf die Idee bin ich noch garnicht gekommen, mir diesen mal genauer anzusehen. Ich habe mich bisher immer nur für die Schreibweise der Befehle und die Parameter interessiert.

    mfg Roger

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •