Step 7 Daten kopieren

Canopus231171

Level-1
Beiträge
70
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo, ich benötige mal Hilfe zum kopieren von Daten.

DB 4 mit 100 Byte soll in einem DB 100 gleiche Bytelänge kopiert werden.

Der DB100 hat ein Array von 500, also fast der DB100, 500 mal die Daten von DB 4. wenn der DB 100 voll ist, soll dieser oben wieder überschrieben werden.

Aber wie
 
Hallo,

das könnte man z.B. mit einem dynamischen Anypointer und SFC20 BLKMOV lösen. Mach dich mal über den Aufbau eines Anypointers schlau, vlt. hilft dir der Link. Grundsätzlich brauchst du irgendeinen Zähler den du mit der Startadresse des Anypointers multiplizierst um auf die aktuelle Zieladresse zu kommen. Nach jedem Kopiervorgang wird der Zähler erhöht usw...

Edit: Natürlich muss der Wiederholfaktor mit dem Zähler multipliziert werden und zur Startadresse hinzuaddiert...

Any-Zeiger für Datentypen


 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,

bin noch immer bei dem Versuch die Daten zu schieben,
Wenn an dem CALL "sfcBLKMOV" ( SRCBLK := #in_Zeiger,

mein P#DB4.dbx0.0 Byte 100 direkt Parametriert wird werden die Daten Problemlos in den anderen Ziel DB übertragen.
Nun möchte ich aber auch, das der Pointer für #in_Zeiger diese Aufgabe übernimmt, nur leider funktioniert das mit dem #in_Zeiger nicht.
Ich hoffe das jemand eine Idee hat.









FUNCTION FC 5 : INT
TITLE =
//Aufbau Anypointer:
//
//it |15.. ..8 | 7.. ..0 |
//Byte 0 | 10h für S7 | Datentyp | Byte 1
//Byte 2 | Wiederholungsfaktor | Byte 3
//Byte 4 | DB-Nummer (oder 0) | Byte 5
//Byte 6 | Speicherbereich | 0 0 0 0 0 B B B | Byte 7
//Byte 8 | B B B B B B B B | B B B B B b b b | Byte 9
//================================================================================
//Datentypen in HEX:
//
//00 NIL / 01 BOOL / 02 BYTE / 03 CHAR / 04 WORD / 05 INT / 06 DWORD / 07 DINT
//
//08 REAL / 09 DATE / 0A TOD / 0B TIME / 0C S5TIME / 0E DT / 13 STRING
//
//================================================================================
//#StartKopieren:
//
//Bei positiver Flanke werden Daten vom QuellDB in den ZielDB kopiert.
//================================================================================
VERSION : 0.1




VAR_INPUT
QuellDB : INT ; //DB Nummer vom Ziel
ZielDB : INT ; //DB zum Ziel DB
StartKopieren : BOOL ; //Anstoss Daten kopieren
TypZiel : BYTE ; //00 NIL / 01 BOOL / 02 BYTE / 03 CHAR / 04 WORD / 05 INT / 06 DWORD / 07 DINT
Wiederholungsfaktor : INT ; //Wiederholungsfaktor Datenlänge
Anfang_Bereich_Ziel : INT ; //Anfang Bereich, ab welechem Datenbereich soll der Zielbereich Kopiert werden
Speicherbereich_Ziel : BYTE ; //81 Eingänge-82 Ausgänge-83 Merker-84 Datenbaustein-85-Instanz-DB-86 Lokal d-87
TypQuelle : BYTE ; //00 NIL / 01 BOOL / 02 BYTE / 03 CHAR / 04 WORD / 05 INT / 06 DWORD / 07 DINT
Anfang_Bereich_Quelle : INT ; //Anfang Bereich, ab welechem Datenbereich soll der Quellbereich Eingefügt werden
SpeicherbereichQuelle : BYTE ; //81 Eingänge-82 Ausgänge-83 Merker-84 Datenbaustein-85-Instanz-DB-86 Lokal d-87
Datenlaenge : DINT ; //Kompletter Speicherbereich des Ziel DB´s
END_VAR
VAR_TEMP
out_Zeiger : ANY ;
in_Zeiger : ANY ;
ZielDBnr : INT ;
Return : INT ;
Anzahl_Bytes : BYTE ;
quell_DB : INT ;
QuellDBAnfang : BYTE ;
QuellDBnr : INT ; //DB Nummer von der Quelle
Merkerword : DINT ;
END_VAR
BEGIN
NETWORK
TITLE =Daten zum Ziel DB
//81 Eingänge 82 Ausgänge 83 Merker
//84 Datenbaustein 85 Instanz-DB 86 Lokal daten (L-Stack)
//87 Vorherige Lokal daten




NETWORK
TITLE =


U #StartKopieren;
SPBN ende;
NETWORK
TITLE =Daten vom Quell DB


L #QuellDB;
T #QuellDBnr;
AUF DI [#QuellDBnr];


L P##in_Zeiger;
LAR2 ;
L B#16#10; //10h für s7
T LB 0;
L #TypZiel; //Typ
T LB 1;
L #Wiederholungsfaktor; //Anzahl (Wiederholungsfaktor)
T LW 2;
L #QuellDBnr; //*1 Datenbaustein (hier 0 da wir ja auf
T LW 4; // einen Merkerbereich zugreifen wollen)
L B#16#0; //Anfangsadresse
SLD 3; //Pointer bauen
T LD 6;
L #Speicherbereich_Ziel; //Speicherbereich (hier DB)
T LB 6;




NETWORK
TITLE =Daten zum Ziel DB
//81 Eingänge 82 Ausgänge 83 Merker
//84 Datenbaustein 85 Instanz-DB 86 Lokal daten (L-Stack)
//87 Vorherige Lokal daten
L #ZielDB;
T #ZielDBnr;
AUF DB [#ZielDBnr];


L P##out_Zeiger;
LAR1 ;
L B#16#10; //10h für s7
T LB 0;
L #TypZiel; //Typ
T LB 1;
L #Wiederholungsfaktor; //Anzahl (Wiederholungsfaktor)
T LW 2;
L #ZielDBnr; //*1 Datenbaustein (hier 0 da wir ja auf
T LW 4; // einen Merkerbereich zugreifen wollen)
L MW 200; //Anfangsadresse
SLD 3; //Pointer bauen
T LD 6;
L #Speicherbereich_Ziel; //Speicherbereich (hier DB)
T LB 6;






L #Anfang_Bereich_Ziel;
L #Datenlaenge;
>=I ;
SPBNB wert;
L 0;
L MW 200;
wert: NOP 0;


L #Wiederholungsfaktor;
L MW 200;
+I ;
T MW 200;


R #StartKopieren;
ende: NOP 0;


NETWORK
TITLE =


CALL "sfcBLKMOV" (
SRCBLK := #in_Zeiger,
RET_VAL := #Return,
DSTBLK := #out_Zeiger);
NETWORK
TITLE =






END_FUNCTION
 
Auf die Schnelle: Du schreibst immer in die selben TEMP-Adressen LB0...LB9, anstatt in die ANY-Variablen #out_Zeiger und #in_Zeiger. Ändere mal wie folgt:
Code:
      L     P##out_Zeiger; 
      LAR1  ; 
      L     B#16#10; //10h für s7
      T     LB     [COLOR="#FF0000"][AR1,P#0.0][/COLOR]; 
      L     #TypZiel; //Typ 
      T     LB     [COLOR="#FF0000"][AR1,P#1.0][/COLOR]; 
      L     #Wiederholungsfaktor; //Anzahl (Wiederholungsfaktor)
      T     LW     [COLOR="#FF0000"][AR1,P#2.0][/COLOR]; 
      L     #ZielDBnr; //*1 Datenbaustein (hier 0 da wir ja auf
      T     LW     [COLOR="#FF0000"][AR1,P#4.0][/COLOR]; //   einen Merkerbereich zugreifen wollen) 
      L     MW   200; //Anfangsadresse
      SLD   3; //Pointer bauen
      T     LD     [COLOR="#FF0000"][AR1,P#6.0][/COLOR]; 
      L     #Speicherbereich_Ziel; //Speicherbereich (hier DB)
      T     LB     [COLOR="#FF0000"][AR1,P#6.0][/COLOR];
- bei registerindirekten Zugriffen möglichst immer AR1 verwenden und AR2 möglichst nicht verwenden
- das "AUF DB [#ZielDBnr];" und "AUF DI [#QuellDBnr];" scheint überflüssig, weil Du ja mit BLKMOV kopierst

Falls weitere Fehler: welchen RET_VAL liefert BLKMOV?

Harald
 
Wie Harald schon gesagt hat, du baust die Anys im Temp-Bereich falsch zusammen....

Code:
      L     P##out_Zeiger; 
      LAR1  ; 
[COLOR=#000000]      L     B#16#10; //10h für s7
      T     LB     [AR1,P#0.0]; 
      L     #TypZiel; //Typ 
      T     LB     [AR1,P#1.0]; 
      L     #Wiederholungsfaktor; //Anzahl (Wiederholungsfaktor)
      T     LW     [AR1,P#2.0]; 
      L     #ZielDBnr; //*1 [/COLOR][COLOR=#ff0000]Datenbaustein (hier 0 da wir ja auf[/COLOR][COLOR=#000000]
      T     LW     [AR1,P#4.0]; //   einen Merkerbereich zugreifen wollen) 
      L     MW   200; //Anfangsadresse
      SLD   3; //Pointer bauen
      T     LD     [AR1,P#6.0]; 
      L     #Speicherbereich_Ziel; //[/COLOR][COLOR=#ff0000]Speicherbereich (hier DB)[/COLOR][COLOR=#000000]
      T     LB     [AR1,P#6.0];[/COLOR]

Und außerdem schätze ich mal wird die Funktion falsch beschalten. Willst du jetzt DBs kopieren oder Merker ?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Was der Programmcode mit dem MW200 tut bzw. tun soll kapier ich nicht - ich kann nicht sagen, ob das irgendwie richtig oder falsch ist. Auf jeden Fall nutzlos und Pfui ist das Rücksetzen des FC-Input "#StartKopieren". Und der BLKMOV wird immer aufgerufen, unabhängig vom Zustand des #StartKopieren, auch wenn die ANY-Zeiger gar nicht zusammengebastelt wurden! - dann wird im schlimmsten Fall irgendwas zufälliges im SPS-Programm überschrieben.

Harald
 
Zurück
Oben