Pointer in SCL ?

AndreK

Level-1
Beiträge
415
Reaktionspunkte
27
Zuviel Werbung?
-> Hier kostenlos registrieren
ich möchte eigentlich nur zyklisch 20 Datenwörter umlaufend füllen...

Aber die SCL Hilfe hat mir unter "Pointer" nicht geholfen...

Jemand einen Tipp für mich, die definierte schreibweise in SCL macht mich fertig...

Werde mir auch die anderen Beiträger hier dazu morgen reinziehen...

Gedacht ist folgendes:
1. Zählpuffer = Zählpuffer + 1
2. Transferiere Wert in DW(Zählpuffer)
3. wenn der Zählpuffer =20 dann setze wieder auf 0
 
Zuletzt bearbeitet:
Mit Pointern kannst du in SCL nicht arbeiten.
Aber, falls es sich um DB's handelt, mit indizierten Zugriffen, sowohl auf den DB, als auch auf die jeweilige Variable.
Gib die Stichwöreter mal in der Suche ein, müssten ein paar Beispiel im Forum sein.
Viel Erfolg.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich würde so vorgehen :
In SCL einen FB projektieren.
Im STAT-Bereich des FB ein ARRAY [1..20] of WORD deklarieren.
Auf dieses ARRAY dann indiziert zugreifen.

Beispiel :
Code:
VAR
   myARRAY : ARRAY [1..20] of WORD ;
END_Var
 
und im Programm :
 
myARRAY[1] := 1000 ;
 
oder
 
myARRAY[i] := 2000 ;   // wobei i eine INT-Variable ist ...

Vielleicht kommst du so schon weiter.

Gruß
LL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
ich möchte eigentlich nur zyklisch 20 Datenwörter umlaufend füllen...

Hier ist noch mal ein Programmbeispiel für einen Ringpuffer mit indirekter Adressierung in S7-SCL:

Code:
FUNCTION_BLOCK FB100
 
NAME    : PUFFER
FAMILY  : SPSFORUM
AUTHOR  : KAI
VERSION : '1.0'
 
VAR_INPUT
    DB_NUMMER    : INT;
    STARTADRESSE : INT;
    LAENGE       : INT;
    WERT         : INT;
    EINLESEN     : BOOL;
END_VAR
 
VAR
    ADRESSE       : INT;
    FLANKENMERKER : BOOL;
    HILFSMERKER   : BOOL;
END_VAR
 
BEGIN
 
// Flankenauswertung positive Flanke
 
FLANKENMERKER := EINLESEN AND NOT HILFSMERKER;
HILFSMERKER   := EINLESEN;
 
// Neuen Wert in Ringpuffer einlesen
 
IF FLANKENMERKER THEN
 
    WORD_TO_BLOCK_DB(INT_TO_WORD(DB_NUMMER)).DW[ADRESSE + STARTADRESSE] := 
    INT_TO_WORD(WERT);
 
    ADRESSE := ADRESSE + 2;
 
    IF ADRESSE > ((LAENGE - 1) * 2) THEN
        ADRESSE := 0;
    END_IF;
 
END_IF;
 
END_FUNCTION_BLOCK

Gruß Kai
 

Anhänge

  • OB1.pdf
    5,8 KB · Aufrufe: 73
  • FB100.pdf
    6 KB · Aufrufe: 107
  • DB200.pdf
    4,5 KB · Aufrufe: 62
  • Ringpuff.zip
    32,5 KB · Aufrufe: 88
Siehe zu dem Thema auch die Hilfe zu S7-SCL:

Indizierter Zugriff auf Datenbausteine

Sie haben auch die Möglichkeit, auf Datenbausteine indiziertzuzugreifen. Dies hat gegenüber der absoluten Adressierung den Vorteil, dass Sie Operanden adressieren können, deren Adresse erst zur Laufzeit feststeht. Sie können also zum Beispiel die Laufvariable einer FOR-Schleife als Adresse verwenden.

Der indizierte Zugriff auf einen Datenbaustein geschieht ähnlich wie der absolute Zugriff. Er unterscheidet sich nur in der Angabe der Adresse.

Anstelle der Adresse wird ein Index spezifiziert, der eine Konstante, eine Variable oder ein arithmetischer Ausdruck sein kann.

Der indizierte Zugriff setzt sich aus der DB-Bezeichnung, dem Operandenkennzeichen (Schlüsselwort "D" und Größen-Präfix) sowie einem Basis-Ausdruck für das Indizieren zusammen.

Die Indizierung muss den folgenden Regeln entsprechen:
  • Bei einem Zugriff, der vom Datentyp BYTE, WORD oder DWORD ist, müssen Sie genau einen Index verwenden. Der Index wird als Byteadresse interpretiert. Die Zugriffsbreite wird durch das Größen-Präfix festgelegt.
  • Bei einem Zugriff, der vom Datentyp BOOL ist, müssen Sie zwei Indizes benutzen. Der erste Index spezifiziert die Byteadresse, der zweite Index die Bitposition innerhalb des Bytes.
  • Jeder Index muss dabei ein arithmetischer Ausdruck vom Datentyp INT (0 - 32767) sein
Beispiel:

STATUS_1:= DB11.DW[ZAEHLER];
STATUS_2:= DB12.DX[WNR, BITNR];
STATUS_1:= Datenbasis1.DW[ZAEHLER];
STATUS_2:= Datenbasis2.DX[WNR, BITNR];
STATUS_1:= WORD_TO_BLOCK_DB(INDEX).DW[ZAEHLER];

Gruß Kai
 
Zurück
Oben