Step 7 SCL Problem indirekte Adressierung Doppelwort

CNC840D

Level-2
Beiträge
161
Reaktionspunkte
10
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich hab mal wieder ein kleines Problem mit S7-SCL.
Der Baustein soll im Sekundentakt einen Zähler in einem Global-DB um eins erhöhen.
Allerdings bekomme ich immer die Fehlermeldung unzulässige Operandentypen in der Zeile 32 beim compilieren.
Krieg das irgendwie nicht hin.
Habt Ihr noch einen Tipp was ich falsch mache

Danke schonmal

FUNCTION_BLOCK "FB_Wartungszaehler"
VAR_INPUT
i_WartungsDB :BLOCK_DB; // Eingangsparameter
i_ZaehlerNr :INT;
i_ImpulsSek :BOOL;
i_VorwarnGrenze1 :INT;
i_WarnGrenze1 :INT;
i_VorwarnGrenze2 :INT;
i_WarnGrenze2 :INT;
i_VorwarnGrenze3 :INT;
i_WarnGrenze3 :INT;
END_VAR
VAR_OUTPUT
o_SammelmeldWart :BOOL;
END_VAR

VAR
FP_ImpulsSek :BOOL;
FM_ImpulsSek :BOOL;
END_VAR

// Flankenmerker Sekunde
FM_ImpulsSek:= i_ImpulsSek AND NOT FP_ImpulsSek;
FP_ImpulsSek:=i_ImpulsSek;

//Wert im Global-DB um eins erhöhen
IF FM_ImpulsSek THEN
i_WartungsDB.DD[i_ZaehlerNr*4]:=i_WartungsDB.DD[i_ZaehlerNr*4]+1; //---> in dieser Zeile bekomme ich immer wieder den Fehler angezeigt!!
END_IF;
END_FUNCTION_BLOCK
 
Rechenoperationen sind nur mit Datentypen INT, DINT oder REAL erlaubt.
Dein .DD ist jedoch vom Datentyp DWORD. Um damit rechnen zu können musst du dem Compiler sagen, das ist ein DINT, und nach dem Rechnen vor der Zuweisung wieder sagen, das Ergebnis ist ein DWORD. Also so:
Code:
i_WartungsDB.DD[i_ZaehlerNr*4] := DINT_TO_DWORD(DWORD_TO_DINT(i_WartungsDB.DD[i_ZaehlerNr*4]) + 1);

Wenn du es vernünftig machen möchtest, dann legst du in deinem Wartungs-DB ein ARRAY[0..x] of DINT an und übergibst dieses Array deiner Funktion. Das macht alles viel einfacher, leserlicher und auch konvertierbar auf TIA-Portal mit einer 1200/1500 oder andere Steuerungen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was willst du mit "DD" ausdrücken ? DBD ?
Ich weiß nicht ob der Code so funktioniert, da er einfach unnötig kompliziert ist.

Warum muss der Wartungs-DB als BLOCK-DB übergeben werden ? Kann man nicht die Sturktur als UDT übergeben ?

Außerdem denke ich das die Flankenauswertung nicht ganz richtig ist (rein symbolisch)

Code:
FP_ImpulsSek := i_ImpulsSek AND NOT FM_ImpulsSek;
FM_ImpulsSek := i_ImpulsSek;

IF #FP_ImpulsSek THEN
WartungsDB.Zaehler := WartungsDB.Zaehler+1;
END_IF;
 
Oder noch besser, diesen Zählwert als IN_OUT Parameter machen, und dann direkt mit Wert aus dem Array inkl. Index (z.B. WartungsDB.Zaehler[42]) beschalten, dann hast du auch ordentliche Querverweise.
 
Zurück
Oben