Step 7 Pointer auf String ...

Boxy

Level-3
Beiträge
1.440
Reaktionspunkte
138
Zuviel Werbung?
-> Hier kostenlos registrieren
stehe ich heute auf dem Schlauch, oder sehe ich vor lauter Bäume den Wald nicht mehr.
Manches wäre mit SCL einfacher, es muss aber AWL sein :ROFLMAO:

Ich habe ein kleines Problem bzgl Strings und deren Initialisierung.
Bei einem String wird ja in den ersten beiden Bytes einmal die Max. Länge und dann die tatsächliche Zeichenzahl geschrieben.
Soweit so gut, funktioniert ja auch immer!
Bisher habe ich dies immer über die feste Adresse in z.B. dem InstanzDB eines FBs gemacht.


Code:
VAR
      PI_SERVPrgm            :PI_SERV;
      NC_Progname            :STRING  [32] := '_N_NAME_00001_SPF';   
      NC_Progpfad            :STRING  [12] := '/_N_CMA_DIR/';
      NC_Progname_max        :BYTE := 32;   
      NC_Progname_ist        :BYTE := 17;   
      
END_VAR

NETWORK
TITLE = Max. Stringlänge und Anzahl Zeichen vorbelegen

    l    NC_Progname_max;
    t    DB100.dbb96;            // max. Stringlänge in 1'tes Byte
    l    NC_Progname_ist;          // tatsächliche Länge _N_NAME_00001_SPF (17 Zeichen)
    t    DB100.dbb97;            // tatsächliche Länge in 2'tes Byte

Jetzt möchte ich aber auf die Symbolische bzw. eine etwas flexiblere Programmierung das umstellen.
Problem ist ja, sobald etwas ggf. in dem DB verschoben oder eingefügt wird, stimmen die Adressen ja nicht mehr!
Ebenfalls kann der Programmname sich ändern (kürzer oder länger) und daher muss dann der String ebenfalls modifiziert werden.

Also möchte ich eigentlich mittels Pointer auf die Adresse von NC_Progname oder NC_Progpfad zugreifen.
Kann mir da mal einer kurz helfen ob das so stimmen würde? Habe weder PLC Sim noch ne Steuerung gerade zur Hand ...


Code:
NETWORK
TITLE = Max. Stringlänge und Anzahl Zeichen vorbelegen

      L     P##NC_Progname;
      T     AR1;
      
      L     #NC_Progname_max;
      T     DIB [AR1]

      L     P##NC_Progname;
      L     P#1.0;
      +D;
      T     AR1;

      L     #NC_Progname_ist;
      T     DIB [AR1];


thx :cool:
 
Bisher habe ich dies immer über die feste Adresse in z.B. dem InstanzDB eines FBs gemacht.

Code:
NETWORK
TITLE = Max. Stringlänge und Anzahl Zeichen vorbelegen

    l    NC_Progname_max;
    t    [COLOR="#FF0000"]DB100.dbb96[/COLOR];            // max. Stringlänge in 1'tes Byte
    l    NC_Progname_ist;          // tatsächliche Länge _N_NAME_00001_SPF (17 Zeichen)
    t    [COLOR="#FF0000"]DB100.dbb97[/COLOR];            // tatsächliche Länge in 2'tes Byte
[/CODE]
Das funktioniert so nur in einem FB mit nur einer einzigen Instanz ...

Besser:
Code:
NETWORK
TITLE = Max. Stringlänge und Anzahl Zeichen vorbelegen

      TAR2;                     // Multiinstanz-Offset dieser Instanz in AKKU1 holen
      UD    DW#16#FFFFFF;       // Ausblenden der Bereichskennung (DB)
      L     P##NC_Progname;     // Variablenadresse in dieser Instanz (DI)
      +D;                       // Variablenadresse in dieser Instanz + Offset dieser Instanz
      LAR1;                     // in AR1
      
      L     #NC_Progname_max;
      T     DIB [AR1, P#0.0];   // "T D [AR1, P#0.0];" funktioniert auch, "DIB" ist aber "sicherer"

      L     #NC_Progname_ist;
      T     DIB [AR1, P#1.0];

Zugriff auf eine Multiinstanz

Achtung! Wenn der FB als "multiinstanzfähig" markiert ist dann darf AR2 nicht verändert werden bzw. muß vor jedem Zugriff auf Instanz-Variablen wiederhergestellt werden.

Harald
 
Zurück
Oben