Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 9 von 9

Thema: SCL: 4 Byte TO Real - Pointer in Funktion

  1. #1
    Registriert seit
    25.11.2009
    Beiträge
    38
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,

    von einem Profibusgerät bekomme ich eine Real Variable. Leider sind die 4 Bytes aus denen das Real besteht vertauscht. Also hab ich mir versucht (auch mit der hilfe hier eine Funktion zu schreiben, die die vier Bytes in einen Real wandelt. Da ich aus der Backhoff Welt komme, verstehe ich gar nicht warum ich keinen pointer deklarieren kann. Wie soll ich das denn sonst lösen?


    Code:
    FUNCTION FC_4BYTE_TO_REAL : REAL
    VAR_INPUT
        b1  : BYTE;
        b2  : BYTE;
        b3  : BYTE;
        b4  : BYTE;
    END_VAR
    
    VAR_TEMP
        // temporäre Variablen
        pt          : POINTER TO BYTE;
        temp_real   : REAL;
    END_VAR
    
        // Anweisungsteil
        (*Wert aus 4 Byte zusammensetzen*)
        pt := ADR(temp_real);
        pt^ := b2;
        pt := (pt+1);
        pt^ := b1;
        pt := (pt+1);
        pt^ := b4;
        pt := (pt+1);
        pt^ := b3;
    
        FC_4BYTE_TO_REAL := temp_real;
    END_FUNCTION
    Fehler: Deklaration einer Aufrufinstanz oder verwendeter Parameterdatentyp in diesem Vereinbarungsblock nicht zulässig.

    WTF?

    Auch das hier https://support.industry.siemens.com...dti=0&lc=de-WW beschriebene Any Pointer Construct aus dem Bild 01 lässt sich nicht übersetzen? Ich habe Simatic Manager V5.3 SP6 Upd2. Wurde da was geändert am Compiler? Pointer nur noch im TIA oder so?

    Kann mich bitte jemand erleuchten?
    AWL ist leider nicht so meins. Wenn es nicht anders geht, nehm ich auch das, dann aber bitte nachsichtig sein.

    Vielen Dank
    Zitieren Zitieren SCL: 4 Byte TO Real - Pointer in Funktion  

  2. #2
    Registriert seit
    07.06.2006
    Ort
    Bayern
    Beiträge
    623
    Danke
    27
    Erhielt 156 Danke für 139 Beiträge

    Standard

    SCL und Pointer ist bei Step 7 Classic nicht gerade der Brüller.

    Mit AWL lässt sich dein Vorhaben eigentlich recht einfach bewerkstelligen.

    Deinen obigen SCL-Code mit "Pointer To Byte" und "^" versteht der Step 7 Compiler vermutlich auch nicht - das geht so nur mit Codesys, Beckhoff, etc.

    Pointer mit SCL geht nur mit AT-Sicht, und die geht wiederum nur im VAR_INPUT Bereich.

    Schau dir mal folgenden Thread an, da hatte jemand ein ähnliches Problem - vielleicht hilft dir das weiter: http://www.sps-forum.de/simatic/24511-pointer-scl-kein-any-2.html



  3. #3
    Registriert seit
    07.06.2006
    Ort
    Bayern
    Beiträge
    623
    Danke
    27
    Erhielt 156 Danke für 139 Beiträge

    Standard

    Hier noch ein AWL-FC, der die Bytes in einem DWord tauscht:

    Code:
    FUNCTION "SwapBytesDWord" : VOID
    TITLE =
    //Change Byteorder in DWord
    AUTHOR : xy
    VERSION : 1.0
    
    
    VAR_INPUT
      InDataDWord : DWORD ;    //Indata DWord
    END_VAR
    VAR_OUTPUT
      OutDataDWord : DWORD ;    //Outdata DWord
    END_VAR
    VAR_TEMP
      SaveAR1 : DWORD ;    
      TempInDWord : ARRAY  [0 .. 3 ] OF BYTE ;    
      TempOutDWord : DWORD ;    
    END_VAR
    BEGIN
    NETWORK
    TITLE =
    
          TAR1  #SaveAR1; //Adressregister sichern
    
          L     P##TempInDWord; //Zeiger auf lokales Datenarray
          LAR1  ; 
    
          L     #InDataDWord; //Eingangs DWord auf Array umkopieren
          T     LD [AR1,P#0.0]; 
    
          L     P##TempOutDWord; 
          LAR1  ; 
    
          L     #TempInDWord[0]; 
          T     LB [AR1,P#3.0]; 
    
          L     #TempInDWord[1]; 
          T     LB [AR1,P#2.0]; 
    
          L     #TempInDWord[2]; 
          T     LB [AR1,P#1.0]; 
    
          L     #TempInDWord[3]; 
          T     LB [AR1,P#0.0]; 
    
          L     #TempOutDWord; 
          T     #OutDataDWord; 
    
          LAR1  #SaveAR1; //Adressregister wiederherstellen
    
    
    END_FUNCTION

    Da kannst du dir bestimmt auch ein bisschen was abschauen, und auf deine Bedürfnisse anpassen.

  4. #4
    Registriert seit
    23.07.2009
    Ort
    Österreich
    Beiträge
    2.367
    Danke
    457
    Erhielt 696 Danke für 521 Beiträge

    Standard

    Step7-Classic SCL ist für einen Beckhoff-Umsteiger sicher ungewöhnlich...
    Wie uncle_tom schon schrieb gibt's "^" in der SCL-Syntax nicht, mit Pointern auf Adressen an sich arbeitet man eigentlich in der Praxis kaum.
    Hier 3 Varianten...

    Variante 1: Am häufigsten genutzt und wohl am elegantesten: AT-Sicht
    Code:
    FUNCTION FC60 : REAL
    VAR_INPUT
        BY1 : BYTE;
        BY2 : BYTE;
        BY3 : BYTE;
        BY4 : BYTE;
    END_VAR
    VAR_TEMP
        BYStruct : STRUCT
        BY1 : BYTE;
        BY2 : BYTE;
        BY3 : BYTE;
        BY4 : BYTE;
        END_STRUCT;
        REAL_AT AT BYStruct : REAL;   
    END_VAR
    
    
    BYStruct.BY1 := BY1;
    BYStruct.BY2 := BY2;
    BYStruct.BY3 := BY3;
    BYStruct.BY4 := BY4;
    
    
    FC60 := REAL_AT;
    
    
    END_FUNCTION
    Variante 2: Auch ganz nett und gar und "neumodische" indirekte Adressierung und Pointer-Zeugs...
    Code:
    FUNCTION FC61 : REAL
    VAR_INPUT
        BY1 : BYTE;
        BY2 : BYTE;
        BY3 : BYTE;
        BY4 : BYTE;
    END_VAR
    VAR_TEMP
       OutVAR : DWORD; 
    
    
    END_VAR
    
    
    OutVar := BY1;
    OutVar := SHL(IN:=OutVar, N:=8) OR BY2;
    OutVar := SHL(IN:=OutVar, N:=8) OR BY3;
    OutVar := SHL(IN:=OutVar, N:=8) OR BY4;
    
    
    FC61:= DWORD_TO_REAL(OutVar);
    
    
    END_FUNCTION
    Variante 3: Diesmal mit ANY-Pointer auf Struct und BLKMOV (schlechter Ersatz für AT)
    Code:
    FUNCTION FC62 : REAL
    VAR_INPUT
        BY1 : BYTE;
        BY2 : BYTE;
        BY3 : BYTE;
        BY4 : BYTE;
    END_VAR
    VAR_TEMP
        BYStruct : STRUCT
        BY1 : BYTE;
        BY2 : BYTE;
        BY3 : BYTE;
        BY4 : BYTE;
        END_STRUCT;  
        ANY_Ptr : ANY;
        SFC20_RetVal : INT;
        rTMp : REAL;
    END_VAR
    
    
    BYStruct.BY1 := BY1;
    BYStruct.BY2 := BY2;
    BYStruct.BY3 := BY3;
    BYStruct.BY4 := BY4;
    
    
    ANY_Ptr := BYStruct;
    SFC20_RetVal := BLKMOV(SRCBLK := ANY_PTr, DSTBLK := rTmp); 
    
    
    FC62 := rTmp;
    
    
    END_FUNCTION
    ... viele Wege führen nach Rom...
    If at first you don't succeed, you're not Van Damme!
    ... or maybe using TIA!

  5. Folgender Benutzer sagt Danke zu RONIN für den nützlichen Beitrag:

    artofautomation (03.09.2015)

  6. #5
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.285
    Danke
    932
    Erhielt 3.320 Danke für 2.682 Beiträge

    Standard

    Zitat Zitat von uncle_tom Beitrag anzeigen
    Hier noch ein AWL-FC, der die Bytes in einem DWord tauscht:

    Code:
    [...]
          TAR1  #SaveAR1; //Adressregister sichern
    
          L     P##TempInDWord; //Zeiger auf lokales Datenarray
          LAR1  ; 
    
          L     #InDataDWord; //Eingangs DWord auf Array umkopieren
          T     LD [AR1,P#0.0]; 
    
          L     P##TempOutDWord; 
          LAR1  ; 
    
          L     #TempInDWord[0]; 
          T     LB [AR1,P#3.0]; 
    
          L     #TempInDWord[1]; 
          T     LB [AR1,P#2.0]; 
    
          L     #TempInDWord[2]; 
          T     LB [AR1,P#1.0]; 
    
          L     #TempInDWord[3]; 
          T     LB [AR1,P#0.0]; 
    
          L     #TempOutDWord; 
          T     #OutDataDWord; 
    
          LAR1  #SaveAR1; //Adressregister wiederherstellen
    OK, ein Beispiel, wie man indirekte Adressierung mit AR-Register machen kann...
    Um die Byte-Reihenfolge in einem DWord umzukehren tät dasselbe auch dieser 3-Zeiler:
    Code:
          L     #InDataDWord;
          TAD;
          T     #OutDataDWord;

    Beim TE soll aber nicht die Byte-Reihenfolge im DWord umgekehrt werden, sondern die Byte-Reihenfolge in Words. Aus der Byte-Reihenfolge 1234 soll 2143 werden.

    Wenn der Swap-FC 4 einzelne Eingangsbytes verarbeiten soll, dann kann man das durchaus in SCL machen, z.B. wie in RONINs Variante 1 mit der AT-Sicht (noch anpassen zur richtigen Bytefolge).

    Wenn ich unterstelle, daß die 4 Bytes direkt aufeinanderfolgen, dann würde ich das wohl so machen:
    Code:
    FUNCTION "FC_4BYTE_TO_REAL" : REAL
    TITLE =
    VERSION : 0.1
    
    VAR_INPUT
      pt4Bytes : POINTER ; //Pointer auf 4 aufeinanderfolgende Bytes
    END_VAR
    VAR_TEMP
      DBnr : WORD ;
    END_VAR
    BEGIN
    NETWORK
    TITLE =
    
          L     P##pt4Bytes;     //Adresse des Pointers auf 4 aufeinanderfolgende Bytes
          LAR1  ; 
          L     W [AR1,P#0.0]; 
          T     #DBnr; 
          L     D [AR1,P#2.0]; 
          UD    DW#16#FFFFFFF8;  //vorsichtshalber P#x.y --> P#x.0
          LAR1  ; 
          AUF   DB [#DBnr];      //DBNO+AR1 zeigt nun auf die 4 Bytes
    
          L     D [AR1,P#0.0];   //die 4 aufeinanderfolgenden Bytes
          TAD   ;                //1234 --> 4321
          RLD   16;              //              --> 2143
          T     #RET_VAL; 
    
    END_FUNCTION
    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

  7. #6
    Registriert seit
    19.06.2015
    Beiträge
    459
    Danke
    26
    Erhielt 40 Danke für 35 Beiträge

    Standard

    Gut gemacht Variante 1.

  8. #7
    Registriert seit
    21.11.2014
    Beiträge
    228
    Danke
    7
    Erhielt 30 Danke für 28 Beiträge

    Standard

    Zitat Zitat von PN/DP Beitrag anzeigen
    OK, ein Beispiel, wie man indirekte Adressierung mit AR-Register machen kann...
    Um die Byte-Reihenfolge in einem DWord umzukehren tät dasselbe auch dieser 3-Zeiler:
    Code:
          L     #InDataDWord;
          TAD;
          T     #OutDataDWord;

    Beim TE soll aber nicht die Byte-Reihenfolge im DWord umgekehrt werden, sondern die Byte-Reihenfolge in Words. Aus der Byte-Reihenfolge 1234 soll 2143 werden.

    Wenn der Swap-FC 4 einzelne Eingangsbytes verarbeiten soll, dann kann man das durchaus in SCL machen, z.B. wie in RONINs Variante 1 mit der AT-Sicht (noch anpassen zur richtigen Bytefolge).
    [...]
    Dann nimm dich statt TAD TAW, das ist beträchtlich kürzer

  9. #8
    Registriert seit
    30.10.2009
    Ort
    10 km vom Herzen der Natur
    Beiträge
    1.628
    Danke
    120
    Erhielt 340 Danke für 255 Beiträge

    Standard

    Code:
    L #Wert
    TAD
    TAW
    TAD
    TAW
    T #Wert2
    Gruß
    Michael

  10. #9
    Registriert seit
    25.11.2009
    Beiträge
    38
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo Ronin,

    bin jetzt erst wieder von der Baustelle zurück .

    Für die Variante 1 habe ich mich entschieden. Funktioniert wunderbar, auch rückwärts nach dem selben Prinzip. Danke.

    Auf Variante 2 hätte ich auch kommen können. In der richtigen Reihenfolge nach links schieben und verodern. Eigentlich ganz einfach. War bloß zu verbort was meine Pointer angeht. Danke.

    Variante 3: hab ich auch ausprobiert, funktioniert. Anypointer auf Struktur und BLKMOVE. Danke.

    Großer Daumen nach oben.

    An alle anderen: Danke für die AWL Vorschläge. Um AWL mache ich aber nach Möglichkeit einen Bogen.

Ähnliche Themen

  1. 4 Byte in ein REAL zusammenführen
    Von JandeFun im Forum CODESYS und IEC61131
    Antworten: 9
    Letzter Beitrag: 13.12.2011, 22:02
  2. Pointer to Byte
    Von enter im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 15.09.2010, 09:33
  3. Byte werte in Real umrechen
    Von enter im Forum CODESYS und IEC61131
    Antworten: 7
    Letzter Beitrag: 25.06.2010, 09:09
  4. Byte to Real
    Von uwemiess im Forum Simatic
    Antworten: 40
    Letzter Beitrag: 09.07.2008, 14:46
  5. REAL in BYTE umwandeln
    Von Terence_Hill im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 18.01.2008, 20:03

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •