Step 7 SCL Aufruf des SFC22

BlueDogi

Level-1
Beiträge
48
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,

ich habe das Problem das ich den SFC22 nicht faufgerufen bekomme Fehlermeldung ist als Screenshot angehangen und den Code habe ich hier. Die Zeile in der, der Fehler auftrit habe ich Rot makiert.

Code:
FUNCTION_BLOCK FB30VAR_INPUT
    GD:INT; //Größe pro Datensatz in Bayte.
    AD:INT; //Anzahl der Datensätze
    S:BOOL; //POS. Flanke zum Schiben.
    DB_Nr:INT; //Nummer des DBs der erschtellt werden soll.
    DB_er:BOOL; //DB erstellen POS. Flanke
    DATA:ANY; //Pointer auf die Daten
        END_VAR

VAR_TEMP
    // temporäre Variablen
END_VAR
VAR
    G:WORD; //Gesamtgröße
    DB_erstellt:BOOL; //DB ist bereits erstellt.
    Schieben:BOOL; //Schieben läuft.
    ND:INT; //Nächster Datesatz. Zum Schieben.
    NZ:INT; //Nächstes Ziel beim Schieben.
    DB_LOW:WORD;
    DB_UP:WORD;
    DUMY_Nr:WORD; //Nummer Des Erstellten DBs.
    END_VAR
    IF DB_er THEN
        
        G:=INT_TO_WORD(GD*AD-1);
        DB_LOW:=INT_TO_WORD(DB_Nr);
        DB_UP:=INT_TO_WORD(DB_Nr+1);
        
        CREAT_DB(LOW_LIMIT := DB_LOW  // IN: WORD
                 ,UP_LIMIT := DB_UP // IN: WORD
                 ,COUNT := G // IN: WORD
                 ,DB_NUMBER := DUMY_Nr // OUT: WORD
                 [COLOR=#ff0000]); // INT
[/COLOR]        
        
        ;//DB Erstellen
        
    ELSE
        
    IF DB_erstellt THEN
        
        ;//Schieben!
        
    ELSE
        
        ;//ENDE!
        
    END_IF;
    END_IF;
    
    
    ;
END_FUNCTION_BLOCK

Vielen Dank für Eure Hilfe

BlueDogi
 

Anhänge

  • Unbenannt.PNG
    Unbenannt.PNG
    8,2 KB · Aufrufe: 26
Der SFC hat einen ReturnValue vom Typ Int.

Code:
MyRetVal := [COLOR=#333333]CREAT_DB(LOW_LIMIT := DB_LOW  // IN: WORD[/COLOR]
                    ,UP_LIMIT := DB_UP // IN: WORD
                    ,COUNT := G // IN: WORD
                    ,DB_NUMBER := DUMY_Nr // OUT: WORD
                    );
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde mal sagen: die SFC hat einen Rückgabewert vom Typ INT, den man auch verwenden muß.
Code:
temp_INT := CREAT_DB(LOW_LIMIT := DB_LOW  // IN: WORD
                    ,UP_LIMIT := DB_UP // IN: WORD
                    ,COUNT := G // IN: WORD
                    ,DB_NUMBER := DUMY_Nr // OUT: WORD
                    ); [COLOR="#FF0000"]// INT[/COLOR]

Harald
 
Ich habe da noch eine Frage und zwar kann wie kann ich einen ANY Pointer in SCL schreiben.
Der auf ein DB zeigt. Bekannt ist die DB_Nr. sowie die das Bytes wo begonnen werden soll und die Länge in Byte. alle werte liegen in Variabelen.
Normal wird ja so geschriebn: P#DB3.DBX0.0 BYTE2 Ich möchte jetzt das jeweils DB3; DBX0.0; und BAYTE2 variabel sind.

Ich möchte sie an einem BLOCK MOVE verwenden Rot makiert.

Code:
 FUNCTION_BLOCK FB30
VAR_INPUT
    GD:INT; //Größe pro Datensatz in Bayte.
    AD:INT; //Anzahl der Datensätze
    S:BOOL; //POS. Flanke zum Schiben.
    DB_Nr:INT; //Nummer des DBs der erschtellt werden soll.
    DB_er:BOOL; //DB erstellen POS. Flanke
    DATA:ANY; //Pointer auf die Daten
        END_VAR

VAR_TEMP
    // temporäre Variablen
END_VAR
VAR
    G:WORD; //Gesamtgröße
    DB_erstellt:BOOL; //DB ist bereits erstellt.
    Schieben:BOOL; //Schieben läuft.
    ND:INT; //Nächster Datesatz. Zum Schieben.
    NZ:INT; //Nächstes Ziel beim Schieben.
    DB_LOW:WORD;
    DB_UP:WORD;
    DUMY_Nr:WORD; //Nummer Des Erstellten DBs.
    SFC22_INT:INT;
    BLKMOV_INT:INT;
END_VAR
    IF DB_er THEN
        
        //Erstellen des Datenbausteines mit Hilfe des SFC22.
         
         G:=INT_TO_WORD(GD*AD-1);
         DB_LOW:=INT_TO_WORD(DB_Nr);
         DB_UP:=INT_TO_WORD(DB_Nr+1);
        
         SFC22_INT:=CREAT_DB(LOW_LIMIT := DB_LOW  // IN: WORD
                 ,UP_LIMIT := DB_UP // IN: WORD
                 ,COUNT := G // IN: WORD
                 ,DB_NUMBER := DUMY_Nr // OUT: WORD
                 ); // INT
        
    ELSE
        
        IF WORD_TO_INT(DUMY_Nr) > 0 THEN 
        DB_erstellt:=TRUE;
        END_IF;
    
        
    IF DB_erstellt & S THEN
        
        // Errechnen des Ersten zu schiebenden Datensatzes und des Ersten Ziels.
        ND:=WORD_TO_INT(G)-(2*GD-1);
        NZ:=WORD_TO_INT(G)-(GD-1);
    
    WHILE ND >= 0 DO
        
        [COLOR=#ff0000]BLKMOV_INT:= BLKMOV(SRCBLK :=  // IN: ANY
               ,DSTBLK :=  // OUT: ANY
             ); // INT
[/COLOR]        
        ;
    END_WHILE;

        
        
    ELSE
        
        ;//ENDE!
        
    END_IF;
    END_IF;
    
    
    ;
END_FUNCTION_BLOCK

Gibt es überhaupt eine möglichkeit dafür?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke ich hab das so weit verstanden aber warum wird für DBX0.0 in dem Pointer dw#16#84000000 angegeben. Das wird mit dem Datentyp zusammen Hängen aber kann man das auch leserlich dastellen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich meinte eher was ich da reinschreiben muss wen ich z.B. die Adresse 10.0 haben möchte.

deswegen der Link auf die Ausführungen in den FAQ.
84h ist der Speicherbereich Datenbaustein ... die restlichen drei Bytes des DW beinhalten die Adresse (siehe übersichtliche Darstellung im verlinkten Beitrag)

für 10.0 wäre das dann: DW#16#84000050

Basis 10 - drei nach Links/multipliziert mit acht - hexadezimale Darstellung: 50h
 
OK verstanden ersten drei für die Bit Adresse der rest für die Byte Adresse. So jetzt will ich aber in einer Schleife die Adresse immer wider um x erhöhen für ein Beispiel die Zahl 10. Der Wärt nach dem ersten durchlauf müsste dan DW#16#840000A0 betragen oder? aber wie muss ich rechnen. ich kann ja nicht einfach das DWORD mit 10 Addieren.
 
Wenn du 10 aufaddieren willst auf eine Adresse, dann

L 10
SLD 3
L dein_Pointer
+D

SLD 3 bewirkt, dass die 10 um die 3 Bitpositionen nach links geschoben wird, dann kannst du sie auf den Pointer aufaddieren.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
OK verstanden ersten drei für die Bit Adresse der rest für die Byte Adresse. So jetzt will ich aber in einer Schleife die Adresse immer wider um x erhöhen für ein Beispiel die Zahl 10. Der Wärt nach dem ersten durchlauf müsste dan DW#16#840000A0 betragen oder? aber wie muss ich rechnen. ich kann ja nicht einfach das DWORD mit 10 Addieren.

zuerst die Adresse ermitteln, also z.B. aus dem Schleifenzähler errechnen
diese in das passende Format bringen (also mal 8 ... Bit dazu, wenn gewünscht - zusätzliche Variable notwendig)
und das so enstandene Doppelword mit dem Datentyp-Doppelwort DW#16#84000000 ODER-Verknüpfen
fertig ist.
 
Zurück
Oben