Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 8 von 8

Thema: Pointer auf eine globale Periepherievariable bestimmen

  1. #1
    Registriert seit
    18.12.2005
    Beiträge
    71
    Danke
    0
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo

    Ich bin auf der Suche nach einer Lösung, die mir einen Pointer auf eine globale Variable liefert. In einer Hochsprache, z.B. C, kann ich mir zur Laufzeit den Pointer auf eine Variable bestimmen lassen und kann, sofern mir die Struktur der benachbarten Elemente bekannt ist, den Pointer manipulieren und so auf diese benachbarten Elemente zugreifen. Jetzt hab ich aber nur STEP7 auf einer S7-400 zur Verfügung und da ist mir das nicht geläufig, ob das überhaupt geht, was ich mir vorstelle.

    Ich habe in der Symboltabelle verschiedene Periepherieadressen symbolisiert, wie z.B. PAW 568, PAW 572, PAW 576 usw. Dahinter verbergen sich Displays, die über Profibus DP angesteuert werden sollen. Die Struktur, die sich hinter jeder Adresse verbirgt, ist z.B. jeweils 8 Byte breit und dient zur Aufnahme des darzustellenden Wertes und einiger Steuerinformationen. Jetzt möchte ich gerne einen FB (ggf. auch einen FC - bleibt sich gleich) schreiben, der als VAR_IN einen Bausteinparameter enthält, an den ich bei dem Aufruf dieses FB's z.B. den Aktualoperanden "PAW 568" anlegen kann. Im FB benötige ich nun eine Möglichkeit, den Pointer auf "PAW 568" bestimmen zu können, damit ich diesen manipulieren kann, um auch die anderen Bytes beschreiben zu können. Die Variante, die Adresse als INT-Konstante, z.B. 568, an einen Bausteinparameter zu legen, um dann mit der indirekten Adressierung zu arbeiten, würde zwar funktionieren, ist mir aber nicht elegant genug, da ich dann auf diese Weise den Vorzug der symbolischen Adressierung aufgeben würde.

    Wäre die Anwendung des SFC 15 der richtige Weg? Das ganze soll auch noch, falls möglich, in SCL geschrieben werden, falls nicht, dann geht so was auch in AWL, ich hätte damit keine Probleme wird aber von der Seite des Kunden nicht so gerne gesehen.

    Gruß Barnee
    Zitieren Zitieren Pointer auf eine globale Periepherievariable bestimmen  

  2. #2
    Anonymous Gast

    Standard

    Hallo,

    mit Hilfe der ANY-Pointer kannst du Datenfelder
    eines beliebigen Typs adressieren. Aufbau siehe
    S7-Hilfe.

    Du brauchst dazu die Register-Adressierung über
    AR1/AR2
    Adressregister, in AWL:
    - L P##ANY_IN
    - LAR 1
    - L B [AR1,P#0.0] //Zugriff
    - ...
    - L W [AR1,P#2.0] etc.

    Vorsicht: AR2 wird in Instanzen vom System ver-
    wendet, ohne dass du die Befahle siehst (du bist
    hier schon sehr nahe am System!) Also unbedingt
    vorher die Registerinhalte retten !!!!!!!

    In SCL ist die AT-Anweisung sehr nützlich. damit
    kannst du "typisierte Pointer" erzeugen, d.h. du
    übergibt einen Zeiger auf die Startadresse und
    kannst diesen Zeiger mit einer lokalen Strukur
    überladen.

    SFC 15 ist bei Zugriffen auf Profibus-Variablen
    >8 Bit grundsätzlich angebracht, weil du sonst schon
    bei einem Wort High- und Low-Byte aus zwei
    unterschiedlichen Zyklen haben kannst.

    Was bei Siemens leider nicht funktioniert, ist
    die Definition von globalen Variablen in der
    HW-Konfig, auf die du dann im Programm zu-
    greifen kannst. Aber es ist allemal besser, sich
    einen Pointer zu bauen, dann hast du auch
    bessere Unterstützung durch die QVL.

    Gruß G.
    Zitieren Zitieren ANY-Pointer und AT-Anweisung  

  3. #3
    Registriert seit
    06.10.2003
    Beiträge
    3.411
    Danke
    451
    Erhielt 506 Danke für 408 Beiträge

    Standard

    Hallo Barnee,

    ..Die Struktur, die sich hinter jeder Adresse verbirgt, ist z.B. jeweils 8 Byte breit..
    Für diese Struktur würde ich zunächst einen UDT anlegen und diesen in einem DB für jeden dieser Busteilnehmer vereinbaren. Den UDT event. noch einmal in Ein- und Ausgänge strukturell unterteilen, um diese Teile später der SFC14/15 symbolisch übergeben zu können. Die Größe der Strukturen sollte mit den Adressbereichen der Teilnehmer (HW-Konfig) übereinstimmen.
    Den selben UDT kann man dann als Bausteinparameter deklarieren und somit symbolisch auf die jeweiligen Daten zugreifen. Die Kommunikation erfolgt dann über SFC14/SFC15.

    Eine Möglichkeit, über ANY-Pointer und indirekte Adressierung die Daten zu bearbeiten, jedoch trotzdem symbolisch darauf zu zu greifen, findest du hier. Das sieht zwar erst einmal umständlicher aus, ist aber möglicherweise reourcensparender als über Bausteinparameter-UDT.


    Gruß, Onkel
    Es gibt viel mehr Leute, die freiwillig aufgeben, als solche, die echt scheitern.
    Henry Ford

  4. #4
    Barnee ist offline Benutzer
    Themenstarter
    Registriert seit
    18.12.2005
    Beiträge
    71
    Danke
    0
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Zitat Zitat von Noch ein Gast
    Hallo,

    mit Hilfe der ANY-Pointer kannst du Datenfelder
    eines beliebigen Typs adressieren. Aufbau siehe
    S7-Hilfe.
    .....
    In SCL ist die AT-Anweisung sehr nützlich. damit
    kannst du "typisierte Pointer" erzeugen, d.h. du
    übergibt einen Zeiger auf die Startadresse und
    kannst diesen Zeiger mit einer lokalen Strukur
    überladen.
    ANY-Zeiger sind mir jetzt auch schon in den Sinn gekommen.
    Leider funktioniert die AT-Anweisung nur auf Lokalvariablen, wäre schön wenn es auch auf Eingangsvariablen anwendbar wäre, is aber nicht

    OK, ich bin grad dabei, den FC zu basteln. Ich hab jetzt eine Eingangsvariable ADR vom Typ ANY. Im FC kopiere ich diese Eingangsvariable auf eine lokale Variable ADX gleichen Typs, SCL frißt das, müßte also gehen. Mit der AT-Anweisung hab ich eine neue Sicht namens ADP als Struktur über ADX gelegt und kann so die einzelnen Komponenten des ANY-Zeigers lesen. Die unteren 4 Bytes des ANY-Zeigers werden schlußendlich 3 bits nach rechts geschoben, wo bei ich anschließend in den untersten beiden Bytes die Anfangsadresse des Peripheriebereiches erhalte den ich beschreiben will. Mit dieser Anfangsadresse kann man dann entweder über indirekte Adressierung schreiben oder ich verwende je nach Anforderung an die Konsistenz den SFC 15. Es findet natürlich eine Typprüfung statt, die Einzelheiten hab ich aber hier nicht weiter dargestellt.

    Wenn ich das getestet hab (wird aber eher Mitte nächster Woche sein) werd ich den Baustein ins Forum stellen.

    Gruß Barnee
    Zitieren Zitieren Re: ANY-Pointer und AT-Anweisung  

  5. #5
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.222
    Danke
    533
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard

    Ich würde dir in deinem Fall eher zur der Variante mit der UDT raten, da du in deinem FC/FB dann direkt mit den symbolischen Namen aus der UDT arbeiten kannst und nicht mit Zeigern (Any-Pointern) arbeiten mußt.
    Das hilft vor Allem später, wenn du nach einiger Zeit an deinem Code ändern willst, ist jedenfalls meine Erfahrung dazu.
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  6. #6
    Barnee ist offline Benutzer
    Themenstarter
    Registriert seit
    18.12.2005
    Beiträge
    71
    Danke
    0
    Erhielt 1 Danke für 1 Beitrag

    Standard

    Zitat Zitat von Onkel Dagobert
    Hallo Barnee,

    ..Die Struktur, die sich hinter jeder Adresse verbirgt, ist z.B. jeweils 8 Byte breit..
    Für diese Struktur würde ich zunächst einen UDT anlegen und diesen in einem DB für jeden dieser Busteilnehmer vereinbaren. Den UDT event. noch einmal in Ein- und Ausgänge strukturell unterteilen, um diese Teile später der SFC14/15 symbolisch übergeben zu können. Die Größe der Strukturen sollte mit den Adressbereichen der Teilnehmer (HW-Konfig) übereinstimmen.
    Den selben UDT kann man dann als Bausteinparameter deklarieren und somit symbolisch auf die jeweiligen Daten zugreifen. Die Kommunikation erfolgt dann über SFC14/SFC15.

    Gruß, Onkel
    Hallo Onkel Dagobert
    Ich glaub, ich hab einen ganz guten Ansatz für die Problemlösung gefunden - siehe mein letztes Post. Die Sache mit dem UDT wäre sicher gut, wenn es damit nicht ein Problem in CFC geben würde, da CFC die Einbettung von Strukturen in übergeordnete Strukturen (ein DB ist schon mal grundsätzlich eine Struktur) nur bis zur 2. Ebene akzeptiert. Aus diesem Grund sind auch die FB's aus dem Drive ES nur bedingt in CFC anwendbar, da sind schon ein paar Klimmzüge notwendig - alles Kappes Drive ES generiert ja eine ähnliche von dir vorgeschlagene Struktur. Da aber bei einem umfangreichen Projekt eine Vorprojektierung notwendig ist - ich mach das immer unter Excel -, damit bei der HW-Konfig auch alles mit rechten Dingen zugeht, ist bei m ir der Bedarf von Drive ES nicht mehr gegeben. Ich hab Drive ES wieder aus dem Projekt herausgeworfen. Die Ansteuerung von Micromaster 440 mach ich mit eigenen Bausteinen. Es wird nur noch die Starter-Applikation verwendet.

    Gruß Barnee

  7. #7
    Registriert seit
    06.10.2003
    Beiträge
    3.411
    Danke
    451
    Erhielt 506 Danke für 408 Beiträge

    Standard

    Hallo Barnee,

    ..Leider funktioniert die AT-Anweisung nur auf Lokalvariablen, wäre schön wenn es auch auf Eingangsvariablen anwendbar wäre, is aber nicht..
    Wenn du einen FB verwenden würdest, müsste die AT-Anweisung auch auch auf Eingangsparameter vom Typ ANY anwendbar sein.


    Gruß, Onkel
    Es gibt viel mehr Leute, die freiwillig aufgeben, als solche, die echt scheitern.
    Henry Ford

  8. #8
    Barnee ist offline Benutzer
    Themenstarter
    Registriert seit
    18.12.2005
    Beiträge
    71
    Danke
    0
    Erhielt 1 Danke für 1 Beitrag

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Code:
    FUNCTION FC201 : VOID
    
    TITLE = 'numeric display SIEBERT S102 with 4 digits'
    //
    //Comment:
    //
    VERSION : '1.0'
    AUTHOR  : HL
    NAME    : S1024
    FAMILY  : YYY
    
    //Data representation of S102 in SI16 mode
    //  Byte 0   Byte 1   Byte 2   Byte 3
    //+--------+--------+--------+--------+
    //|76543210|76543210|76543210|76543210|
    //+--------+--------+--------+--------+
    // |||||||| RESERVED   MSB      LSB
    // |||||||+---------------------------- DP0 (DP 2..0 see table 1)
    // ||||||+----------------------------- DP1
    // |||||+------------------------------ DP2
    // ||||+------------------------------- RESERVED always set to 0
    // |||+-------------------------------- RESERVED always set to 0
    // ||+--------------------------------- FL (1 Flashing, 0 normal)
    // |+---------------------------------- BL (1 Blanking, 0 normal)
    // +----------------------------------- ST (1 Segment test, 0 normal)
    //
    //
    //Table 1: Decimal dot
    //----------------------
    //  DP2  DP1  DP0  Meaning
    //+----+----+----+--------  
    //|  0 |  0 |  0 | No dp
    //|  0 |  0 |  1 | dp at 2. digit
    //|  0 |  1 |  0 | dp at 3. digit
    //|  0 |  1 |  1 | dp at 4. digit
    
    // Typical-Attribute
    {
      S7_m_c:='false';
      S7_blockview:='big'
    }
    VAR_INPUT
        ADR     : ANY;
        PV_R    : REAL := 0;
        DPoint  : INT  := 0;
        SegTest : BOOL := false;
    END_VAR
    
    VAR_OUTPUT
        Error   : BOOL;
        Ernum   : INT;
    END_VAR
    
    VAR_TEMP
        ADP     : ANY;
        ADX AT ADP : STRUCT
            ID    : BYTE;
            TYP   : BYTE;
            CNT   : INT;
            DBN   : INT;
            PTR   : DWORD;
        END_STRUCT;
        by_0    : BYTE;
        by_1    : BYTE;
        val     : INT;
        padr    : INT;
    END_VAR
    
    BEGIN
      ADP   := ADR;
    
      IF &#40;ADX.TYP <> B#16#04&#41; THEN                                 // error if not from type of word
        Error &#58;= true;
        Ernum &#58;= -7;
        RETURN;
      END_IF;
    
      IF &#40;&#40;ADX.PTR AND DW#16#FF00_0000&#41; <> DW#16#8000_0000&#41; THEN   // error if not adressing the periphery
        Error &#58;= true;
        Ernum &#58;= -6;
        RETURN;
      END_IF;
    
      padr &#58;= DWORD_TO_INT&#40;SHR &#40;IN &#58;= ADX.PTR, N &#58;= 3&#41;&#41;;           // start adress
    
      Ernum &#58;= 0;
      by_0  &#58;= 0;
      by_1  &#58;= 0;
    
      IF SegTest THEN
        by_0 &#58;= B#16#80;
        val  &#58;= 0;
      END_IF;
    
      IF &#40;PV_R < -32768&#41; THEN
        Ernum &#58;= -5;
        val   &#58;= -32768;
      ELSIF &#40;PV_R > 32767&#41; THEN
        Ernum &#58;= -4;
        val   &#58;= -32768;
      ELSIF &#40;PV_R < -999&#41; THEN
        Ernum &#58;= -3;
      ELSIF &#40;PV_R > 9999&#41; THEN
        Ernum &#58;= -2;
      ELSE
        CASE DPoint OF
          0..3&#58; by_0 &#58;= by_0 OR INT_TO_BYTE&#40;DPoint&#41;;
        ELSE
          Ernum &#58;= -1;
        END_CASE;
      END_IF;
    
      IF &#40;Ernum >= -3&#41; THEN
        val &#58;= REAL_TO_INT &#40;PV_R&#41;;
      END_IF;
      
      Error &#58;= Ernum < 0;
    
      PQB&#91;padr    &#93; &#58;= by_0;
      PQB&#91;padr + 1&#93; &#58;= by_1;
      PQW&#91;padr + 2&#93; &#58;= INT_TO_WORD&#40;val&#41;;
    
    END_FUNCTION
    Hier schon einmal meine Lösung - aber noch ungetestet. Das kommt erst nächste Woche, wenn ich im Büro die SPS aufbauen kann, zur Zeit wird unser Büro umgebaut, deshalb muß ich nach warten.

    Gruß Barnee

    PS. Die Anweisungen sind natürlich nach IEC in Englisch!!!!!

Ähnliche Themen

  1. per Pointer eine FC aufrufen?
    Von FrankTheTank im Forum Simatic
    Antworten: 8
    Letzter Beitrag: 08.08.2011, 12:50
  2. Antworten: 6
    Letzter Beitrag: 11.03.2010, 07:50
  3. Antworten: 20
    Letzter Beitrag: 25.05.2009, 08:27
  4. Zeiger/Pointer auf eine Struktur
    Von logo78 im Forum Simatic
    Antworten: 2
    Letzter Beitrag: 29.03.2009, 17:09
  5. Eine POINTER Frage
    Von Danielegger im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 30.07.2004, 16:19

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •