SCL-FC lässt sich nicht in SPS einspielen

Aksels

Level-2
Beiträge
257
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Leute,

ich habe einen FC in SCL geschrieben.
Dieser lässt sich auch übersetzen. Wenn ich ihn allerdings in die SPS spielen möchte bekomme ich die Fehlermeldung, daß das nicht gine, weil die Speicherbereichsgrenzen verletzt werden (sinngemäß).
Hier der code:
Code:
FUNCTION FC_Archiv_Nav : INT

// Bausteinparameter
VAR_INPUT
    // Eingangsparameter
    m_DT2 : DATE_AND_TIME;
    M_DT_Einzel AT m_DT2 : ARRAY[0..7] OF BYTE;

END_VAR

VAR_IN_OUT
    // Durchgangsparameter
END_VAR

VAR_OUTPUT
    // Ausgangsparameter

END_VAR


VAR_TEMP
    // temporäre Variablen
m_Schaltjahr : BOOL;
m_Jahr : INT;
m_Monat : INT;
m_Tag : INT;
m_TagNr: INT;
m_DT :DATE_AND_TIME;
m_str1 : STRING[10];
m_str2 : STRING[10];
m_str3 : STRING[10];

END_VAR
m_str1 := 'a';
m_str2 := 'a';
m_str3 := 'a';

    // Anweisungsteil
    M_DT:=m_DT2;
    // Anweisungsteil
    m_Schaltjahr:=false;
    m_Jahr:=BCD_TO_INT( m_DT_Einzel[0]);
    m_Monat := BCD_TO_INT( m_DT_Einzel[1]);
    m_Tag := BCD_TO_INT( m_DT_Einzel[2]);
    m_TagNr:=FC_d_aus_DT(m_DT := m_DT ); // INT
    IF m_Jahr < 90 THEN
        // Anweisungsteil_IF
        m_Jahr:=m_Jahr + 2000        ;
    ELSE
        // Anweisungsteil_ELSE
        m_Jahr:=m_Jahr + 1990;
    END_IF;

    m_Schaltjahr :=  ((m_Jahr - 1990) MOD 4)=(0);
    
    IF db210.DB_TMJ_Last = db210.DB_Tag0_Mon1_Jahr2 THEN
        ;
    ELSE
        db210.DB_TMJ_Last := db210.DB_Tag0_Mon1_Jahr2;
        CASE DB210.DB_Tag0_Mon1_Jahr2 OF
            0 : //Tag
                DB210.DB_Nr := m_TagNr;
            1 :  //Mon
                DB210.DB_Nr := m_Monat;
            2 :  //Jahr
                DB210.DB_Nr := m_Jahr - 2011;
        END_CASE;
    END_IF;
   IF DB210.DB_Nr_Minus THEN
        DB210.DB_Nr := DB210.DB_Nr - 1;
    END_IF;
    IF DB210.DB_Nr_Plus THEN
        DB210.DB_Nr := DB210.DB_Nr + 1;
    END_IF;
    
    
    IF DB210.DB_Tag0_Mon1_Jahr2 < 0 THEN
        // Anweisungsteil_IF
        DB210.DB_Tag0_Mon1_Jahr2:=0        ;
    ELSIF DB210.DB_Tag0_Mon1_Jahr2 > 2 THEN
        // Anweisungsteil_ELSIF
        DB210.DB_Tag0_Mon1_Jahr2:=2;
    ELSE
        // DB210.DB_Tag0_Mon1_Jahr2 ist OK
        ;
    END_IF;
   CASE DB210.DB_Tag0_Mon1_Jahr2 OF
        0 :
                            // Anweisungen_0..3
            IF DB210.DB_Nr < 0  THEN
                // Anweisungsteil_IF
                DB210.DB_Nr := 0;
            ELSIF DB210.DB_Nr > 365 THEN
                // Anweisungsteil_ELSIF
                DB210.DB_Nr:=365;
            ELSE
                // DB_Nr ok
                
                IF m_Schaltjahr THEN
                    // Anweisungsteil_IF
                    ;
                ELSE
                    // Anweisungsteil_ELSE
                    IF DB210.DB_Nr = 59 THEN
                        IF DB210.DB_Nr_Minus THEN
                            DB210.DB_Nr :=58;
                        END_IF;
                        IF DB210.DB_Nr_Plus THEN
                            DB210.DB_Nr :=60;
                        END_IF;
                        
                    END_IF;
                    
                    
                END_IF;

            END_IF;
            //Anzeige Setzen
            IF DB210.DB_Nr > m_TagNr THEN
                m_Jahr := m_Jahr - 1;
            END_IF;

            CASE DB210.DB_Nr OF
                0..30 :
                    // Jannuar
                    m_str1 := INT_TO_STRING(DB210.DB_Nr + 1);
                    m_str2:='. Jan ';
                    m_str3:=INT_TO_STRING(m_Jahr);
                    DB210.DB_Anz_Txt := CONCAT( IN1:=m_str1 ,IN2:= m_str2, IN3:= m_str3);
                    //DB210.DB_Anz_Txt := CONCAT( IN1:=INT_TO_STRING(DB210.DB_Nr + 1) ,IN2:= '. Jan ', IN3:= INT_TO_STRING(m_Jahr));

                31..59 :
                    // Februar

                    m_str1 := INT_TO_STRING(DB210.DB_Nr - 30);
                    m_str2:='. Feb ';
                    m_str3:=INT_TO_STRING(m_Jahr);
                    DB210.DB_Anz_Txt := CONCAT( IN1:=m_str1 ,IN2:= m_str2, IN3:= m_str3);

                    //DB210.DB_Anz_Txt := CONCAT( IN1:=INT_TO_STRING(DB210.DB_Nr - 30) ,IN2:= '. Feb ', IN3:= INT_TO_STRING(m_Jahr));



                            ELSE:
                    // Anweisungen_ELSE
                    ;
                END_CASE;


    
    ELSE:
        // Anweisungen_ELSE
        ;
    END_CASE;


    
DB210.DB_Nr_Minus:=false;
DB210.DB_Nr_Plus :=false;

    ;
    FC_Archiv_NAV := 100;
END_FUNCTION
Wenn ich nur das erste CONCAT drin habe gehts.
Wenn ich das Zweite einfüge geht es nicht mehr.

Hat mir jemand einen Tip?

Tschau,
Aksels
 
Hallo,
wenn es am Concat hängt dann ist es Stringverarbeitung und damit dann der Lokaldaten-Stack. Im Klartext : du verbrauchst zu viel Lokaldaten ...
Was hast du für eine CPU am Start ?

Gruß
Larry
 
Es kann auch daran liegen, dass die CPU Probleme mit den verschachtelten Funktionsaufrufen hat. Anstelle von

DB210.DB_Anz_Txt := CONCAT( IN1:=INT_TO_STRING(DB210.DB_Nr - 30) ,IN2:= '. Feb ', IN3:= INT_TO_STRING(m_Jahr));

vieleicht Folgendes versuchen:

Str1: String;
Str3: String;
...
Str1 := INT_TO_STRING(DB210.DB_Nr - 30;
Str3 := INT_TO_STRING(m_Jahr);

DB210.DB_Anz_Txt := CONCAT( IN1:=Str1 ,IN2:= '. Feb ', IN3:= Str3);

Gerade die Funktion mit mehreren INx vertragen nicht zu komplexe Aufrufe. Manchmal gehen auch nur zwei INx, obwohl laut Hilfe mehr möglich wäre. Also:

Str1 := CONCAT( IN1:=INT_TO_STRING(DB210.DB_Nr - 30) ,IN2:= '. Feb ');
DB210.DB_Anz_Txt := CONCAT( IN1:= Str1, IN2:= INT_TO_STRING(m_Jahr));
 
Ohne es zu erklären zu können, aber 3 Zeilen gefällt mich besser als eine lange komplizierte Zeile.
So wenn es funktioniert mit 3 Zeilen, warum nicht es so bleiben lassen ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
... anhand der anderen Beiträge verstehe ich es jetzt auch ... klar ...

du willst an Stelle von :
Code:
m_str1 := INT_TO_STRING(DB210.DB_Nr + 1);
m_str2:='. Jan ';
m_str3:=INT_TO_STRING(m_Jahr);
DB210.DB_Anz_Txt := CONCAT( IN1:=m_str1 ,IN2:= m_str2, IN3:= m_str3);
das schreiben :
Code:
 DB210.DB_Anz_Txt := CONCAT( IN1:=INT_TO_STRING(DB210.DB_Nr + 1) ,IN2:= '. Jan ', IN3:= INT_TO_STRING(m_Jahr));
da hat dann auf jeden Fall stoecklepator vollkommen Recht.
Die Step7-Wandlungsroutinen (wie hier INT_TO_STRING) arbeiten grundsätzlich nur auf einen initialisierten String. Den hast du im 2.Fall nicht.

Gruß
Larry
 
Hab es jetzt folgende Variante gewählt:

Den Vorschlag alles ineinanderzuschachteln werde ich noch testen.

Habe mir meine Cases mal angesehen und mir die drei Zwischenstrings in den Cases zusammengebaut und dann nur einen einzigen CONCAT ganz an den Schluß gesetzt. Damit ging es auf Anhieb.

Vielen dank für die Rege Teilnahme.
 
Zurück
Oben