TIA Indirekte Adressierung Array

_Ansgar

Level-1
Beiträge
12
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin,

ich habe folgendes Problem und komm nicht dahinter wie ich es im tia am elegantesten umsetze..

Ich habe einen FB der als Register dienen soll, in der Funktion wird ein Pointer berechnet. Die Funktion soll wenn die entsprechende Flanke kommt entweder Daten aus dem Array lesen oder eintragen.
Es wäre schön wenn ich das Array in der Static Schnittstelle positionieren könnte aber auch ein separater Array DB wäre OK.

Also ich habe folgendes Probiert:

1. Versuch: Separater DB
Ich habe den DB über die INOUT Schnittstelle übergeben und die Adressierung wie folgt durchgeführt:

[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif] L #"Daten Station 1"
T #"Speicher DB".THIS[#Rechnungsvariablen."Nest Station 1"]


so hat es nicht funktiioniert...
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]
L #"Daten Station 1"
T "Speicher Taktscheibe".THIS[#Rechnungsvariablen."Nest Station 1"]


die zweite Variante funktioniert, allerdings möchte ich nicht direkt auf den DB zugreifen sondern über die Schnittstelle


2. Versuch: Array in der Static Schnittstelle

[/FONT][FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif] L #"Daten Station 1"
T #Speicher.THIS[#Rechnungsvariablen."Nest Station 1"]


Der zweite Versuch hat auch nicht funktioniert...



Kann mir jemand sagen was ich falsch mache?

Beste Grüße[/FONT]


[/FONT]
 
Falsch gemacht hast Du:
- Du schreibst nur allgemein "hat nicht funktioniert", nennst aber nicht, ob, wo und welche Fehlermeldungen kommen
- Du schreibst nicht welche CPU mit welcher Firmware Du verwendest
- Du schreibst nicht welche TIA-Version Du verwendest

zu 2) Array in der Static Schnittstelle
Du musst den Name des Array angeben, das THIS hat da nichts zu suchen
Code:
VAR //Static
  Speicher : Array[0..123] OF INT;
END_VAR

L #"Daten Station 1"
T #Speicher[#Rechnungsvariablen."Nest Station 1"]

zu 1) separaten DB übergeben
Wenn Du symbolisch auf Variablen in einem übergebenen DB zugreifen willst, dann mußt Du dafür sorgen, daß der Compiler die Struktur des übergebenen DB kennt. Wenn Du indiziert zugreifen willst, dann muß der Datentyp ein Array sein. Entweder ein Array-DB eines Datentyps (weil das Array da keinen Name hat gibt es die TIA-Hilfskrücke THIS), oder in dem DB ist exlizit ein Array deklariert. In beiden Fällen muß die Struktur des DB (oder des übergebenen DB-Teils) als "PLC-Datentyp" deklariert werden, damit dieser Datentyp auch an der Übergabeschnittstelle deklariert werden kann und der Compiler dafür sorgt, daß tatsächlich nur Speicherbereiche von diesem Datentyp beim Aufruf übergeben werden können.
Wie sieht Dein PLC-Datentyp etwa aus? Und wie wolltest Du den Array-DB übergeben?
Wenn Du nur den DB-Name des Array-DB übergibst, dann geht das nur als Variant und dann kannst Du nur mit ReadFromArrayDB und WriteToArrayDB zugreifen. Oder Du deklarierst als Übergabe ein Array von der selben Größe und Datentyp wie der Array-DB, dann kannst Du auf #Parametername[#Rechnungsvariablen."Nest Station 1"] zugreifen.

Warum soll es bei Dir ein Array-DB sein, warum nimmst Du kein normal/explizit deklariertes Array in einem DB?


PS: TIA läßt zwar Leerzeichen und sonstigen Blödsinn in Variablennamen zu, das sollte man sich aber nicht angewöhnen, weil das in anderen seriösen Programmiersprachen nicht möglich ist. Und man weiß nicht, ob TIA nicht irgendwann mal zur Vernunft kommt und das abschafft und spätestens dann bekommt man Probleme beim Verwenden/Migrieren von altem Code. ;)

Harald
 
Code:
VAR //Static
  Speicher : Array[0..123] OF INT;
END_VAR

L #"Daten Station 1"
T #Speicher[#Rechnungsvariablen."Nest Station 1"]

Hallo nochmal,

funktioniert diese Art der Adressierung auch im Simatic Manger also Step7 5.6 ?

Code:
[COLOR=#222222][FONT=Verdana]#Speicher[#Rechnungsvariablen."Nest Station 1"]
[/FONT][/COLOR]

Ich habe anstatt der #Rechnungsvariabelen."Nest Station 1" in der Static Schnittstelle einfach einen Zähler als Integer deklariert. Leider ärgert der Syntax mich mal wieder.

Code:
[COLOR=#222222][FONT=Verdana][COLOR=#222222][FONT=Verdana]
[/FONT][/COLOR][/FONT][/COLOR][LEFT][COLOR=#222222][FONT=Verdana][COLOR=#222222][FONT=Verdana]VAR //Static[/FONT][/COLOR]
[COLOR=#222222][FONT=Verdana]Speicher : Array[0..500] OF REAL;
Zaehler  : INT[/FONT][/COLOR]
[COLOR=#222222][FONT=Verdana]END_VAR

[/FONT][/COLOR][/FONT][/COLOR][FONT=Verdana]   L     #Laufmeter
[/FONT][FONT=Verdana]   L     #Offset_Station_1
[/FONT][FONT=Verdana]   +R    
 [/FONT][FONT=Verdana][COLOR=#ff0000]T     #Speicher[#Zaehler] // Diese Stelle gefällt dem Syntax nicht[/COLOR]
[/FONT][/LEFT]

Vielen Dank schonmal
 
Zuletzt bearbeitet:
siehe Hilfe zu AWL > Index > Indirekte Adressierung > Speicherindirekte Adressierung
Der Index in den Speicher (des Arrays) muß ein Pointer im Doppelwortformat sein und eine Bitadresse (P#Byte.Bit) enthalten.
Code:
VAR_TEMP
  tempDwPtr : DWORD;
END_VAR

  L     #Zaehler
  SLD   5                   //entspricht "Zaehler * 8 * 4": UInt --> P# auf REAL-Array
  L     P##Speicher         //Anfangsadresse des Array in dieser Instanz
  +D
  TAR2                      //Multiinstanzoffset aus AR2 (Offset dieser Instanz)
  UD    DW#16#FFFFFF        //Bereichskennung ausblenden
  +D
  T     #tempDwPtr          //ergibt Adresse im Array im (Mutter-)IDB

  L     #Laufmeter
  L     #Offset_Station_1
  +R
  T     DID [#tempDwPtr]    // #Speicher[#Zaehler]

Harald
 
Zuletzt bearbeitet:
Hallo Harald,

erstmal wieder vielen Dank für dein Engagement und die schnelle kompetente Hilfe. Es hat zwar ne Weile gedauert aber ich glaube langsam hab ichs verstanden :)

Beste Grüße
Ansgar
 
Guten Morgen,

also ich habe jetzt folgende Adressierung in die CPU geladen:

Code:
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]//      U     #IM_Speichern_Station_1
      U     #Speichern_Station_1
      SPBN  st1[/FONT]
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]      L     #Zaehler
      SLD   5
      L     P##Speicher
      +D    
      TAR2  
      UD    DW#16#FFFFFF
      +D    
      T     #temp_pointer[/FONT]
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]      L     #Laufmeter
      L     #Offset_Station_1
      +R    
    T     DID [#temp_pointer][/FONT]
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]      L     1
      L     #Zaehler
      +I    
      T     #Zaehler[/FONT]
[FONT=Verdana,Arial,Tahoma,Calibri,Geneva,sans-serif]st1:  NOP   0
[/FONT]

Leider geht die CPU jedes mal in Stop so bald, ich #Speichern_Station_1 setze.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wird #Speichern_Station_1 auch wieder rückgesetzt oder rast #Zaehler dann unbegrenzt hoch?
Wird #Zaehler irgendwo auf die Arraygrenzen überwacht/begrenzt?
IDB aktuell und geladen?
Was steht im CPU-Diagnosepuffer warum sie in STOP geht?

Harald
 
Wäre es nicht eine klare Fall für SCL ?
Dann funktioniert denselbe code mit STEP7 Classic und STEP7 TIA, und mit S7-300/400 und S7-1500.
Und es ist nicht notwendig mit das zusammenstücken von den Pointer in Code.

Einfach:
Speicher[Zaehler] := Laufmeter + Offset_Station_1 ;
 
Hatte vergessen, das ich den Zähler nicht begrenzt habe. Funktioniert jetzt soweit, im Moment hänge ich an einer anderen Stelle:

Code:
[FONT=Verdana]      L     0
      SLD   5
      L     P##Speicher
      +D    
      TAR2  
      UD    DW#16#FFFFFF
      +D    
      T     #temp_pointer

[/FONT]
[FONT=Verdana]      L     DID [#temp_pointer]
      L     #Laufmeter
      ==R   
      =     #HM_Flanke_Makieren

[/FONT]
[FONT=Verdana]      U     #HM_Flanke_Makieren
      SPBN  pos0[/FONT]
[FONT=Verdana]      L     1
      L     #Zaehler
      -I    
      T     #Zaehler

[/FONT]
[FONT=Verdana]      L     1
      SLD   5
      L     P##Speicher
      +D    
      TAR2  
      UD    DW#16#FFFFFF
      +D    
      T     #POINTER_SRCBLK

[/FONT]
[FONT=Verdana]      L     0
      SLD   5
      L     P##Speicher
      +D    
      TAR2  
      UD    DW#16#FFFFFF
      +D    
      T     #POINTER_DSTBLK

[/FONT]
[FONT=Verdana]      CALL  "BLKMOV"
       SRCBLK :=#POINTER_SRCBLK [COLOR=#ff0000]DWORD 499  [/COLOR]    //  An dieser Stelle habe ich wieder Probleme 
       RET_VAL:=#BLKMOV_RET_VAL        // [COLOR=#222222][FONT=Verdana]Ich möchte alle Real Werte in dem Array um eine Position verschieben, 
[/FONT][/COLOR]       DSTBLK :=#POINTER_DSTBLK        // [COLOR=#222222][COLOR=#222222][FONT=Verdana][FONT=Verdana]so dass Position 0 immer mit dem nächsten Wert belegt ist.[/FONT][/FONT][/COLOR][/COLOR] 

[/FONT]
[FONT=Verdana]pos0: NOP   0

[/FONT]
[FONT=Verdana]      U     #HM_Flanke_Makieren
      FP    #FM_Makieren
      =     #IM_Makieren[/FONT]
[FONT=Verdana]      U     #IM_Makieren
      =     #Flanke_Makieren
[/FONT]
 
Zuletzt bearbeitet:
Musst Du wirklich 2000 Bytes verschieben/umspeichern, um 4 Bytes hinzuzufügen? Kann das Daten speichern nicht als Ringpuffer realisiert werden?

BLKMOV benötigt keine 32-Bit-Pointer sondern ANY (10 Byte lang). Du müsstest richtige ANY zusammenbasteln - siehe Step7-Hilfe zum Aufbau des Datentyps ANY
Code:
VAR_TEMP
  ANY_SRCBLK : ANY;
  ANY_DSTBLK : ANY;
END_VAR

//Source-ANY zusammenbasteln (#Speicher[1..499])
  LAR1  P##ANY_SRCBLK

  L     W#16#1008           //0x10 und Datentyp: REAL
  T     LW [AR1, P#0.0]     //ANY: ID und Datentyp

  L     499                 //Anzahl REALs (hat Dein Array 500 oder 501 Elemente?)
  T     LW [AR1, P#2.0]     //ANY: Wiederholfaktor

  L     DINO                //Nummer des IDB
  T     LW [AR1, P#4.0]     //ANY: DB-Nummer

  L     P#4.0               //Offset zweiter REAL im Array #Speicher[0..500] (P#4.0 entspricht: 1 SLD 5)
  L     P##Speicher         //Anfangsadresse des Array in dieser Instanz (Kennung DI)
  +D
  TAR2                      //Multiinstanzoffset aus AR2 (Offset dieser Instanz)
  UD    DW#16#FFFFFF        //Bereichskennung (DB) ausblenden
  +D
  T     LD [AR1, P#6.0]     //ANY: Bereichsadresse (P#DIX...)

//Dest-ANY zusammenbasteln (#Speicher[0..498])
...

  CALL "BLKMOV"
   SRCBLK :=#ANY_SRCBLK
   RET_VAL:=#BLKMOV_RET_VAL
   DSTBLK :=#ANY_DSTBLK

Wenn Dein Array in einem globalen DB liegen würde, dann könntest Du das Umspeichern fest programmieren:
Code:
  CALL "BLKMOV"
   SRCBLK :=P#DB1.DBX4.0 DWORD 499 //(hat Dein Array 500 oder 501 Elemente?)
   RET_VAL:=#BLKMOV_RET_VAL
   DSTBLK :=P#DB1.DBX0.0 DWORD 499

Was für eine SPS-CPU hast Du (Bestellnummer)?
Willst Du nicht mal drüber nachdenken, die Aufgabe in SCL zu lösen?


PS1:
Code:
[FONT=Verdana][COLOR="#FF0000"]      L     0
      SLD   5
      L     P##Speicher
      +D    
      TAR2  
      UD    DW#16#FFFFFF
      +D    
      T     #temp_pointer


      L     DID [#temp_pointer][/COLOR]
      L     #Laufmeter
      ==R   
      =     #HM_Flanke_Makieren[/FONT]
kannst Du auch viel einfacher schreiben:
Code:
      [COLOR="#0000FF"]L     #Speicher[0][/COLOR]
      L     #Laufmeter
      ==R
      =     #HM_Flanke_Makieren

PS2: "==R" könnte manchmal schief gehen, ">=R" oder "<=R" ist vielleicht besser?


PS3:
#POINTER_SRCBLK und #POINTER_DSTBLK sind pointer (6 byte)
#POINTER_SRCBLK und #POINTER_DSTBLK können hier höchstens 4 Byte groß sein


Harald
 
Moin,
also ich habe mich jetzt auch nochmal mit den ANY Pointern beschäfftigt und es funktioniert :)

Vielen Dank nochmal

Ich weiß nicht ob ein Ringpuffer geeignet ist, eigentlich soll es ja nur ein Schieberegister sein.

Beim nächsten Projekt werde ich mich mal mit scl beschäfftigen, ich glaub da wird manches einfacher.

Beste Grüße
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich weiß nicht ob ein Ringpuffer geeignet ist, eigentlich soll es ja nur ein Schieberegister sein.
Wenn Du umfangreiche Daten relativ nutzlos durch die Gegend meinst schieben zu müssen, dann solltest Du Dich unbedingt auch mal mit Arrays und mit einem RingPuffer beschäftigen - und nicht nur, aber natürlich auch mit SCL.

Gruss, Heinileini
 
Zurück
Oben