TIA SCL: DWORD -> ARRAY[1..272] of BOOL

asm

Level-1
Beiträge
52
Reaktionspunkte
6
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Ich will mehrere Doppelwörter in ein Bitarray[1..272] verschieben.

Dword#1 -> Bitarray[1..32]
Dword#2 -> Bitarray[33..64]
...

Bei SCATTER mault er die Größe vom Array an, weil das ja genau 32 Bit haben muss.

Umgehen kann ich das, wenn ich mir ein 32 Bitarray lokal bastel und damit den SCATTER fütter.

Nur wie bekomme ich dann dieses lokale 32 Bitarray in das große Bitarray..

Kennt hier jmd. eine elegante Lösung?
 
Schau dir mal AT an.
Damit kannst du einen Variablentyp mit einem anderen quasi überlagern.
Also zum Beispiel dein Bit-Array mit einem DWord-Array.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin asm,

ich würde zwei FOR-Schleifen kaskadieren. Die Innere für jeweils ein DW und die Äußere für die Bits eines DW.

In der inneren Schleife maskierst Du ein Bit aus. Vor der inneren Schleife initialisierst Du die Maske immer mit DWORD#1. Dann in jedem Schleifendurchgang mit 2 multiplizieren.

AT ist natürlich eine Variante, aber dazu kann ich nichts sagen, da ich es noch nie verwendet habe.

VG

MFreiberger
 
Zuletzt bearbeitet:
Mögliecherweise geht der Vorschlag von Blockmove nicht, wenn die Variablen unterschiedliche Größen haben.
Das Ganze würde ich in einer Schleife machen, von i := 1 to 32 und im "großen" Array einen Offset dazuaddieren, je nachdem, in welchen Bereich das ganze soll.
 
der AT funktioniert nur leider nicht bei optimierterten Bausteinen

Vielleicht könnte der move_blk_variant auch was bringen. Ich simulier mal ein bisschen
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also, um Dein kleines 32er Bitarray in ein großes Bitarray zu bekommen initialisiere die Zählvariable der FOR-Schleife entsprechend.
Mit SCATTER bin ich nicht so vertraut. Aber es könnte so gehen:

Code:
FOR #i := 0 TO 7 DO // 8 Doppelwörter
    FOR #j := 0 TO 31 DO // 32 Bits im Doppelwort
        SCATTER(IN := #SourceDWord,
                       OUT => #kleinesBitarray);
        #grossesBitarray[(#i * 32) + #j] := #kleinesBitarray[#j];
    END_FOR;
END_FOR;

oder:
Code:
FOR #i := 0 TO 7 DO // 8 Doppelwörter
    #maske := DWORD#1;
    FOR #j := 0 TO 31 DO // 32 Bits im Doppelwort
        #grossesBitarray[(#i * 32) + #j] := (#SourceDWord AND #maske);
        #maske *= 2;
    END_FOR;
END_FOR;

Hinweis:
ich habe frecherweise den Code so gestaltet, dass er mit Array[0..n], also grossesBitarray[0..271] und kleinesBitarray[0..31]arbeitet. Ich bin sowieso der Meinung, dass man ein Array immer von 0 beginnen lassen sollte (ja, es gibt Ausnahmen!). Dann tut man sich bei Schleifen meist leichter (besonders, wenn man mit Restberechnung zu Werke geht). Außerdem starten die Arrays im Panel sowieso immer bei 0, wenn man sie von der SPS in den Variablenhaushalt des Panels überträgt...
 
Zuletzt bearbeitet:
der AT funktioniert nur leider nicht bei optimierterten Bausteinen

Vielleicht könnte der move_blk_variant auch was bringen. Ich simulier mal ein bisschen
Ich sehe aber für den Fall schon einen Vorteil für den "nicht optimierten" Baustein. Das wäre die einfachste Form der Umsetzung ...
Wichtig hier zu erwähnen (das kam bei Blockmove aus meiner Sicht nicht so rüber) ist, dass man bei der AT-Überlagerung das nicht für einen Teil des Arrays machen kann sondern es für das ganze Array machen muss - das sehe ich hier aber auch niocht als Problem. Vor Allem belegt es ja keinen zusätzlichen Speicher sondern ermöglicht ja nur eine neue Sicht auf den schon vorhandenen (deklarierten) Speicher ...
 
noch eine alternative wäre:


Code:
DWord_Array[0] := Dword1;
DWord_Array[1] := Dword2;
...

Serialize(SRC_VARIABLE:=DWord_Array, DEST_ARRAY=>Array_of_Byte, POS:=POS) 
Deserialize(SRC_ARRAY:=Array_of_Byte, DEST_VARIABLE=>Array_of_bits, POS:=POS)
 
noch eine alternative wäre:


Code:
DWord_Array[0] := Dword1;
DWord_Array[1] := Dword2;
...

Serialize(SRC_VARIABLE:=DWord_Array, DEST_ARRAY=>Array_of_Byte, POS:=POS)
Deserialize(SRC_ARRAY:=Array_of_Byte, DEST_VARIABLE=>Array_of_bits, POS:=POS)
Aber Achtung: Bevor Deserialize aufgerufen wird, muss #POS neu initialisiert werden.
Zudem müssen für Serialize und Deserialize noch Rückgabewerte angegeben werden.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mh.. die Idee mit dem Dword Array ist gut.

Temp.DWORD [0..8]

db.BIT[0..287]

SCATTER_BLK(IN:=Temp.DWORD[0], COUNT_IN:=9, OUT=>db.BIT[0]);

Danke an alle Vorschläge! (y)
 
das stimmt nicht ganz, siehe TIA Hilfe " Variablen mit AT überlagern:

Anhang anzeigen 69353
Genau deshalb habe ich ja auch "anschauen" geschrieben.
AT kann recht viel und es bleibt dabei das Meiste an Typprüfung erhalten.
Wenn es möglich ist, dann verwende ich die die Remanenz-Einstellung. Ansonsten verwende ich für da auch mal ausnahmsweise nicht optimierte Bausteine.
 
Mh.. die Idee mit dem Dword Array ist gut.

Temp.DWORD [0..8]
Das sind dann aber 9 DWord's. 1..8 oder 0..7 wären 8.

Warum jetzt 0..287? Ach so.. Also 9 DWord's.

SCATTER_BLK(IN:=Temp.DWORD[0], COUNT_IN:=9, OUT=>db.BIT[0]);
Ach. Kannte ich noch gar nicht. Das ist ja elegant.

Danke an alle Vorschläge! (y)
Gerne.
 
Ja der klappt. Das lässt sogar ein 1-Element array DWORD[0..0] zu.

Damit geht dann auch das aufdröseln:

Code:
SCATTER_BLK(IN:=Temp.DWORD[0], COUNT_IN:=1, OUT=>db.BIT[0]);
..
SCATTER_BLK(IN:=Temp.DWORD[0], COUNT_IN:=1, OUT=>db.BIT[32]);
..
SCATTER_BLK(IN:=Temp.DWORD[0], COUNT_IN:=1, OUT=>db.BIT[64]);
..
 
Zuletzt bearbeitet:
Zurück
Oben