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

Ergebnis 1 bis 8 von 8

Thema: Wandeln Double/Float in S7- dword

  1. #1
    Registriert seit
    06.09.2008
    Beiträge
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo!

    Habe folgendes Problem:

    Ich muß von KBR ein Multimess über Profibus an eine S7-315-2 PN/DP
    einbinden! Ist auch weiter kein Problem nur die Ausgelesenen Daten liegen nur in Float und Double vor! Float müsste noch mit S7 real übereinstimmen indem ich die HW-Konfig bearbeite, doch was/wie mache ich mit double???

    Hier die Info's von KBR:

    float:
    Format korrespondiert mit dem IEEE 754 Standard
    Darstellung 4 Byte
    Genauigkeit 24 Bit (􀂾 repräsentieren >7 Dezimalstellen)
    Zusammensetzung 24 Bit-Mantisse; 8 Bit Exponent
    Mantisse 23 Bit (M) + 1 Bit (S)
    Das MSB der Mantisse beträgt immer 1 => wird nicht extra gespeichert!
    S = Vorzeichen der Mantisse: S = 1 􀂾 negative Zahl; S = 0 􀂾 positive Zahl
    Exponent 8 Bit (0-255); wird relativ zu 127 gespeichert, d.h. der aktuelle Wert destion der Zahl 127 vom
    abgespeicherten Wert.
    Akt. Exp. = gesp. Wert des Exp. – 127 => Zahlenbereich von 128 bis -127!
    Darstellbarer Zahlenbereich:
    1.18E-38 bis 3.40E+38
    Exponenten ergibt sich aus der Subtrak



    double:
    Format korrespondiert mit dem IEEE 754 Standard
    Darstellung 8 Byte
    Genauigkeit 52 Bit (􀂾 repräsentieren >15 Dezimalstellen)
    Zusammensetzung 52 Bit-Mantisse; 11 Bit Exponent
    Mantisse 52 Bit (M) + 1 Bit (S)
    Das MSB der Mantisse beträgt immer 1 => wird nicht extra gespeichert!
    S = Vorzeichen der Mantisse: S = 1 􀂾 negative Zahl; S = 0 􀂾 positive Zahl
    Exponent 11 Bit (0-2047);
    wird relativ zu 1023 gespeichert, d.h. der aktuelle Wert des Exponenten
    ergibt sich aus der Subtraktion der Zahl 1023 vom abgespeicherten Wert.
    Darstellbarer Zahlenbereich:
    2.23E-308 bis 1.80E+308}


    Kann mir dabei jemand helfen?
    Kann leider noch nichts testen da die Anlage erst kurz vor Inbetriebnahme kommt! und dann muß ich mit der Programmierung schon fertig sein!
    Zitieren Zitieren Wandeln Double/Float in S7- dword  

  2. #2
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.224
    Danke
    533
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard

    Ich hab das ja noch nie machen müssen.
    Zuerst sei dies hier empfohlen: http://de.wikipedia.org/wiki/IEEE_754
    Die S7 (300-er) kann ja nicht mit Double rechnen. Also würde ich versuchen, die nötigen Kennziffern

    Die Darstellung einer Gleitkommazahl

    besteht aus:
    Vorzeichen s (fast ausnahmslos 1 Bit)
    Basis b (bei normalisierten Gleitkommazahlen nach IEEE 754 ist b = 2)
    Exponent e (r Bits), nicht zu verwechseln mit dem „biased exponent“ bzw. der Charakteristik
    Mantisse m (p Bits), manchmal als Signifikant bezeichnet
    zu extrahieren, dann entsprechend zu runden und ins Float-Format umzurechnen. Wenn denn die Double in die Float von der Größe her hineinpaßt. Denke aber, hauptsächlich wegen der höheren Genaugkeit wurde die Double verwendet.
    Geändert von Ralle (05.12.2008 um 23:58 Uhr)
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  3. #3
    the.insider ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    06.09.2008
    Beiträge
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Die Theorie ist mir soweit auch klar, nur wie setzt man dies Programmierungstechnisch(AWL/FUP/KOP) um???

  4. #4
    Registriert seit
    01.11.2007
    Beiträge
    1.237
    Danke
    91
    Erhielt 407 Danke für 368 Beiträge

    Standard

    Ist das denn wirklich nötig ? Hier ging es schon mal um die Anbindung von KBR an S7, insbesondere der Beitrag #20 dürfte interessant sein (Danke an msb dafür).
    Wenn ich die GSD-Datei richtig deute, dann gibt es zu jedem double-modul ein korrespondierendes float-modul.

    Grüße von HaDi

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

    the.insider (06.12.2008)

  6. #5
    the.insider ist offline Neuer Benutzer
    Themenstarter
    Registriert seit
    06.09.2008
    Beiträge
    5
    Danke
    1
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Habt vielen Dank!

    Hab ich völlig übersehen, dass es den benötigten Wert auch noch als float gibt und das reicht mir natürlich!!!

  7. #6
    Registriert seit
    29.03.2004
    Beiträge
    5.741
    Danke
    143
    Erhielt 1.687 Danke für 1.226 Beiträge

    Standard

    Ich habe mal eine Konvertierungsfunktion für IEEE 754 64-Bit double nach 32-Bit Real geschrieben.
    Es werden allerdings nur normalisierte Werte (Normalfall) konvertiert. Kommt beim Double ein denormalisierter Wert rein wird Null ausgegeben.

    Wenn die Sonderfälle nicht beachtet werden müssten könnte man den Baustein wesentlich verkürzen.

    Hier mal der SCL-Code:
    Code:
    (* DOUBLE_TO_REAL
     * Konvertiert eine IEEE754 64-Bit Gleitpunktzahl in eine IEEE 32-Bit Gleitpunktzahl
     * Liegt der Double-Wert außerhalb des Wertebereiches der 32-Bit Zahl, so
     * wird der entsprechende Max/Min-Wert sowie ein Wert != 0 an Error ausgegeben.
     * 
     * Denormalisierte Werte werden nicht! umgerechnet, sondern es wird 0.0 ausgegeben!
     *
     * Darstellung 64-Bit IEEE754:
     * -------------------------------------------------------------------------------------------
     * S |         Exponent               |            Mantisse
     * -------------------------------------------------------------------------------------------
     * 63|62 61 60 59 58 57 56^55 54 53 52|51 50 49 48^47 46 45 44 43 42 41
     *         BYTE7          ^         BYTE6         ^
     *) 
    
    TYPE DOUBLE :
    STRUCT
        byte0 : BYTE;
        byte1 : BYTE;
        byte2 : BYTE;
        byte3 : BYTE;
        byte4 : BYTE;
        byte5 : BYTE;
        byte6 : BYTE;
        byte7 : BYTE;
    END_STRUCT
    END_TYPE
     
    FUNCTION DOUBLE_TO_REAL : REAL
    TITLE = 'DOUBLE_TO_REAL'
    
    VERSION : '0.1'
    AUTHOR  : TWI
    NAME    : DBL_REAL
    FAMILY  : CONVERT
    
    CONST 
        FLT_MAX := REAL#3.402823e+38;
        FLT_MIN := REAL#1.175495e-38;     
        S_INF := 16#1;
        S_NAN := 16#2;
        S_MAX := 16#3;
        S_MIN := 16#4;
        S_DEN := 16#5;
    END_CONST
    
    VAR_INPUT
        dbl         : DOUBLE;   // (* Byte-Array mit 64-Bit IEEE754 Zahl *)
    END_VAR
    
    VAR_OUTPUT             
        wStatus     : WORD;     // (* Statusausgabe *)
    END_VAR
    
    VAR_TEMP
        xMant_Null  : BOOL;         (* Mantisse des Double-Wertes ist Null *)
        iExponent   : INT;          (* Exponent Double *)
        bFlt_exp    : BYTE;         (* Exponent Real *)
        rFlt_val    : REAL;         (* Real-Wert *)
        dw_AT_rFlt_val AT rFlt_val: DWORD; (* Hilfssicht auf Real-Wert *) 
    END_VAR
    (******************************************************************************)
        wStatus := 16#0; 
        (* Exponent bestimmen (11 Bit) Bits 52-63; Vorzeichenbit ausmaskieren und Mantissenbits rausschieben*)
        iExponent := WORD_TO_INT(SHL(IN := BYTE_TO_WORD(dbl.byte7 AND 16#7F), N := 4) OR 
                                 SHR(IN := BYTE_TO_WORD(dbl.byte6), N := 4));
        
        (* Für Sonderfälle: Prüfen ob Mantisse Null ist *)    
        xMant_Null := ((dbl.byte6 AND 16#0F) OR dbl.byte5 OR dbl.byte4 OR dbl.byte3 OR dbl.byte2 OR dbl.byte1 OR dbl.byte0) = 0;    
        
        (* Sonderfälle abfragen *)
        IF (iExponent = 0) THEN       
            IF (xMant_Null = TRUE) THEN        (* Null *)
                DOUBLE_TO_REAL := 0.0;
                RETURN;
            ELSE                                (* denormalisierter Wert, wird hier nicht ausgewertet sondern 0 ausgegeben! *)
                wStatus := S_DEN;
                bFlt_exp := 0;
                DOUBLE_TO_REAL := 0.0;
                RETURN;
            END_IF;
        ELSIF (iExponent = 2047) THEN 
            IF (xMant_Null = TRUE) THEN         (* Infinity *)
                wStatus := S_INF;
                bFlt_exp := 16#FF;
            ELSE                                (* NaN, Not a Number *)
                wStatus := S_NAN;
                bFlt_exp := 16#FF;
            END_IF;    
        ELSE    
            iExponent := iExponent - 1023;       (* Bias des Exponenten wieder abziehen *)                                                                                                           
            IF (iExponent < -126) THEN           (* Bereich unterschritten *)
                wStatus := S_MIN;
                DOUBLE_TO_REAL := FLT_MIN;
                RETURN;
            ELSIF (iExponent > 127) THEN         (* Bereich überschritten *)
                wStatus := S_MAX;
                DOUBLE_TO_REAL := FLT_MAX;
                RETURN;       
            END_IF;
            
            (* Neuen Exponenten mit Bias bestimmen *)
            bFlt_exp := INT_TO_BYTE(iExponent + 127);
        END_IF;   
        
        (* Vorzeichenbit *)
        dw_AT_rFlt_val := SHL(IN := BYTE_TO_DWORD(dbl.byte7 AND 16#80), N := 24);
        (* Exponent 8 Bit *)
        dw_AT_rFlt_val := dw_AT_rFlt_val OR SHL(IN := BYTE_TO_DWORD(bFlt_exp), N := 23);
        (* Mantisse 23 Bit *)
        dw_AT_rFlt_val := dw_AT_rFlt_val OR SHL(IN := BYTE_TO_DWORD(dbl.byte6 AND 16#0F), N := 19)
                                         OR SHL(IN := BYTE_TO_DWORD(dbl.byte5), N := 11)
                                         OR SHL(IN := BYTE_TO_DWORD(dbl.byte4), N := 3)
                                         OR SHR(IN := BYTE_TO_DWORD(dbl.byte3), N := 5);
        
        DOUBLE_TO_REAL := rFlt_val;   
    END_FUNCTION
    Ich finde ja dass das Bitgeschubse in SCL etwas unkomfortabel ist, in AWL wäre das wesentlich einfacher.
    Oder kennt jemand eine Möglichkeit das einfacher zu schreiben? Evtl. mit einer zusätzlichen AT-Sicht?

    Mich stören vor allem die ganzen x_TO_y, aber sonst meckert der Compiler...

  8. Folgender Benutzer sagt Danke zu Thomas_v2.1 für den nützlichen Beitrag:

    uz71 (11.09.2009)

  9. #7
    Registriert seit
    14.10.2009
    Beiträge
    11
    Danke
    0
    Erhielt 0 Danke für 0 Beiträge

    Standard

    Hallo zusammen,
    ich hole den alten Thread mal wieder vor.

    Ich möchte den Baustein von Thomas_v2.1 benutzen, bekomme aber den UDT nicht vernünftig als Parameter übergeben. Es gibt immer einen Fehler.

    Meine bisherige Vorgehensweise:
    Quelle erzeugt.
    Baustein (FC100) aus Quelle erzeugt.
    UDT100 erzeugt (Symbol: "DOUBLE").
    DB100 erzeugt, in dem der UDT100 benutzt wird (Byte 0-7).

    Wie genau bekomme ich den UDT im DB jetzt als Parameter an den Baustein übergeben? Gibt es da einen Trick?

    Ich habe es so probiert: P#DB100.DBX0.0 Byte 8
    oder so: DB100.DOUBLE

    Funktioniert beides nicht.

    Vielleicht kann mir ja jemand helfen.

    Vielen Dank.

  10. #8
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.727
    Danke
    398
    Erhielt 2.404 Danke für 2.002 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo,
    wenn dein Datenbaustein einen symbolischen Namen hat dann könnte es z.B. so aussehen :
    Code:
    dbl := "mein_symbolischer_DB_Name".mein_sysmbolischer_UDT_Name
    Gruß
    Larry

Ähnliche Themen

  1. Bits wandeln 32Bit <=> Dword
    Von Shettyman im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 22.11.2010, 20:54
  2. Float in Real wandeln - SCL
    Von Gerri im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 23.07.2010, 15:29
  3. Float Wert to Dword und dann zu DINT geht das?
    Von mcmatthew im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 11.12.2009, 16:50
  4. Sentron : Double nach S7-Real wandeln
    Von Kieler im Forum Simatic
    Antworten: 9
    Letzter Beitrag: 11.09.2009, 21:51
  5. Konvertierungsproblem LREAL <--> double
    Von chefsalat im Forum Hochsprachen - OPC
    Antworten: 1
    Letzter Beitrag: 11.06.2007, 15:13

Lesezeichen

Berechtigungen

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