Step 7 Aus Any Pointer DB-Nr und StartAdresse weiter nutzen

tommylik

Level-2
Beiträge
115
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

Mit diesem Code werden über ein Array-Index (int) Werte in eine DB geschrieben.

Code:
      U     e30.0

      SPBN  M001

      L     #Ist_Punkt                  // Byte
      +     -1
      L     4                           // Doppelwortzugriff
      *D    
      L     #Array_Index                // int
      +D    
      SLD   3                           // Pointerformat erstellen
      LAR1  

      AUF   #DB_Nr                      // DB Aufrufen Block_DB
      L     #ID                              // DWord
      T     DBD [AR1,P#0.0]             //Wert in den DB übertragen

M001: NOP   0


Ich möchte gerne die beiden Inputs #DB_Nr(Block_DB) und #Array_Index(int)
gegen einen Any-Pointer austauschen.


Folgenden Code-Schnipsel habe ich im I-Net gefunden, mit meinem Any-Pointer parametriert
und im Simulator ausprobiert.

So weit so gut.

Code:
      L     P##Startadr                 //Adresse des IN-Parameters (Any)
      LAR1                              // Any-Pointer laden

      L     B [AR1,P#0.0]               //Prüfen ANY:S7-ANY-Kennung muß 16#10 sein!
      L     B#16#10
      <>I   
      SPB   err                         //Fehler: Aktualoperand ist kein ANY!

      L     B [AR1,P#1.0]               //ANY:Datentyp, z.B. 16#05 für INT 
      T     #Typ                        // (TEMP, Int)
      L     W [AR1,P#2.0]               //ANY:Wiederholfaktor
      T     #Anzahl                     // (TEMP, Int)
      L     W [AR1,P#4.0]               //ANY:DB-Nummer
      T     #QuellDB                    // (TEMP, Word)
      L     D [AR1,P#6.0]               //ANY:Bereichsadresse mit Bereichskennung, muß auf .0 enden!
      T     #QuellAdr                   // (TEMP, DWord)


err:  NOP   0

Was ich jetzt nicht weiß wie ich in AWL #QuellAdr (DWord) zu meinem #Array_Index(int)
und #QuellDB (Word) zu meiner #DB_Nr(Block_DB) um wandeln kann.

Kann mir einer von Euch sagen wie ich die beiden Codeschnipsel zusammen bekomme?

Wäre Super und vielen Dank im vorraus.

Mfg Tommylik
 
Hallo,

Ok mit dem DB aufruf kann ich das doch so machen? Oder

Code:
AUF  DB [#QuellDB]               // DB Aufrufen
L     #SpotID
T     DBD [AR1,P#0.0]             //Wert in den DB übertragen

Mfg Tommylik
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit diesem Code werden über ein Array-Index (int) Werte in eine DB geschrieben.
Irgendwie passen Deine Variablennamen nicht zu dem was der Code tut.

Was soll #Ist_Punkt sein? Der Index in das DWord-Array, wohin #ID geschrieben wird?
Was soll #Array_Index sein? Die Anfangsadresse des Array im DB?

Unter Fachleuten ist Index die Elementnummer, die das Element im Array adressiert: MyArray[Index]
Und der Name des Array steht für die Anfangsadresse des Array.

Ich möchte gerne die beiden Inputs #DB_Nr(Block_DB) und #Array_Index(int)
gegen einen Any-Pointer austauschen.
Code:
      L     P##Startadr                 //Adresse des IN-Parameters (ANY)
      LAR1                              //in AR1 laden

      L     B [AR1,P#0.0]               //Prüfen ANY: S7-ANY-Kennung muß 16#10 sein!
      L     B#16#10
      <>I   
      SPB   err                         //Fehler: Aktualoperand ist kein ANY!

      L     B [AR1,P#1.0]               //ANY:Datentyp, z.B. 16#05 für INT 
      T     #Typ                        // (TEMP, Int)
      L     W [AR1,P#2.0]               //ANY:Wiederholfaktor
      T     #Anzahl                     // (TEMP, Int)
      L     W [AR1,P#4.0]               //ANY:DB-Nummer
      T     #QuellDB                    // (TEMP, Word)
      L     D [AR1,P#6.0]               //ANY:Bereichsadresse mit Bereichskennung, muß auf .0 enden!
      T     #QuellAdr                   // (TEMP, DWord)


      U     E     30.0
      SPBN  M001

      L     #Ist_Punkt                  // Schreibindex 1..x
      +     -1
      SLD   2                           // *4 weil Doppelwort-Array
      L     #QuellAdr                   // hier beginnt das Array[0..x-1]
      +D    
      LAR1  

      AUF   DB [#QuellDB]               // DB öffnen (falls der ANY auf einen DB zeigt)
      L     #ID                         // DWord
      T     D [AR1,P#0.0]               //Wert in das Array kopieren

M001: NOP   0
err:  NOP   0

Harald
 
Hallo Harald,

Vielen Dank für deine Antwort. Du hast Recht meine Beschriftung ist unlogisch.

#Ist-Punkt ist ein Byte das die Zahlen 1,2,3,4,...usw enthält.

#Array_Index war ein Int mit der Anfangsadresse im DB. Kein Array.
Ist jetzt Struct mit DW und der Name war falsch ich hatte ihn vergessen zu ändern.

ID ist ein Doppelwort mit einer 6 stelligen Zahl.
Dieses Doppelwort entnehme ich aus einem anderen DB, warum "Die" für so eine kleine Zahl
ein Doppelwort genommen haben weiß ich auch nicht.

Da du falsche Infos hattest ist die CPU mit deiner Änderung in Stop gegangen.

Ich habe es so abgeändert und es funktioniert.

Code:
FUNCTION FC3 : VOID
TITLE =ID speichern
{ S7_language := '7(1) Deutsch (Deutschland)  06.03.2020  10:00:19' }
VERSION : 0.1




VAR_INPUT
  StartAdr : ANY ;    
  Req : BOOL ;    
  Ist_Punkt : BYTE ;    
  ID : DWORD ;    
END_VAR
VAR_TEMP
  Typ : INT ;    
  Anzahl : INT ;    
  QuellDB : WORD ;    
  QuellAdr : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =


      L     P##StartAdr; //Adresse des IN-Parameters (ANY)
      LAR1  ; //in AR1 laden


      L     B [AR1,P#0.0]; //Prüfen ANY: S7-ANY-Kennung muß 16#10 sein!
      L     B#16#10; 
      <>I   ; 
      SPB   err; //Fehler: Aktualoperand ist kein ANY!


      L     B [AR1,P#1.0]; //ANY:Datentyp, z.B. 16#05 für INT 
      T     #Typ; // (TEMP, Int)
      L     W [AR1,P#2.0]; //ANY:Wiederholfaktor
      T     #Anzahl; // (TEMP, Int)
      L     W [AR1,P#4.0]; //ANY:DB-Nummer
      T     #QuellDB; // (TEMP, Word)
      L     D [AR1,P#6.0]; //ANY:Bereichsadresse mit Bereichskennung, muß auf .0 enden!
      T     #QuellAdr; // (TEMP, DWord)


      U     #Req; 
      SPBN  M001; 


      L     #Ist_Punkt; // Schreibindex 1, 2, 3,...
      +     -1; 
      L     4; // Doppelwortzugriff
      *D    ; 


      SLD   3; 
      L     #QuellAdr; 
      +D    ; 
      LAR1  ; 


      AUF   DB [#QuellDB]; // DB öffnen (falls der ANY auf einen DB zeigt)
      L     #ID; // DWord
      T     D [AR1,P#0.0]; //Wert in Doppelwort kopieren


M001: NOP   0; 
err:  NOP   0; 
NETWORK
TITLE =Bausteinende


      SET   ; //VKE auf Logisch 1
      SAVE  ; //Im BIE speichern
END_FUNCTION


Noch eine andere Frage

VAR_INPUT
StartAdr : ANY ; Wird ja z.B. mit so etwas parametriert p#DB15.DBX100.0

Die 100.0 ist ja dadurch meine Anfangsadresse wie kann ich mir nur die 100 aus dem Any entnehmen und in eine Variable abspeichern?
Damit ich damit dann weiter arbeiten könnte.

Vielen Dank nochmal für deine Hilfe.

Mfg Tommylik
 
ID ist ein Doppelwort mit einer 6 stelligen Zahl.
Dieses Doppelwort entnehme ich aus einem anderen DB, warum "Die" für so eine kleine Zahl
ein Doppelwort genommen haben weiß ich auch nicht.
:confused:
Ich WEISS es auch nicht, aber vermute, weil
INT : -32.768 .. 32.767
UINT : 0 .. 65.535
6-stellig: -999.999 .. 999.999
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Die 100.0 ist ja dadurch meine Anfangsadresse wie kann ich mir nur die 100 aus dem Any entnehmen und in eine Variable abspeichern?

Indem du deine #QuellAdr (die ja ein Pointer ist, der ja die Bitadresse anzeigt) einfach durch 8 teilst (oder dies elegant mit 'SRD 3' löst).
 
Da du falsche Infos hattest ist die CPU mit deiner Änderung in Stop gegangen.

Ich habe es so abgeändert und es funktioniert.
Ach ja, SLD 3 vergessen... :oops:
Das kannst Du übrigens auch gleich so zusammenfassen:
Code:
      L     #Ist_Punkt                  // Schreibindex 1..x
      +     -1
      [COLOR="#0000FF"]SLD   5[/COLOR]                           // *4 weil Doppelwort-Array + *8 --> P#
      L     #QuellAdr                   // hier beginnt das Array[0..x-1]
      +D
      LAR1


Die 100.0 ist ja dadurch meine Anfangsadresse wie kann ich mir nur die 100 aus dem Any entnehmen und in eine Variable abspeichern?
Code:
      L     #QuellAdr                   // Bereichsadresse mit Bereichskennung P#DBX100.0
      UD    DW#16#FFFFFF                // Bereichskennung löschen --> P#100.0
      SRD   3                           // P#100.0 --> 100
      T     #MyVariable

//oder so (ergibt etwas kürzeren Code):
      L     #QuellAdr                   // Bereichsadresse mit Bereichskennung P#DBX100.0
      SLD   8                           // Bereichskennung löschen
      SRD   11                          // P#100.0 --> 100
      T     #MyVariable

//das kannst Du auch gleich oben beim Holen des ANY machen:
      L     D [AR1,P#6.0]               //ANY:Bereichsadresse mit Bereichskennung
      T     #QuellAdr
      SLD   8                           // Bereichskennung löschen
      SRD   11                          // P#100.0 --> 100
      T     #MyVariable

Harald
 
Das mit den ANYs ist ein echtes Problem. Ich hab mir dazu 2 Bausteine erstellt.
CreateAny : Damit kann man einen ANY aus einzelnen Teilen zusammenbauen
SplitAny : Damit kann man einen ANY in Einzelbestandteile zerlegen.

Das sollte soweit helfen, dass man sieht, ob man mit seinem eigen Code richtig liegt

Für das hantieren mit ARRAYs aus Struct oder UDT hab ich auch noch einen Standarbaustein, der
ist aber in SCL. Damit kann man AUS/IN ARRAY[] OF STRUCT kopieren
Wenn das dein Problem evtl. lösen würde, dann nochmals melden

hier der Code der beiden Bausteine als AWL QUELLE
Code:
FUNCTION "m7a_CreateANY" : VOID
TITLE =CreateANY: erzeugt ANY aus Einzelbestandteilen
//Codierung Datentyp:
//00h : NIL  : Nullpointer
//01h : BOOL : Bits
//02h : BYTE 
//03h : CHAR
//04h : WORD
//05h : INT
//06h : DWORD
//07h : DINT
//08h : REAL
//09h : DATE
//0Ah : Time_OF_DAY (TOD)
//0Bh : TIME
//0Ch : S5Time
//0Dh : nicht definiert
//0Eh : DATE_AND_TIME (DT)
//13h : STRING
//
//Codierung Speicherbereich:
//80h : P : Peripherie
//81h : E : Eingänge
//82h : A : Ausgänge
//83h : M : Merker
//84h : DB: Datenbaustein
//85h : DI: Instanzdatenbaustein
//86h : L : Lokaldaten (L-Stack)
//87h : V : voriger Lokaldatenstack
//
//AUTOR: S. Maag, 
//DATUM: 10/2007
//
//AENDERUNGSVERMERKE:
//--------------------------------------------------------------------------------
//DATUM        NAME       AENDERUNG
//--------------------------------------------------------------------------------
//04.11.2011   S.Maag     Fehler Speicherbereichsverarbeitung mit UD statt OD
//                        behoben
//--------------------------------------------------------------------------------
//
//HINWEISE:
AUTHOR : 'S.Maag'
FAMILY : Maagic7
VERSION : 0.1


VAR_INPUT
  B1_DataType : BYTE ;    //1=Bool 2=Byte 3=Char 4=Word 5=INT 6=DW 7=DINT 8=Real 9=Date ...
  B23_Wiederholung : INT ;    //Wiederholungsfaktor
  B45_DB : INT ;    //DB-Nummer oder 0
  B6_Speicher : BYTE ;    //Hex 80=P 81=E 82=A 83=M 84=DB 85=DI 86=L 87=V
  ByteAdr : INT ;    //ByteAdresse
  BitAdr : INT ;    //Bitadresse 0..7
END_VAR
VAR_OUTPUT
  AnyPointer : ANY ;    
END_VAR
VAR_TEMP
  pBit : DWORD ;    
  AR1 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      L     P##AnyPointer; 
      LAR1  ; 
// Byte 0 enthält immer 10h für S7
      L     B#16#10; 
      T     B [AR1,P#0.0]; 

      L     #B1_DataType; 
      T     B [AR1,P#1.0]; // Byte 1 = Datentyp

      L     #B23_Wiederholung; 
      T     W [AR1,P#2.0]; // Byte 2&3 = Wiederholungsfaktor

      L     #B45_DB; 
      T     W [AR1,P#4.0]; // Byte 4&5 = Datenbaustein-Nr

      L     #BitAdr; 
      L     B#16#7; // Bitadresse auf 3 Bit Begrenzen 0..7
      UW    ; 
      L     #ByteAdr; // ByteAdresse um 3 nach links => Pointerformat
      SLD   3; 
      OD    ; // ByteAdress und Bitadresse verbinden
      T     D [AR1,P#6.0]; 

      L     #B6_Speicher; 
      T     B [AR1,P#6.0]; // Byte 6 = Speicherbereich

      SET   ; 
      SAVE  ; 
      CLR   ; 
END_FUNCTION

FUNCTION "m7a_SplitAny" : VOID
TITLE =SplitAny : Zerteilt ANY-Pointer in die relevanten Bestandteile
//Codierung Datentyp:
//00h : NIL  : Nullpointer
//01h : BOOL : Bits
//02h : BYTE 
//03h : CHAR
//04h : WORD
//05h : INT
//06h : DWORD
//07h : DINT
//08h : REAL
//09h : DATE
//0Ah : Time_OF_DAY (TOD)
//0Bh : TIME
//0Ch : S5Time
//0Dh : nicht definiert
//0Eh : DATE_AND_TIME (DT)
//13h : STRING
//
//Codierung Speicherbereich:
//80h : P : Peripherie
//81h : E : Eingänge
//82h : A : Ausgänge
//83h : M : Merker
//84h : DB: Datenbaustein
//85h : DI: Instanzdatenbaustein
//86h : L : Lokaldaten (L-Stack)
//87h : V : voriger Lokaldatenstack
//
//AUTOR: S.Maag
//DATUM: 10/2007
//INTERNET: www.maagic7.de
//
//AENDERUNGSVERMERKE:
//--------------------------------------------------------------------------------
//DATUM        NAME            AENDERUNG
//--------------------------------------------------------------------------------
//
//--------------------------------------------------------------------------------
//
//HINWEISE:
AUTHOR : 'S.Maag'
FAMILY : Maagic7
VERSION : 0.1


VAR_INPUT
  AnyPointer : ANY ;    
END_VAR
VAR_OUTPUT
  B1_DataType : BYTE ;    
  B23_Wiederholung : INT ;    
  B45_DB : INT ;    
  B6_Speicher : BYTE ;    
  ByteAdr : INT ;    
  BitAdr : INT ;    
END_VAR
VAR_TEMP
  AR1 : DWORD ;    
END_VAR
BEGIN
NETWORK
TITLE =

      TAR1  #AR1; // Adressregister 1 sichern

      L     P##AnyPointer; 
      LAR1  ; 
// Byte 0 enthält immer 10h für S7, daher nicht ausgeben
// L     B [AR1,P#0.0]
// T     #B0_PLC

      L     B [AR1,P#1.0]; // Byte 1 = Datentyp
      T     #B1_DataType; 

      L     W [AR1,P#2.0]; // Byte 2&3 = Wiederholungsfaktor
      T     #B23_Wiederholung; 

      L     W [AR1,P#4.0]; // Byte 4&5 = Datenbaustein-Nr
      T     #B45_DB; 

      L     B [AR1,P#6.0]; // Byte 6 = Speicherbereich
      T     #B6_Speicher; 

      L     D [AR1,P#6.0]; // Byte 7&8&9 = BitPointer
      SRD   3; // daraus ByteAdresse berechnen
      T     #ByteAdr; 

      L     B [AR1,P#9.0]; // Byte 9, Bit 0..2 = Bitadresse 
      L     B#16#7; 
      UW    ; 
      T     #BitAdr; 

      LAR1  #AR1; // ursprüngliches Adressregister 1 herstellen
      SET   ; 
      SAVE  ; 
      CLR   ; 
END_FUNCTION
 
Zurück
Oben