Wie kann man Hi-Byte Low-Byte spiegeln?

Klärmolch

Level-2
Beiträge
298
Reaktionspunkte
35
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
wie kann ich innerhalb eines Wortes die Bytes spiegeln, bzw. in einem Doppelwort die Worte?

M0.0 = M1.7
M0.1 = M1.6
...... = ......
M0.7 = M1.0

Mit rotieren habe ich es nicht hinbekommen.

Vielen Dank!

Klaus
 
Hi,
wie kann ich innerhalb eines Wortes die Bytes spiegeln, bzw. in einem Doppelwort die Worte?

M0.0 = M1.7
M0.1 = M1.6
...... = ......
M0.7 = M1.0

Mit rotieren habe ich es nicht hinbekommen.

Vielen Dank!

Klaus
Im Prinzip kann man es ja auch so machen, wie Du es schon geschrieben hast! Wenn Du das Umwandeln der Bits mehrfach brauchst, dann schreib Dir nen kleinen FC mit einer IN-Variable (Wort oder Doppelwort) und einer OUT-Variable (Format entsprechend dem IN).
Im FC geht das IN-Wort über dem Umweg einer Temp-Variable auf das OUT-Wort wie oben beschrieben. Den FC kann man dann mehrfach aufrufen, wie einen Rotierbefehl...
Approx
 
Hallo,

also wenn du das Wort bzw. Doppelwort bitweise haben möchtest würde ich das auch so machen. Das ist recht einfach und kann bibliothekfähig gemacht werden in einem FC.

Solltest du das Wort bzw. Doppelwort im Int bzw. Dint Format haben wollen, ist es warscheinlich wesentlich aufwändiger, müsste aber prinzipiell auch gehen.

Copy
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit den Bit-Befehlen der S7 wird das zwar schneller gehen, aber mit einer kleinen Schleife und schieben/rotieren könnte man das auch so machen:
Code:
      L     0                           // mit 0 initialisieren
      T     #out

      L     16                          // 16 Bits
loop: T     #i

      L     #out
      SLW   1                           // und nach links shiften
      T     #out

      L     #in
      UW    W#16#1                      // Bit ausmaskieren
      L     #out
      OW    
      T     #out                        // in out ein"verodern"

      L     #in                         // Eingang weiterschieben
      SRW   1
      T     #in

      L     #i
      LOOP  loop
 
zwei Schritt vor und ein zurück ...

So sollte es gehen für 16-Bit-Word (nicht getestet):
Code:
                // A1|   Akku1 H-Word     Akku1 L-Word
L    2          //Anzahl Schiebungen für alle SLW ohne Operand
L    #In_Word   // . | ................ FEDCBA9876543210

SLW  1          // F | ................ EDCBA9876543210.
RRDA            // . | F............... .EDCBA9876543210
SLW             // E | F............... DCBA9876543210..
RRDA            // . | EF.............. .DCBA9876543210.
SLW             // D | EF.............. CBA9876543210...
RRDA            // . | DEF............. .CBA9876543210..
SLW             // C | DEF............. BA9876543210....
RRDA            // . | CDEF............ .BA9876543210...
SLW             // B | CDEF............ A9876543210.....
RRDA            // . | BCDEF........... .A9876543210....
SLW             // A | BCDEF........... 9876543210......
RRDA            // . | ABCDEF.......... .9876543210.....
SLW             // 9 | ABCDEF.......... 876543210.......
RRDA            // . | 9ABCDEF......... .876543210......
SLW             // 8 | 9ABCDEF......... 76543210........
RRDA            // . | 89ABCDEF........ .76543210.......

SLW             // 7 | 89ABCDEF........ 6543210.........
RRDA            // . | 789ABCDEF....... .6543210........
SLW             // 6 | 789ABCDEF....... 543210..........
RRDA            // . | 6789ABCDEF...... .543210.........
SLW             // 5 | 6789ABCDEF...... 43210...........
RRDA            // . | 56789ABCDEF..... .43210..........
SLW             // 4 | 56789ABCDEF..... 3210............
RRDA            // . | 456789ABCDEF.... .3210...........
SLW             // 3 | 456789ABCDEF.... 210.............
RRDA            // . | 3456789ABCDEF... .210............
SLW             // 2 | 3456789ABCDEF... 10..............
RRDA            // . | 23456789ABCDEF.. .10.............
SLW             // 1 | 23456789ABCDEF.. 0...............
RRDA            // . | 123456789ABCDEF. .0..............
SLW             // 0 | 123456789ABCDEF. ................
RRDA            // . | 0123456789ABCDEF ................

SRD  16         // . | ................ 0123456789ABCDEF
T    #Out_Word
(alle SLW ohne Anzahl-Operand schieben 2 Bit - steht in Akku2)

Für 32-Bit-DWORD einfach L-Word und H-Word getrennt spiegeln und dann vertauscht zusammensetzen.
Vielleicht gibt es auch noch eine etwas kürzere Variante mit 4x Byte spiegeln.

Harald
 
In einem Byte/Word/Doppelword die Reihenfolge der Bits umdrehen/spiegeln (S7)

Wie kann man in einem Byte/Word/Doppelword die Reihenfolge der Bits umdrehen/spiegeln?
(aus der Bitfolge 76543210 soll die Bitfolge 01234567 werden)
Zunächst die Bit-Reihenfolge in den 4 Teil-Bytes spiegeln und bei Word/Doppelword danach
die in sich gespiegelten Bytes in die gespiegelte Reihenfolge bringen.
Die blauen Operationen für Byte/Word/Doppelword anpassen.
( TAK = Tausche Akku1 mit Akku2 / . = dieses Bit ist 0 )

Doppelword spiegeln:
Code:
                       [COLOR="seagreen"]// H-H-Byte H-L-Byte L-H-Byte L-L-Byte
                       // [B]31----24 23----16 15-----8 7------0[/B][/COLOR]
[COLOR="blue"]L    #In_DWord[/COLOR]         [COLOR="seagreen"]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// #In_DWord von Akku1 in Akku2 merken[/COLOR]
UD   DW#16#F0F0F0F0    [COLOR="seagreen"]// 7654.... 7654.... 7654.... 7654....[/COLOR]
SRD  4                 [COLOR="seagreen"]// ....7654 ....7654 ....7654 ....7654[/COLOR]
TAK                    [COLOR="seagreen"]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]
UD   DW#16#0F0F0F0F    [COLOR="seagreen"]// ....3210 ....3210 ....3210 ....3210[/COLOR]
SLD  4                 [COLOR="seagreen"]// 3210.... 3210.... 3210.... 3210....[/COLOR]
OD                     [COLOR="seagreen"]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#CCCCCCCC    [COLOR="seagreen"]// 32..76.. 32..76.. 32..76.. 32..76..[/COLOR]
SRD  2                 [COLOR="seagreen"]// ..32..76 ..32..76 ..32..76 ..32..76[/COLOR]
TAK                    [COLOR="seagreen"]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]
UD   DW#16#33333333    [COLOR="seagreen"]// ..10..54 ..10..54 ..10..54 ..10..54[/COLOR]
SLD  2                 [COLOR="seagreen"]// 10..54.. 10..54.. 10..54.. 10..54..[/COLOR]
OD                     [COLOR="seagreen"]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]

PUSH                   [COLOR="seagreen"]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#AAAAAAAA    [COLOR="seagreen"]// 1.3.5.7. 1.3.5.7. 1.3.5.7. 1.3.5.7.[/COLOR]
SRD  1                 [COLOR="seagreen"]// .1.3.5.7 .1.3.5.7 .1.3.5.7 .1.3.5.7[/COLOR]
TAK                    [COLOR="seagreen"]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]
UD   DW#16#55555555    [COLOR="seagreen"]// .0.2.4.6 .0.2.4.6 .0.2.4.6 .0.2.4.6[/COLOR]
SLD  1                 [COLOR="seagreen"]// 0.2.4.6. 0.2.4.6. 0.2.4.6. 0.2.4.6.[/COLOR]
OD                     [COLOR="seagreen"]// [B]01234567 01234567 01234567 01234567[/B]
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]TAD[/COLOR]                    [COLOR="seagreen"]// [B]0------7 8-----15 16----23 24----31[/B][/COLOR]
[COLOR="blue"]T    #Out_DWord[/COLOR]        [COLOR="seagreen"]// gespiegeltes DWord ausgeben[/COLOR]

Word spiegeln:
Code:
[COLOR="seagreen"]// ...   Code wie oben bis:
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]TAW[/COLOR]                    [COLOR="seagreen"]// 24----31 16----23 [B]0------7 8-----15[/B][/COLOR]
[COLOR="blue"]T    #Out_Word[/COLOR]         [COLOR="seagreen"]// gespiegeltes L-Word ausgeben[/COLOR]

Byte spiegeln:
Code:
[COLOR="seagreen"]// ...   Code wie oben bis:
// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]

[COLOR="blue"]T    #Out_Byte[/COLOR]         [COLOR="seagreen"]// gespiegeltes L-L-Byte ausgeben[/COLOR]

Harald
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich dachte es gibt einen einzigen direkten Befehl der das kann.
Nun ist mir einiges klarer.
Ich werde die von Euch angeführten Beispiele mal ausprobieren.

@Taddy
Das kann ich auch gebrauchen, S7 <--> alte Kuhnke

Vielen Dank an Euch.

Gruß
Klaus
 
Zuletzt bearbeitet:
Hi,
es hätte nur den Ablauf des Tread geändert.
Die Antwort lautet offensichlich nein.
Daraufhin hätte ich dann nach einer geeigneten Lösung gefragt.
Habe mir einen FC geschrieben und über Tempvariablen getauscht.


Gruß
Klaus
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Zunächst die Bit-Reihenfolge in den 4 Teil-Bytes spiegeln und bei Word/Doppelword danach
die in sich gespiegelten Bytes in die gespiegelte Reihenfolge bringen.
Die blauen Operationen für Byte/Word/Doppelword anpassen.
( TAK = Tausche Akku1 mit Akku2 / . = dieses Bit ist 0 )

Doppelword spiegeln:
Code:
                       [COLOR=seagreen]// H-H-Byte H-L-Byte L-H-Byte L-L-Byte[/COLOR]
[COLOR=seagreen]                      // [B]31----24 23----16 15-----8 7------0[/B][/COLOR]
[COLOR=blue]L    #In_DWord[/COLOR]         [COLOR=seagreen]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]
 
PUSH                   [COLOR=seagreen]// #In_DWord von Akku1 in Akku2 merken[/COLOR]
UD   DW#16#F0F0F0F0    [COLOR=seagreen]// 7654.... 7654.... 7654.... 7654....[/COLOR]
SRD  4                 [COLOR=seagreen]// ....7654 ....7654 ....7654 ....7654[/COLOR]
TAK                    [COLOR=seagreen]// [B]76543210 76543210 76543210 76543210[/B][/COLOR]
UD   DW#16#0F0F0F0F    [COLOR=seagreen]// ....3210 ....3210 ....3210 ....3210[/COLOR]
SLD  4                 [COLOR=seagreen]// 3210.... 3210.... 3210.... 3210....[/COLOR]
OD                     [COLOR=seagreen]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]
 
PUSH                   [COLOR=seagreen]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#CCCCCCCC    [COLOR=seagreen]// 32..76.. 32..76.. 32..76.. 32..76..[/COLOR]
SRD  2                 [COLOR=seagreen]// ..32..76 ..32..76 ..32..76 ..32..76[/COLOR]
TAK                    [COLOR=seagreen]// [B]32107654 32107654 32107654 32107654[/B][/COLOR]
UD   DW#16#33333333    [COLOR=seagreen]// ..10..54 ..10..54 ..10..54 ..10..54[/COLOR]
SLD  2                 [COLOR=seagreen]// 10..54.. 10..54.. 10..54.. 10..54..[/COLOR]
OD                     [COLOR=seagreen]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]
 
PUSH                   [COLOR=seagreen]// Zwischenergebnis Akku1 in Akku2 merken[/COLOR]
UD   DW#16#AAAAAAAA    [COLOR=seagreen]// 1.3.5.7. 1.3.5.7. 1.3.5.7. 1.3.5.7.[/COLOR]
SRD  1                 [COLOR=seagreen]// .1.3.5.7 .1.3.5.7 .1.3.5.7 .1.3.5.7[/COLOR]
TAK                    [COLOR=seagreen]// [B]10325476 10325476 10325476 10325476[/B][/COLOR]
UD   DW#16#55555555    [COLOR=seagreen]// .0.2.4.6 .0.2.4.6 .0.2.4.6 .0.2.4.6[/COLOR]
SLD  1                 [COLOR=seagreen]// 0.2.4.6. 0.2.4.6. 0.2.4.6. 0.2.4.6.[/COLOR]
OD                     [COLOR=seagreen]// [B]01234567 01234567 01234567 01234567[/B][/COLOR]
[COLOR=seagreen]// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]
 
[COLOR=blue]TAD[/COLOR]                    [COLOR=seagreen]// [B]0------7 8-----15 16----23 24----31[/B][/COLOR]
[COLOR=blue]T    #Out_DWord[/COLOR]        [COLOR=seagreen]// gespiegeltes DWord ausgeben[/COLOR]

Word spiegeln:
Code:
[COLOR=seagreen]// ...   Code wie oben bis:[/COLOR]
[COLOR=seagreen]// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]
 
[COLOR=blue]TAW[/COLOR]                    [COLOR=seagreen]// 24----31 16----23 [B]0------7 8-----15[/B][/COLOR]
[COLOR=blue]T    #Out_Word[/COLOR]         [COLOR=seagreen]// gespiegeltes L-Word ausgeben[/COLOR]

Byte spiegeln:
Code:
[COLOR=seagreen]// ...   Code wie oben bis:[/COLOR]
[COLOR=seagreen]// hier sind jetzt alle 4 Bytes in sich gespiegelt[/COLOR]
 
[COLOR=blue]T    #Out_Byte[/COLOR]         [COLOR=seagreen]// gespiegeltes L-L-Byte ausgeben[/COLOR]

Harald

Das letzte Mal habe ich sowas "gehört": war von Puccini!
Absolut feinste Klinge.
Das muss man echt sagen!
 
Ja, da haben ein paar bitgewixt.....
Mein Favorit ist jedoch nachwievor- leider finde ich den Beitrag nicht-
die Erkennung von mehr als einem Bit in einem Wort.....

ich glaube die meisten kennen das....
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Kommt ja auch hierher:
http://www-graphics.stanford.edu/~seander/bithacks.html

Da sind auch noch ein paar andere nette Varianten zu finden.
Danke für den Link Thomas, interessante Seite. Die kannte ich noch nicht.

Da habe ich den uralten Algorithmus nicht her. Den habe ich ca. 1992 mal in C in einer Grafik-Bibliothek verwendet, weil der sehr gut vom Compiler in x86-Assembler umgesetzt wurde. Ich weiß aber echt nicht mehr, aus welchem Buch ich den damals hatte.
Es war dieser C-Code:
Code:
n = (n&0xF0)>>4 | (n&0x0F)<<4;
n = (n&0xCC)>>2 | (n&0x33)<<2;
n = (n&0xAA)>>1 | (n&0x55)<<1;
den habe ich nun einfach nur für 32-Bit S7-AWL erweitert.

Als ich meinen ersten Beitrag #7 (mit der Rotieren-Variante) geschrieben habe, wußte ich noch "da war doch mal was mit Bytes" - es fiel mir aber erst später wieder richtig ein. Und weil der Algorithmus wirklich gut ist, habe ich noch einen Beitrag rangehängt.

Man muß ja solche Algorithmen nicht selber erfinden - Hauptsache, sie fallen einem bei Bedarf wieder ein und man kann sie effizient in die jeweilige Programmiersprache übersetzen.

Harald
 
Hier noch eine Variante aus der OSCAT (die brauchen dafür SCL) (aus der Plain Text Library 3.20, gekürzt):
Code:
FUNCTION REVERSE : BYTE
VAR_INPUT
	IN : BYTE;
END_VAR

(*
	version 1.1	18. feb 2008
	programmer 	hugo
	tested BY		tobias

This function reverses the bits of a byte so that after execution bit 7 is at bit 0 location and so forth.

*)

REVERSE := SHL(in,7) OR SHR(in,7) OR (ROR(in,3) AND 2#01000100) OR (ROL(in,3) AND 2#00100010)
	OR (SHL(in,1) AND 2#00010000) OR (SHR(in,1) AND 2#00001000);

END_FUNCTION

Harald
 
Zurück
Oben