Step 7 Bitfolge (Array) in Dezimalzahl wandeln

Zuviel Werbung?
-> Hier kostenlos registrieren
Also das der SFC20 das so hinbekommt wusste ich nicht.
Der bekommt das NICHT hin, Bits vertauschen kann der SFC20 nicht.
In Deinem Beitrag #14 sehe ich nichts, was darauf hindeutet, daß Du auch noch Bits vertauschen wolltest.
Dein Text und Dein Code suggerieren ein einfaches lineares Kopieren.
(Warum hast Du eigentlich die Bits in falscher Reihenfolge?)

Ich denke wenn ich den Wert 0x0C vorher um 4 nach links rotiere (sprich: die 4 niederwertigen mit den 4 höherwertigen Bits tauschen) und dann den SFC20 darauf anwende, dass mir der dann die richte Bitfolge generiert.
Bist Du sicher, daß Du die 4 niederwertigen mit den 4 höherwertigen Bits tauschen mußt (0123_4567 --> 4567_0123)? Oder willst Du vielleicht die Bitreihenfolge komplett spiegeln (Reverse) (0123_4567 --> 7654_3210)?
Deine Beispielzahl B#16#0C ist als Beispiel ziemlich ungeeignet, besser: wie soll ein B#16#29 nach dem Übertragen aussehen?

Ist das so schwer, sich eindeutig auszudrücken? Ist das so schwer, uns ein paar grundlegende Informationen zu geben? z.B. wissen wir immer noch nicht, für welche CPU das ganze sein soll. Manche CPU lassen diese indirekten Zugriffe nicht zu ...

Meine Glaskugel sagt:
Du programmierst mit Step7 V5.x eine CPU S7-300/400
Du hast im STAT eines FB
* BYTE_CODE : ARRAY[0..5] OF BYTE
* BIT_CODE : ARRAY[0..47] OF BOOL
und willst das BYTE-Array BYTE_CODE in das BOOL-Array BIT_CODE umkopieren, wobei die Bits innerhalb jedes Bytes gespiegelt werden sollen.


Nun, eine Kopierschleife aus dem Byte-Array in das Bit-Array könnte etwa so aussehen:
Code:
      L     P##BYTE_CODE
      T     #PTR_BYTE                   //Pointer auf Quellarray

      L     P##BIT_CODE
      T     #PTR_BIT                    //Pointer auf Zielarray

      L     6                           //Anzahl Bytes
next: T     #SCHLEIFENCOUNTER

[COLOR="#0000FF"]// A) Bits 1:1 kopieren[/COLOR]
      L     DIB [#PTR_BYTE]             //Quellbyte lesen
      T     DIB [#PTR_BIT]              //auf 8 Zielbits schreiben

[COLOR="#0000FF"]// B) oder Bits spiegeln/tauschen/...
//    z.B. Bitwertigkeiten addieren
//    oder Bits tauschen via Schieben und maskieren
//    oder Code von Larry #10, oder ...[/COLOR]

//Pointer weiterstellen
      L     #PTR_BYTE                   //Pointer auf Quellarray
      L     P#1.0                       //1 Byte = 8 Bit weiterstellen
      +D    
      T     #PTR_BYTE

      L     #PTR_BIT                    //Pointer auf Zielarray
      L     P#1.0                       //1 Byte = 8 Bit weiterstellen
      +D    
      T     #PTR_BIT

      L     #SCHLEIFENCOUNTER
      LOOP  next
(nicht getestet, nicht optimiert)
Einen der Pointer (z.B. #PTR_BYTE) könnte man auch in AR1 behalten.

Die Bits im Byte spiegeln siehe nächster Beitrag.

Harald
 
Bits in einem Byte spiegeln (Reverse)

... durch addieren der Bitwertigkeiten:
Code:
// Bitwertigkeiten addieren
      LAR1  #PTR_BYTE                   //Pointer Quellbyte

      L     0                           //Addition mit 0 anfangen

      U     DIX [AR1,P#0.7]             //Quellbyte.7
      SPBN  Bit6
      +     1
Bit6: U     DIX [AR1,P#0.6]             //Quellbyte.6
      SPBN  Bit5
      +     2
Bit5: U     DIX [AR1,P#0.5]             //Quellbyte.5
      SPBN  Bit4
      +     4
Bit4: U     DIX [AR1,P#0.4]             //Quellbyte.4
      SPBN  Bit3
      +     8
Bit3: U     DIX [AR1,P#0.3]             //Quellbyte.3
      SPBN  Bit2
      +     16
Bit2: U     DIX [AR1,P#0.2]             //Quellbyte.2
      SPBN  Bit1
      +     32
Bit1: U     DIX [AR1,P#0.1]             //Quellbyte.1
      SPBN  Bit0
      +     64
Bit0: U     DIX [AR1,P#0.0]             //Quellbyte.0
      SPBN  BitE
      +     128
BitE: T     DIB [#PTR_BIT]              //auf 8 Zielbits schreiben

... durch paarweises vertauschen via Schieben und Maskieren:
Code:
// Algorithmus:
// n = (n&0xF0)>>4 | (n&0x0F)<<4;
// n = (n&0xCC)>>2 | (n&0x33)<<2;
// n = (n&0xAA)>>1 | (n&0x55)<<1;

      L     DIB [#PTR_BYTE]             //Quellbyte lesen

      PUSH                              // Akku1 in Akku2 merken
      UW    W#16#F0                     // 7654....
      SRW   4                           // ....7654
      TAK                               // 76543210
      UW    W#16#F                      // ....3210
      SLW   4                           // 3210....
      OW                                // 32107654

      PUSH                              // Zwischenergebnis Akku1 in Akku2 merken
      UW    W#16#CC                     // 32..76..
      SRW   2                           // ..32..76
      TAK                               // 32107654
      UW    W#16#33                     // ..10..54
      SLW   2                           // 10..54..
      OW                                // 10325476

      PUSH                              // Zwischenergebnis Akku1 in Akku2 merken
      UW    W#16#AA                     // 1.3.5.7.
      SRW   1                           // .1.3.5.7
      TAK                               // 10325476
      UW    W#16#55                     // .0.2.4.6
      SLW   1                           // 0.2.4.6.
      OW                                // 01234567

      T     DIB [#PTR_BIT]              //auf 8 Zielbits schreiben

siehe auch mal hier

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Der bekommt das NICHT hin, Bits vertauschen kann der SFC20 nicht.
In Deinem Beitrag #14 sehe ich nichts, was darauf hindeutet, daß Du auch noch Bits vertauschen wolltest.
Dein Text und Dein Code suggerieren ein einfaches lineares Kopieren.
(Warum hast Du eigentlich die Bits in falscher Reihenfolge?)

Ich meinte damit, dass der SFC20 einzelne Bytes direkt in Bits "umwandeln" kann beim Kopieren. Hätte einen Fehlerwert erwartet..
Mit der falschen Reihenfolge ist mir erst später aufgefallen.

Bist Du sicher, daß Du die 4 niederwertigen mit den 4 höherwertigen Bits tauschen mußt (0123_4567 --> 4567_0123)? Oder willst Du vielleicht die Bitreihenfolge komplett spiegeln (Reverse) (0123_4567 --> 7654_3210)?
Deine Beispielzahl B#16#0C ist als Beispiel ziemlich ungeeignet, besser: wie soll ein B#16#29 nach dem Übertragen aussehen?

Die Bitreihenfolge soll so angeordnet sein, dass aus B#16#29 --> B#16#92 wird.
Also es muss getauscht werden, sodass aus 0123_4567 --> 4567_0123 wird.

Ist das so schwer, sich eindeutig auszudrücken? Ist das so schwer, uns ein paar grundlegende Informationen zu geben? z.B. wissen wir immer noch nicht, für welche CPU das ganze sein soll. Manche CPU lassen diese indirekten Zugriffe nicht zu ...

Meine Glaskugel sagt:
Du programmierst mit Step7 V5.x eine CPU S7-300/400
Du hast im STAT eines FB
* BYTE_CODE : ARRAY[0..5] OF BYTE
* BIT_CODE : ARRAY[0..47] OF BOOL
und willst das BYTE-Array BYTE_CODE in das BOOL-Array BIT_CODE umkopieren, wobei die Bits innerhalb jedes Bytes gespiegelt werden sollen.

Ich dachte das wäre aus meiner Signatur ersichtlich. Also ich habe arbeite mit Step7 V5.5 und einer CPU 414-3 PN/DP.
Die Beiden Arrays sind im STAT des FB, das ist korrekt.
Mit: * BYTE_CODE : ARRAY[0..5] OF BYTE
* BIT_CODE : ARRAY[0..47] OF BOOL
B#16#29 wird gewandelt in B#16#92 und in den BIT_CODE umkopieren.

Aber vielen Dank für die ausführlichen Beispiele.
Ich setzte mich später nochmal ran.

Gruß
TimeOut
 
Zuletzt bearbeitet:
Ich dachte das wäre aus meiner Signatur ersichtlich. Also ich habe arbeite mit Step7 V5.5 und einer CPU 414-3 PN/DP.
In Deiner Signatur stehen 2 verschiedene CPUs ...


Die Bitreihenfolge soll so angeordnet sein, dass aus B#16#29 --> B#16#92 wird.
Also es muss getauscht werden, sodass aus 0123_4567 --> 4567_0123 wird.
also Nibbles tauschen
Code:
      ...
next: T     #SCHLEIFENCOUNTER

      L     DIB [#PTR_BYTE]             //Quellbyte lesen

[COLOR="#0000FF"]// Nibbles tauschen
      SLW   4
      TAW
      RRD   4
      TAW
      RLD   4[/COLOR]

      T     DIB [#PTR_BIT]              //auf 8 Zielbits schreiben

//Pointer weiterstellen
      ...

Harald
 
AWL: Nibbles in einem Byte tauschen

Die Reihenfolge der Bits in einem Byte nibble-weise tauschen: 7654_3210 --> 3210_7654
Das entspricht dem Tauschen von 2 BCD-Ziffern: B#16#29 --> B#16#92

In C würde man schreiben: n = n>>4 | n<<4;
Das kann man leicht in AWL übersetzen (braucht allerdings 2 Akkus):
Code:
      L     #myByte

// C-like : n = n>>4 | n<<4;
      PUSH                              // Akku1 in Akku2 merken
      SRW   4                           // ....7654
      TAK                               // 76543210
      SLW   4                           // 3210....
      OW                                // 32107654

      T     #myByte

Man kann auch nur mit Akku1 die Bits tauschen mit Schieben-/Rotieren-/Tauschen-Operationen. Da gibt es viele Varianten.
(nur mit Schieben geht es nicht, es muß mindestens 1 Operation dabei sein, die die "hinteren" Bits nach "vorne" bringt: TAW, TAD oder RRD/RLD)

Code:
// mein Favorit
      SLW   4                           // ........ ........ ....7654 3210....
      TAW                               // ........ ........ 3210.... ....7654
      RRD   4                           // 7654.... ........ ....3210 ........
      TAW                               // 7654.... ........ ........ ....3210
      RLD   4                           // ........ ........ ........ 32107654

// oder
      SLD   12                          // ........ ....7654 3210.... ........
      TAD                               // ........ 3210.... ....7654 ........
      SRD   4                           // ........ ....3210 ........ 7654....
      TAW                               // ........ ....3210 7654.... ........
      SRD   12                          // ........ ........ ........ 32107654

// oder
      RRD   4                           // 3210.... ........ ........ ....7654
      TAD                               // ....7654 ........ ........ 3210....
      RLD   12                          // ........ ....3210 ........ 7654....
      TAW                               // ........ ....3210 7654.... ........
      SRD   12                          // ........ ........ ........ 32107654

// Nibbles tauschen ala Rubik's Cube
      RRD   4                           // 3210.... ........ ........ ....7654
      SLW   12                          // 3210.... ........ 7654.... ........
      SRD   12                          // ........ ....3210 ........ ....7654
      SLW   12                          // ........ ....3210 7654.... ........
      SRD   12                          // ........ ........ ........ 32107654

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@PN/DP: Vielen Dank für deine Tipps.

Code:
      ...
next: T     #SCHLEIFENCOUNTER

      L     DIB [#PTR_BYTE]             //Quellbyte lesen

[COLOR=#0000FF]// Nibbles tauschen
      SLW   4
      TAW
      RRD   4
      TAW
      RLD   4[/COLOR]

      T     DIB [#PTR_BIT]              //auf 8 Zielbits schreiben

//Pointer weiterstellen
      ...

Habe ich probiert. Das Tauschen der Nibbles hat auch super funktioniert. Allerdings hat er mir dann die einzelnen Bits trotzdem wieder richtig (Also für meine Weiterverarbeitung "falsch")-herum in das BIT_CODE Array kopiert.

Daraufhin habe ich nochmal selbst ein wenig Code erzeugt und so tut er jetzt wie er tun soll.

Code:
      L     0
      T     #SCHLEIFENCOUNTER
      L     128
      T     #ZWISCHENWERT_BIT_INT
      L     P##BYTE_CODE                //Erzeuge Quell-Pointer
      T     #PTR_BYTE
      L     P##BIT_CODE                 // Erzeuge Ziel-Pointer
      T     #PTR_BIT


_1:   L     DIB [#PTR_BYTE]
      L     #ZWISCHENWERT_BIT_INT
      UW    
      L     #ZWISCHENWERT_BIT_INT
      ==I                               // Prüfe auf Bitwertigkeit
      =     DIX [#PTR_BIT]


      LAR1  #PTR_BIT                    // Pointer weiterstellen
      +AR1  P#0.1
      TAR1  #PTR_BIT




      L     #ZWISCHENWERT_BIT_INT       // Bit-Wert verringern
      SRW   1
      T     #ZWISCHENWERT_BIT_INT


      L     #ZWISCHENWERT_BIT_INT
      L     0
      ==I   
      SPBN  _1




      L     #SCHLEIFENCOUNTER
      L     1
      +I    
      T     #SCHLEIFENCOUNTER


      LAR1  #PTR_BYTE                   // Pointer weiterstellen
      +AR1  P#1.0
      TAR1  #PTR_BYTE


      L     128                         // Neues Byte --> Bitwert neu initialisieren
      T     #ZWISCHENWERT_BIT_INT


      L     #SCHLEIFENCOUNTER
      L     6
      ==I   
      SPBN  _1

Es geht bestimmt noch schöner und schneller, aber so genügt mir das erst mal ;)
Vielen Dank an alle

Gruß
TimeOut
 
Kurz überflogen... irgendwie tut Dein Code nicht das was Du erklärt hast was Du wolltest. :confused: Wo tauschst Du nun die Nibbles?

Harald
 
Zurück
Oben