Aus einer FB Struktur ein Wort auslesen

ottopaul

Level-1
Beiträge
160
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich habe in einem FB eine STAT-Structure angelegt, die über 4Bytes geht. Dabei sind die einzelnen Bits angelegt worden und kommentiert.
Nun will ich aber nur das erste Word als WORD auslesen. Wie mache ich das, da nur nur Bits projektiert sind?
 
... wie Ralle schon gesagt hat :
im TEMP-Bereich Var hPointer : DWORD anlegen

L p##erstes_Bit_aus_Structur
t hPointer

L DIW [hPointer]

so ginge es zum Beispiel ...
 
Bei einer Struct ein ganz klein wenig anders:

Code:
FUNCTION_BLOCK FB 32
TITLE =
VERSION : 0.1


VAR_OUTPUT
  Output : WORD ;    
END_VAR
VAR
  Otto : STRUCT     
   Bool_1 : BOOL ;    
   Bool_2 : BOOL ;    
   Bool_3 : BOOL ;    
   Bool_4 : BOOL ;    
   Bool_5 : BOOL ;    
   Bool_6 : BOOL ;    
   Bool_7 : BOOL ;    
   Bool_8 : BOOL ;    
   Bool_9 : BOOL ;    
   Bool_10 : BOOL ;    
   Bool_11 : BOOL ;    
   Bool_12 : BOOL ;    
   Bool_13 : BOOL ;    
   Bool_14 : BOOL ;    
   Bool_15 : BOOL ;    
   Bool_16 : BOOL ;    
   Bool_17 : BOOL ;    
   Bool_18 : BOOL ;    
  END_STRUCT ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     P##Otto; 
      LAR1  ; 

      L     DIW [AR1,P#0.0]; 
      T     #Output; 
END_FUNCTION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... wie Ralle schon gesagt hat :
im TEMP-Bereich Var hPointer : DWORD anlegen

L p##erstes_Bit_aus_Structur
t hPointer

L DIW [hPointer]

so ginge es zum Beispiel ...


l p##stucturname
lar1

l diw [ar1,p#0.0]


zweites wort

l diw [ar1,p#2.0]


drittes bit vom zweiten wort

u dix [ar1,p#2.2]
 
Zuletzt bearbeitet:
Noch'n FC

Hallo,

ich hab das mal so gemacht - und ruf seitdem den FC auf:

Code:
FUNCTION FC326 : VOID
 
TITLE = 'BitsToWord'
//
// Funktion: 16 Bits werden einem Word zugeordnet.
//
VERSION : '1.0'
AUTHOR  : 'FA/ST'
FAMILY  : 'CONVERT'
// 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

hth
 
Hallo,

ich hab das mal so gemacht - und ruf seitdem den FC auf:

Code:
FUNCTION FC326 : VOID
 
TITLE = 'BitsToWord'
//
// Funktion: 16 Bits werden einem Word zugeordnet.
//
VERSION : '1.0'
AUTHOR  : 'FA/ST'
FAMILY  : 'CONVERT'
// 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

hth


für meinen geschmack zu kompliziert, zu aufgebalsen und zu langsam...

abgesehen davon frisst der fc aufruf mehr zeilen als die awl um das über einen pointer zu machen...
 
Zuviel Werbung?
-> Hier kostenlos registrieren
l p##stucturname
lar1

l diw [ar1,p#0.0]


zweites wort

l diw [ar1,p#2.0]


drittes bit vom zweiten wort

u dix [ar1,p#2.2]

Bei einer registerindirekten bereichsexternen (bereichsübergreifenden) Adressierung kann man auch schreiben:

l p##stucturname
lar1

l w [ar1,p#0.0]


zweites wort

l w [ar1,p#2.0]


drittes bit vom zweiten wort

u [ar1,p#2.2]

Gruß Kai
 
Bei einer registerindirekten bereichsexternen (bereichsübergreifenden) Adressierung kann man auch schreiben:

Gruß Kai

:sm19:Ich brüll mich grad fast weg, Markus, uns fehlt noch ein smiliey wo einer mit den Fäusten vor sich auf dem Boden rumdrischt :ROFLMAO:!
 
Du bist ja bloß neidisch, weil Du nicht so tolle Fremdwörter kennst. :ROFLMAO:

Im übrigen heißt das tatsächlich registerindirekte, bereichsexterne (bereichsübergreifende) Adressierung.

Und wenn Du schreibst:

Code:
FUNCTION_BLOCK FB 32
TITLE =
VERSION : 0.1
 
VAR_OUTPUT
  Output : WORD ;    
END_VAR
VAR
  Otto : STRUCT     
   END_STRUCT ;    
END_VAR
BEGIN
NETWORK
TITLE =
 
      L     P##Otto; 
      LAR1  ; 
 
      [COLOR=red]L     DIW [AR1,P#0.0];[/COLOR] 
      T     #Output; 
END_FUNCTION_BLOCK

dann ist das einfach nur unsauber programmiert.

Gruß Kai
 
Das Dein Programmcode falsch ist, hat hier keiner behauptet. Dein Programmcode funktioniert ja auch, er ist einfach nur unsauber programmiert. :idea:


Registerindirekte bereichsexterne (bereichsübergreifende) Adressierung

Bei der bereichsexternen (bereichsübergreifenden) Adressierung wird der Bereichszeiger zusammen mit dem Operandenbereich in das Adressregister geschrieben. Bei der registerindirekten Anweisung braucht man dann als Operand nur noch die Kennung für die Operandenbreite anzugeben: keine Angabe bei einem Bit, B bei einem Byte, W bei einem Wort, D bei einem Doppelwort.

Code:
      [COLOR=red]L     P##Otto[/COLOR]
      LAR1
 
      [COLOR=red]L     W [AR1,P#0.0][/COLOR]
      T     #Output

Im folgendem Programmcode wird ein bereichsexterner (bereichsübergreifender) Zeiger auf das Globaldatenbit DBX10.0 in das Adressregister AR1 geladen. Dann wird eine bereichsexterne (bereichsübergreifende) Adressierung über das Adressregister AR1 auf ein Wort durchgeführt. Bei der Ausführung der Ladeanweisung wird das Globaldatenwort DBW10 geladen.

Code:
      [COLOR=red]L     P#DBX10.0[/COLOR]
      LAR1  
 
      [COLOR=red]L     W [AR1,P#0.0][/COLOR]


Registerindirekte bereichsinterne Adressierung mit bereichsexternen (bereichsübergreifenden) Zeiger

Steht im Adressregister der Bereichszeiger zusammen mit dem Operandenbereich (bereichsexterner, bereichsübergreifender Zeiger) und wird dieser Zeiger bei einer bereichsinternen Anweisung angegeben, dann wird der im Adressregister stehende Operandenbereich ignoriert.

Code:
      [COLOR=red]L     P##Otto[/COLOR]
      LAR1  
 
      [COLOR=red]L     DIW [AR1,P#0.0][/COLOR]
      T     #Output

Im folgenden Programmcode wird ein bereichsexterner (bereichsübergreifender) Zeiger auf das Globaldatenbit DBX10.0 in das Adressregister AR1 geladen. Dann wird eine bereichsintene Adressierung über das Adressregister AR1 auf ein Merkerwort durchgeführt. Bei der Ausführung der Ladeanweisung wird das Merkerwort MW10 geladen.

Code:
      [COLOR=red]L     P#DBX10.0[/COLOR]
      LAR1  
 
      [COLOR=red]L     MW [AR1,P#0.0][/COLOR]

Gruß Kai
 
Zuletzt bearbeitet:
Schön, dann ignorier ich doch auch mal :ROFLMAO:! Halt unsauber, aber so bin ich :cool:!

Hier mußt du erst nachsehen, was #Otto denn ist um zu wissen, wo es herkommt:

L P##Otto
LAR1

L W [AR1,P#0.0]
T #Output


Hier weiß man gleich, wo es herkommt:

L P##Otto
LAR1

L DIW [AR1,P#0.0]
T #Output

Also was solls!
 
Zuletzt bearbeitet:
Im SPS-Forum kann jeder nach seiner Facon selig werden (frei nach Friedrich dem Großen) ;)

Gruß Kai
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Also ích denke ihr seid beide Eliteprogrammierer... was solls's.

Eine Anektote:
Beim SIE Wien war früher ein Programmierer (mittlerweile ein Superfreund von mir).... der hat damals- jetzt ist er ja (leider) Vertriebsmann- viele unglaublich tolle Software geschrieben, ua. auch am Flughafen Wien.... einige Jahre später kam ich auch dort hin um einige Änderungen zu machen und der Verantwortliche dort erinnerte sich an der Herrn vom Siemens: "quick and dirty- er war einen Tag hier- alles funktionierte- aber wir haben 3 Wochen nachdokumentiert"... wie man sieht jeder hat seine Art und Stil... mit allen Vor-und Nachteilen.

Seid nachsichtig.... auf dieser Leistungsebene zumindest.....

Gute Nacht
 
Zurück
Oben