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

Ergebnis 1 bis 3 von 3

Thema: In SCL ein CHAR-Feld zu einem String zusammen fassen!

  1. #1
    Registriert seit
    16.08.2013
    Beiträge
    9
    Danke
    3
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo SCL-Experten,

    habe hier einen SCL-Baustein definiert, an dem ich den Fehler nicht finden kann.

    Der Baustein soll eine definierte Länge von CHAR's zu einem STRING-Typ zusammen fassen. Die Ausgabe des Wertes funktioniert nicht ganz!
    Als Eingabe für den CHAR-Speicher, ist am Eingang ein ANY-Zeiger verwendet ->z.B.: P#DB2000.DBX100.0 BYTE100
    Am Ausgang wird einfach eine STRING-Variable angegeben.

    Meine Vermutung ist, das es in der FOR-Schleife liegt, bei dem Aufruf -> WORD_TO_BLOCK_DB

    Habe hier den SCL-Code aufgeführt:

    Code:
    ///////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////
    // UDT that mimics ANY pointer type. Used to construct an ANY pointer for DB access  
    TYPE "ANYPOINTER"  
    TITLE = DISSASEMBLED ANYPOINTER  
    VERSION : 1.0  
    AUTHOR  : 'FFF'  
    NAME    : 'ANYPTR'  
    FAMILY  : 'COMMON'  
        
        STRUCT  
            S7Code         : BYTE;   // Code for S7 = 0x10  
            DataType       : BYTE;   // Code for data type = 0x02 = byte 
            //DataType := 16#01; // For boolean access  
            //DataType := 16#02; // For byte access  
            //DataType := 16#03; // For char access  
            //DataType := 16#04; // For word access  
            //DataType := 16#05; // For int access  
            //DataType := 16#06; // For dword access  
            //DataType := 16#07; // For dint access  
            //DataType := 16#08; // For real access  
            Length         : INT;    // Repetition factor = Send/receive length  
            DBNumber       : INT;    // Data block Number  
            MemoryArea     : BYTE;   // Specified memory area = 0x84 = data block  
            //MemoryArea := 16#84; // For shared DB access  
            //MemoryArea := 16#85; // For instance DB access  
            ByteAddressMSB : BYTE;   // Byte address most significant bits  
            ByteAddressLSB : WORD;   // Byte address least significant bits  
        END_STRUCT;  
    END_TYPE  
    ///////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////
    // This function puts a amount of Chars to one String
    FUNCTION "CHAR_TO_STRNG" : STRING
    VERSION : '1.0'  
    AUTHOR  : FFF  
    NAME    : CHR_STRG  
    FAMILY  : COMMON  
    VAR_INPUT
        //Pointer for DB informaton
        pSrcDB : ANY;     
    END_VAR 
    VAR_TEMP
        //control variable
        i, a : INT;     
        //String variables
        Temp_String : STRING[254];
        Sym_Name_View AT Temp_String : STRUCT
            _Str_Max_Len : BYTE;
            _Str_Akt_Len : BYTE;
            _Symb_Array : ARRAY[1..254] OF BYTE;
        END_STRUCT;
        temp_pSrcDB : ANY;
        // Define source datablock access ANY pointer         
        SrcDBAny AT temp_pSrcDB : "ANYPOINTER";   // ANY pointer data structure    
        u1Addr             : DWORD;        // Union pointer for calculation of byte offset address  
        u1 AT u1Addr: STRUCT               // This is equivalent to a union in 'c'. A dword goes in and word / byte LSB / byte MSB come out  
            ByteAddrLSBPad     : BYTE;         // Not Used  
            ByteAddrMSB        : BYTE;         // Byte address most significant bits  
            WordAddr           : WORD;         // Byte address least significant bits  
        END_STRUCT;  
        //u1Addr := INT_TO_DWORD(SRCDBADR * 16); // For word / int access  
        //u1Addr := INT_TO_DWORD(SRCDBADR * 32); // For dword / dint / real access 
        DBB_No : INT;
        Temp_Word : WORD;
    END_VAR
    ///////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////
    BEGIN  
    Temp_String := '0';
    temp_pSrcDB := pSrcDB;
    //Set up DB numbers  
    Temp_Word := INT_TO_WORD(SrcDBAny.DBNumber);
    //Obtain the source DB address for ANY pointer  
    //load the beginning data block BYTE 
    u1.ByteAddrMSB := SrcDBAny.ByteAddressMSB;  
    u1.WordAddr := SrcDBAny.ByteAddressLSB ;  
    // Address of the beginning Byte of the source data block
    DBB_No := DWORD_TO_INT(SHR(IN := u1Addr, N := 3));   
    // Copy the data from ARRAY of CHAR to STRING 
    FOR i := 1 TO SrcDBAny.Length BY 1 DO 
        Sym_Name_View._Symb_Array[i] := WORD_TO_BLOCK_DB(INT_TO_WORD(SrcDBAny.DBNumber)).DB[i];  
    END_FOR;
    //FOR a := 1 TO SrcDBAny.Length BY 1 DO 
    //  ;//"DB_String".Test[a] := Sym_Name_View._Symb_Array[a]; 
    //END_FOR;
    //Write the length for the Output string
    Sym_Name_View._Str_Max_Len := INT_TO_BYTE(SrcDBAny.Length);
    Sym_Name_View._Str_Akt_Len := INT_TO_BYTE(SrcDBAny.Length);
    //Output string
    "CHAR_TO_STRNG" := Temp_String;     
    END_FUNCTION
    ///////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////////
    Hoffe, dass mir jemand weiterhelfen kann.

    Danke
    Fabries
    Zitieren Zitieren In SCL ein CHAR-Feld zu einem String zusammen fassen!  

  2. #2
    Registriert seit
    22.03.2007
    Ort
    Detmold (im Lipperland)
    Beiträge
    11.794
    Danke
    398
    Erhielt 2.417 Danke für 2.013 Beiträge

    Standard

    Hallo,
    deine DB-Nummer ergibt sich (für mich) aus SrcDBAny.DBNumber.
    Dein erstes Byte in dem DB errechnet sich aus (SrcDBAny.ByteAddressMSB * 65536 + SrcDBAny.ByteAddressLSB) / 8 - passende Casts bitte berücksichtigen.
    Die Schleife müßte dann in etwa so aussehen :
    Code:
    FOR i := 0 TO SrcDBAny.Length-1 BY 1 DO 
        Sym_Name_View._Symb_Array[i] := WORD_TO_BLOCK_DB(INT_TO_WORD(SrcDBAny.DBNumber)).DB[i+myByteOffset];  // Formel für myByteOffset siehe oben ...
    END_FOR;
    Gruß
    Larry

  3. #3
    Registriert seit
    22.06.2009
    Ort
    Sassnitz
    Beiträge
    11.314
    Danke
    932
    Erhielt 3.329 Danke für 2.688 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Muß das unbedingt mit dieser rechenaufwendigen Schleife sein?
    Man könnte SFC20 BLKMOV nutzen:
    Code:
    FUNCTION "CHAR_TO_STRNG" : STRING
    VERSION : '1.0'  
    AUTHOR  : FFF  
    NAME    : CHR_STRG  
    FAMILY  : COMMON  
    VAR_INPUT
        pSrcDB : ANY;     
    END_VAR
    VAR_TEMP
        Temp_String : STRING[254];
        Sym_Name_View AT Temp_String : STRUCT
            _Str_Max_Len : BYTE;
            _Str_Akt_Len : BYTE;
            _Symb_Array : ARRAY[1..254] OF BYTE;
        END_STRUCT;
        temp_pSrcDB : ANY;
        SrcDBAny AT temp_pSrcDB : "ANYPOINTER";   // ANY pointer data structure
        Temp_Int : INT ;
    END_VAR
    BEGIN
    
    Temp_String := '';     //Sym_Name_View._Str_Max_Len := 254 ; Sym_Name_View._Str_Akt_Len := 0 ;
    temp_pSrcDB := pSrcDB; //for access DataType and Length in the ANY
    
    IF SrcDBAny.DataType = 16#02 THEN //only if DataType = 16#02 = BYTE
      // Copy the data from ARRAY of CHAR to STRING
      Temp_Int := BLKMOV(SRCBLK := pSrcDB, DSTBLK := Sym_Name_View._Symb_Array );
    
      //Write the length for the Output string
      Sym_Name_View._Str_Max_Len := INT_TO_BYTE(SrcDBAny.Length);
      Sym_Name_View._Str_Akt_Len := Sym_Name_View._Str_Max_Len;
    END_IF;
    
    //Output string
    "CHAR_TO_STRNG" := Temp_String;     
    END_FUNCTION
    Der Code ist ungetestet.
    Vermutlich sollte man noch testen/ausschließen, daß der INPUT-ANY auf den Bereich 16#86 (L-Stack) zeigt. Und eventuell auch 16#87 Vorgänger-Lokaldaten ausschließen?

    Harald
    Es ist immer wieder überraschend, wie etwas plötzlich funktioniert, sobald man alles richtig macht.

    FAQ: Linkliste SIMATIC-Kommunikation über Ethernet

Ähnliche Themen

  1. [SCL] String in Char umwandeln
    Von emilio20 im Forum Simatic
    Antworten: 10
    Letzter Beitrag: 27.11.2012, 06:58
  2. Antworten: 9
    Letzter Beitrag: 31.08.2012, 08:55
  3. Antworten: 50
    Letzter Beitrag: 09.08.2012, 09:31
  4. String-->Char-->String umwandeln
    Von diabolo150973 im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 25.04.2012, 14:29
  5. SCL zwei INT aus einem STRING
    Von Uli_87 im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 24.02.2009, 10:33

Lesezeichen

Berechtigungen

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