WORD aus einzelnen Bits zusammensetzen

moeins

Level-1
Beiträge
165
Reaktionspunkte
16
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich will mir einen FB bauen der als Eingang #Bit1...#Bit16 hat und möchte diese Bits zu einem #Ausgangswort zusammensetzen. Die Position der Bits in dem Wort soll variabel sein.
Irgendwie fehlt mir der Ansatz dazu, wie ich in dem #Ausgangswort die Bit gezielt platziere...?!?
 
...?
Was willst du genau machen ?
Eine Funktion, die als Ausgang (oder IN_OUT) ein WORD liefert, in dem du per Parameter ein Bit setzt, also in etwa so ?
Code:
FC xyz
  Bit_Nr :   [0 .. 15]
  Status :  [0 / 1]
  SetWORD :
schreib mal etwas mehr (genauer) dazu ...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also dann will ich es nochmal kurz erklären. So in etwa :

FC xyz
Bit1: E0.1
Bit2: M12.3
Bit3: E6.2
..
Bit16: M3.4
Ausgangswort: DB2.DBW4
Ich habe am FB/FC die Eingänge #Bit1, #Bit2, #Bit3, ...bis #Bit16.
An diese Eingänge werden Merker bzw. SPS-Eingänge angelegt.
Diese 16 Bit sollen dann so zusammengesetzt werden das dadurch ein Wort entsteht, was ich dann in WinCC Flexible als Meldewort nutzen will.

Prinzipiell brauche ich nur Bit1-Bit16 so zusammensetzen das es mit Lowbyte und Highbyte passt und so in WinCC auch gleich mit Meldung 1 beginnt.

Ich möchte diese Funktion aber auch für andere Zwecke nutzen.

Mir fehlt jetzt nur der Ansatz das z.B. wenn #Bit1 =1 ist, diese in das #Ausgangswort an die entsprechende Stelle zu schreiben.
Wie kann ich auf die einzelnen Bits einer #symbolischen Variable zugreifen ?
 
in deinem FC hat das ausgangswort eine lokale adresse z.b. LW 6 ... bei diesem wort kannst du dann jedes bit einzeln anfassen z.b. L 6.2 oder L 7.5

....ich hör sie schon wieder aufschreien... :rolleyes:
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Und hier dann ein Pointervorschlag ;) :

#######################################
FUNCTION "Bit->Word" : VOID
TITLE =Bit -> Word
VERSION : 0.1

VAR_INPUT
BIT_01 : BOOL ;
BIT_02 : BOOL ;
BIT_03 : BOOL ;
BIT_04 : BOOL ;
BIT_05 : BOOL ;
BIT_06 : BOOL ;
BIT_07 : BOOL ;
BIT_08 : BOOL ;
BIT_09 : BOOL ;
BIT_10 : BOOL ;
BIT_11 : BOOL ;
BIT_12 : BOOL ;
BIT_13 : BOOL ;
BIT_14 : BOOL ;
BIT_15 : BOOL ;
BIT_16 : BOOL ;
END_VAR
VAR_OUTPUT
WORD_AUS : WORD ;
END_VAR
VAR_TEMP
temp_word : WORD ;
END_VAR
BEGIN
NETWORK
TITLE =
LAR1 P##temp_word;
U #BIT_01;
= L [AR1,P#1.0];
U #BIT_02;
= L [AR1,P#1.1];
U #BIT_03;
= L [AR1,P#1.2];
U #BIT_04;
= L [AR1,P#1.3];
U #BIT_05;
= L [AR1,P#1.4];
U #BIT_06;
= L [AR1,P#1.5];
U #BIT_07;
= L [AR1,P#1.6];
U #BIT_08;
= L [AR1,P#1.7];
U #BIT_09;
= L [AR1,P#0.0];
U #BIT_10;
= L [AR1,P#0.1];
U #BIT_11;
= L [AR1,P#0.2];
U #BIT_12;
= L [AR1,P#0.3];
U #BIT_13;
= L [AR1,P#0.4];
U #BIT_14;
= L [AR1,P#0.5];
U #BIT_15;
= L [AR1,P#0.6];
U #BIT_16;
= L [AR1,P#0.7];
L #temp_word;
T #WORD_AUS;
END_FUNCTION
#######################################

Gruß André
 
Viele Wege führen nach Rom

Und hier noch eine Variante in SCL, läßt sich übrigens leicht auf BYTEs oder DW's erweitern:

-------------------------------
FUNCTION FC326 : VOID


TITLE = 'BitsToWord'
//
// Funktion: 16 Bits werden einem Word zugeordnet.
//
VERSION : '1.0'

// Bausteinparameter
VAR_INPUT
// Eingangsparameter
BIT_1 : BOOL;
BIT_2 : BOOL;
BIT_3 : BOOL;
BIT_4 : BOOL;
BIT_5 : BOOL;
BIT_6 : BOOL;
BIT_7 : BOOL;
BIT_8 : BOOL;
BIT_9 : BOOL;
BIT_10 : BOOL;
BIT_11 : BOOL;
BIT_12 : BOOL;
BIT_13 : BOOL;
BIT_14 : BOOL;
BIT_15 : BOOL;
BIT_16 : BOOL;


END_VAR

VAR_IN_OUT
// Durchgangsparameter
END_VAR

VAR_OUTPUT
WORD_OUT : WORD;
END_VAR


VAR_TEMP
// temporäre Variablen
I : INT;
WORD_TMP : WORD;
BITS: ARRAY[1..16] OF BOOL;

END_VAR
BITS[1 ]:= BIT_1 ;
BITS[2 ]:= BIT_2 ;
BITS[3 ]:= BIT_3 ;
BITS[4 ]:= BIT_4 ;
BITS[5 ]:= BIT_5 ;
BITS[6 ]:= BIT_6 ;
BITS[7 ]:= BIT_7 ;
BITS[8 ]:= BIT_8 ;
BITS[9 ]:= BIT_9 ;
BITS[10 ]:= BIT_10 ;
BITS[11 ]:= BIT_11 ;
BITS[12 ]:= BIT_12 ;
BITS[13 ]:= BIT_13 ;
BITS[14 ]:= BIT_14 ;
BITS[15 ]:= BIT_15 ;
BITS[16 ]:= BIT_16 ;

// Anweisungsteil
WORD_TMP := B#16#0;
FOR I := 0 TO 15 DO
WORD_TMP:=SHL(IN:=WORD_TMP,N:=1);
IF ((BITS[16-I]) = TRUE) THEN
WORD_TMP := WORD_TMP OR B#16#01 ;

ELSE
WORD_TMP := WORD_TMP OR B#16#00 ;
END_IF;
END_FOR;
// *********************
// Ausgabe
// *********************
WORD_OUT :=WORD_TMP;

END_FUNCTION
 
Mal auf die schnelle mit dem AT Operant in SCL:
Code:
FUNCTION FC25 : WORD

VAR_INPUT
  Bit_00  :BOOL;
  Bit_01  :BOOL;
  Bit_02  :BOOL;    
  Bit_03  :BOOL;
  Bit_04  :BOOL;
  Bit_05  :BOOL;
  Bit_06  :BOOL;    
  Bit_07  :BOOL;  
  Bit_08  :BOOL;
  Bit_09  :BOOL;
  Bit_10  :BOOL;    
  Bit_11  :BOOL;  
  Bit_12  :BOOL;
  Bit_13  :BOOL;
  Bit_14  :BOOL;    
  Bit_15  :BOOL;      
END_VAR

VAR_TEMP
  // temporäre Variablen
  myWord  :WORD;
  myArray AT myWord :ARRAY[0..15] OF BOOL; 
END_VAR

  // Anweisungsteil
  myArray[ 0] := Bit_00;
  myArray[ 1] := Bit_01;
  myArray[ 2] := Bit_02;
  myArray[ 3] := Bit_03;
  myArray[ 4] := Bit_04;
  myArray[ 5] := Bit_05;
  myArray[ 6] := Bit_06;
  myArray[ 7] := Bit_07;
  myArray[ 8] := Bit_08;
  myArray[ 9] := Bit_09;
  myArray[10] := Bit_10;
  myArray[11] := Bit_11;
  myArray[12] := Bit_12;
  myArray[13] := Bit_13;
  myArray[14] := Bit_14;
  myArray[15] := Bit_15;
  
  FC25 := ROL(IN:=myWord, N:=8); (* MSB und LSB Tauschen *)
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... und hier aus meinem Fundus zur Vervollständigung die SCL-Lösung für das, was ich oben weiter gefragt hatte ...
[gezielt ein Bit im WORD setzten / löschen]

Code:
FUNCTION FC424 : VOID              // UP Bit in WORD setzen
 
VAR_INPUT
   Bit_Nr : INT ;     // Bit-Nummer  [0..15] , -1 = alle
   Aktion : INT ;     // 0 = löschen , 1 = setzen
END_VAR
VAR_IN_OUT
   WORD_Var : WORD ;  // Variable, in der das Bit geändert werden soll   
END_VAR
VAR_OUTPUT
END_VAR
VAR_TEMP
   Shift_Var : WORD ;
   Shift_Anz : INT ;
   Maske_W   : WORD ; 
END_VAR
 
BEGIN
IF Bit_Nr >= 00 THEN
   Shift_Anz := 0 ;
      IF     Bit_Nr <= 07 THEN Shift_Anz := Bit_Nr + 8 ;
      ELSIF  Bit_Nr <= 15 THEN Shift_Anz := Bit_Nr - 8 ;
      END_IF ;
   Shift_Var := 1 ; 
   Maske_W := SHL (IN:=Shift_Var , N:=Shift_Anz) ;  // Maske bilden (1 Bit)
 
ELSIF Bit_Nr = -1 THEN 
   Maske_W := 16#FFFF ;                             // Maske bilden (alle Bits)
END_IF ; 
 
IF Aktion = 0 THEN  // Bit löschen
   Maske_W := Maske_W XOR 16#FFFF ;    // Maske invertieren
   WORD_Var := WORD_Var AND Maske_W ; 
ELSE                // Bit setzen
   WORD_Var := WORD_Var OR Maske_W ; 
END_IF ;
 
END_FUNCTION

Vielleicht hat ja auch jemand daran Spass ...
 
in deinem FC hat das ausgangswort eine lokale adresse z.b. LW 6 ... bei diesem wort kannst du dann jedes bit einzeln anfassen z.b. L 6.2 oder L 7.5

....ich hör sie schon wieder aufschreien... :rolleyes:

Hallo vierlagig,

da möchte ich jetzt mal aufschreien...

Diese Lösung ist wirklich nicht empfehlenswert!

Spätestens wenn du mal Lokalvariablen nachfügst, wird das im Chaos enden.

Viel besser ist es, du benutzt den P## - Befehl.

Damit kannst du symbolisch auf Bits im Wort zugreifen.

Ich glaub, Volker hat dazu einen Beitrag für die FAQ geschrieben,
alternantiv gibts auf meiner HP das Beispiel "Graycode", dass die Verwendung des P##
demonstriert.

Zu guter letzt kann man auch in der Not auf das gute alte Schmiermerkerwort zurück greifen...

CU

Jürgen


.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich wollte Dir ein Danke verpassen und 100% Ack. schreiben aber dann kam das Grauen:

Bitte, bitte nicht! Schmiermerker gehören zu den schlimmsten Stolpersteine.

Hallo Zotos,

daran erkennt man, dass du noch Jung bist und kein S5 kennst! :)
In der S5 - Welt sind Schmiermerker zwingend notwendig,
auch in den Siemens - Bausteinen werden diese verwendet.

Ich schrieb ja extra in der Not, und dann frisst ja der Teufel bekanntlich sogar Fliegen...

Wenn man ein Schmiermerkerwort einsetzt und in der Symbolliste ordentlich dokumentiert,
ist es m.E. nicht verboten. Aber auch nicht schön, ganz klar.


CU

Jürgen


.
 
Zuletzt bearbeitet:
es ging um einen baustein, der aus 16 bits ein word baut, kann mir nicht vorstellen, wie bei einer solchen standardfunktion jemand noch andere lokale variablen hinzufügen möchte ... *pissigwird* :rolleyes:
 
Schmiermerker haben bei Step7 ihre Existenzberechtigung verloren.
Wer diese ernsthaft einsetzt ist einfach geistig bei der S5 stehen geblieben und hat sich für den falschen Beruf entschieden.

@IBN-Service: Danke für die Verbesserung!
IBN-Service schrieb:
Da ist aber einer aus dem Konzept geraten, was?
"Wer das ernst haft einsetzt ist einfach Geistig bei der S5 stehen geblieben und hat sich für den falschen Beruf entschieden."

ernsthaft ist EIN Wort,
geistig wird KLEIN geschrieben.

Glaub ich zumindest...

Schönen Tag noch,

Jürgen.
__________________
Softwareentwicklung und Inbetriebnahme weltweit:
http://www.ibn-service.com
Zufall überlassen wir den anderen
 
Zuletzt bearbeitet:
Das Ausgangswort liegt nicht in den Lokaldaten der FC. Auf die Ein- und Ausgänge eine Funktion kann man nicht mittels absoluter Adressierung zugreifen, behaupte ich jetzt mal.


Gruß, Onkel
 
Zurück
Oben