S7 Kopieren von Datenbereichen zw. 2 DBs in SCR CPU 318 2-DP S7 5.3 + SP2

Norbert.N

Level-1
Beiträge
11
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,
ich habe folgendes Problem:
Ich habe einen DB in dem 20 Doppelworte stehen DB200.dbd0 – db200.dbd80.
Aus diesem möchte ich dynamisch, zu bestimmten Zeitpunkten jeweils Bytes in einen Anderen DB kopieren nämlich immer DB202.dbb0.
Die Quelladresse wird jeweils neu berechnet und liegt folgendermaßen vor:

Adresse DW: Integer (0 – 80)
Adresse Byte: Integer (0 – 3)

Dazu habe ich mir hier im Forum folgenden SCR-Code zusammengeklaut (Ich habe bisher noch nie mit SCR gearbeitet) und angepasst.

FUNCTION FC205: VOID
VAR_INPUT
Kopieren: BOOL;
Quell_Doppelwort: INT;
Quell_Byte: INT;
Ziel_Byte: INT;
Quell_DB: BLOCK_DB;
Ziel_DB: Block_DB;
END_VAR
VAR_OUTPUT
Wert_Byte: BYTE;
END_VAR
VAR_TEMP
Temp: Dword;
Temp_Quell_Byte: DWORD;
Temp_Ziel_Byte: DWORD;
END_VAR
VAR
Quelle: STRUCT //ANY Struktur 1 anlegen
ANY_id: BYTE;
Source_DataType: BYTE;
Source_Lenght: WORD;
Source_DB_Nummer: WORD;
Source_Byte_Pointer: DWORD;
END_STRUCT;

Ziel: STRUCT //ANY Struktur 2 anlegen
ANY_id: BYTE;
Destin_DataType: BYTE;
Destin_Lenght: WORD;
Destin_DB_Nummer: WORD;
Destin_Byte_Pointer: DWORD;
END_STRUCT;
//Deklaration ANY Pointer für Quell-DB
pAny_source AT Quelle: ANY;
//Deklaration ANY Pointer für Ziel-DB
pAny_destin AT Ziel: ANY;
erg: INT; //Rückgabewert / Return value
END_VAR

//Vorbelegen der Quell-ANY-Pointer Variablen
Temp_Quell_Byte:= WORD_TO_DWORD(INT_TO_WORD(Quell_Byte));
Temp_Quell_Byte:= SHL(IN:=Temp_Quell_Byte,N:=3);
Quelle.ANY_id:= 16#1;
Quelle.Source_DataType:= 16#2;
Quelle.Source_Lenght:= 16#0a;
Quelle.Source_DB_Nummer:= BLOCK_DB_TO_WORD(Quell_DB);
Quelle.Source_Byte_Pointer:= Temp_Quell_Byte;

//Vorbelegen der Ziel-ANY-Pointer Variablen
Temp_Ziel_Byte:= WORD_TO_DWORD(INT_TO_WORD(Ziel_Byte));
Temp_Ziel_Byte:= SHL(IN:=Temp_Ziel_Byte,N:=3);
Ziel.ANY_id:= 16#1;
Ziel.Destin_DataType:= 16#2;
Ziel.Destin_Lenght:= 16#0a;
Ziel.Destin_DB_Nummer:= BLOCK_DB_TO_WORD(Ziel_DB);
Ziel.Destin_Byte_Pointer:= Temp_Ziel_Byte;

//Aufruf SFC20 und Parametrierung der ANY-Pointer-Variablen
IF Kopieren = True THEN
erg:= SFC20(srcblk:= pAny_source, dstblk:= pAny_destin);
End_IF;

END_FUNCTION


Aufruf des FCs zu Testzecken im OB 1mit Statischen Parametern:

U "M 0.1"
= L 20.0
BLD 103
U "M 0.1"
SPBNB _001
CALL FC 205
Kopieren :=L20.0
Quell_Doppelwort:=20
Quell_Byte :=3
Ziel_Byte :=1
Quell_DB :="Fehlerliste Isra"
Ziel_DB :="Vergleich_Fehlernummer"
Wert_Byte :=MB200
_001: NOP 0


Leider funktioniert das ganze nicht. Zu allem Überfluss bekomme ich wenn ich den Baustein beobachten möchte immer die Meldung, dass der Baustein nicht Testbar sei.
Was mache ich falsch?
Danke schon mal für eure Mühe.
Gruß,
Norbert
 
tach norbert,

ich denke du meinst scl .... aber egal, ich würde sowas immer in awl machen !

Hier ne Quelle .. ich denke das ist, wonach Du suchst ...

Aufrufen kannst Du den Baustein am besten, indem Du den Kopierbefehl auf EN legst ...

FUNCTION "Blocktransf. vorbereiten" : VOID
TITLE =Copy data set
//Kopieren von Datenbereichen
//Name: COPY
//Funktion: Mit diesem Baustein können Datenbereiche (in Datenbausteinen)
// anhand der SFC 20 "BLOCKMOV" kopiert werden. Quell-und Zielbereich
// können variabel an den Parametern angegeben werden.
// Der Baustein enthält 2 ANY-Pointer: für den Quell-und Zielbereich,die
// beim Aufruf des SFC 20"BLOCKMOV" an der Parametern angegeben werden.
//
//Q_NR : DB-Nummer des Quellbereichs
//Q_Anfang : Datenwortnummer des Anfangs des Quellebereichs
//Q_Laenge : Länge des Quellbereichs
//Z_NR : DB-Nummer des Zielbereichs
//Z_Anfang : Datenwortnummer des Anfangs des Zielbereichs
//Z_Laenge : Länge des Zielbereichs
//Zeiger_Q : Any-Pointer für Quellbereich
//Zeiger_Z : Any-Pointer für Zielbereich
NAME : COPY
VERSION : 0.0


VAR_INPUT
Q_NR : INT ; //DB-NR des Quellbereichs
Q_Anfang : INT ; //Datenwortnummer des Anfangs des Quellebereichs
Q_Laenge : INT ; //Länge des Quellbereichs
Z_NR : INT ; //DB-NR des Zielbereichs
Z_Anfang : INT ; //Datenwortnummer des Anfangs des Zielbereichs
Z_Laenge : INT ; //Länge des Zielbereichs
END_VAR
VAR_OUTPUT
ReturnVal : INT ; //Return Value
END_VAR
VAR_TEMP
Zeiger_Q : ANY ; //Any-Pointer für Quellbereich
Zeiger_Z : ANY ; //Any-Pointer für Zielbereich
END_VAR
BEGIN
NETWORK
TITLE =Source preparation
//Quellzeiger vorbereiten
L P##Zeiger_Q; //Adresse des Zeigers auf Quellbereich
LAR1 ;
L W#16#1002; //Datentypkennung : Byte
T LW [AR1,P#0.0];
L #Q_NR; //DB-NR des Quellbereichs
T LW [AR1,P#4.0];
L #Q_Anfang; //Datenwortnummer des Anfangs des Quellebereichs
SLD 3;
OD DW#16#84000000; //Bereichskennung: Datenbaustein
T LD [AR1,P#6.0];
L #Q_Laenge; //Länge des Quellbereichs
T LW [AR1,P#2.0];

NETWORK
TITLE =Tracking preparation
//Zielzeiger vorbereiten
L P##Zeiger_Z; //Adresse des Zeigers auf Zielbereich
LAR1 ;
L W#16#1002; //Datentypkennung : Byte
T LW [AR1,P#0.0];
L #Z_NR; //DB-NR des Zielbereichs
T LW [AR1,P#4.0];
L #Z_Anfang; //Datenwortnummer des Anfangs des Zielbereichs
SLD 3;
OD DW#16#84000000; //Bereichskennung: Datenbaustein
T LD [AR1,P#6.0];
L #Z_Laenge; //Länge des Zielbereichs
T LW [AR1,P#2.0];

NETWORK
TITLE =Copy Data
//Daten kopieren
CALL "BLKMOV" (
SRCBLK := #Zeiger_Q,//Any-Pointer für Quellbereich
RET_VAL := #ReturnVal,
DSTBLK := #Zeiger_Z);//Any-Pointer für Zielbereich
END_FUNCTION

Gruß stricky
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke schon mal

Whow das ging aber schnell.
Klar hab ich SCL gemeint (da sieht man wie vertraut ich damit bin :) ).
Ich werde es gleich morgen mal ausprobieren.
Danke erst mal
 
In AWL:

Code:
FUNCTION FC 112 : INT
TITLE =BLK_Move
{ S7_language := '7(1) Deutsch (Deutschland)  30.06.2005  09:16:38' }
AUTHOR : Ralle
FAMILY : SYSTEM
NAME : BLK_MOVE
VERSION : 1.1

VAR_INPUT
  AnzahlDBB : INT ; 
  QuellDB : INT ; 
  QuellDW : INT ; 
  ZielDB : INT ; 
  ZielDW : INT ; 
END_VAR
VAR_TEMP
  Quelle : ANY ; 
  Ziel : ANY ; 
END_VAR
BEGIN
NETWORK
TITLE =Blocktransfer zwischen Datenbausteinen
      LAR1  P##Quelle; //Anfangsadresse des ANY-Pointers in AR1 laden
      L     B#(16, 2); //Syntax-ID und Typ: Byte laden
      T     LW [AR1,P#0.0]; 
      L     #AnzahlDBB; //Transferlaenge
      T     LW [AR1,P#2.0]; 
      L     #QuellDB; //Quelle-DB 
      T     LW [AR1,P#4.0]; 
      L     P#DBX 0.0; //Anfangs-DW im Quell-DB
      L     #QuellDW; 
      ITD   ; 
      SLD   3; 
      +D    ; 
      T     LD [AR1,P#6.0]; 
      LAR1  P##Ziel; //Anfangsadresse des ANY-Pointers in AR1
      L     B#(16, 2); //Syntax-ID und Typ: Byte laden
      T     LW [AR1,P#0.0]; 
      L     #AnzahlDBB; //Transferlaenge
      T     LW [AR1,P#2.0]; 
      L     #ZielDB; //Ziel-DB
      T     LW [AR1,P#4.0]; 
      L     P#DBX 0.0; //Anfangs-DW im Ziel-DB
      L     #ZielDW; 
      ITD   ; 
      SLD   3; 
      +D    ; 
      T     LD [AR1,P#6.0]; 
      CALL SFC   20 (
           SRCBLK                   := #Quelle,
           RET_VAL                  := #RET_VAL,
           DSTBLK                   := #Ziel);
END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
no go

Hallo zusammen,
ich habe leider das gleiche Problem mit zwei Zeigern. Habe es mehrmals überpürft und komme eingfach nicht dahinter was falsch ist.
Wer kann mir helfen?
L P##t_Movepointer_SRCBLK
LAR1 //zeiger ins adressregister laden
L W#16#10 //SyntaxID. bei S7 immer 10
T LB [AR1,P#0.0]
L W#16#6 //Typ
T LB [AR1,P#1.0]
L #i_No_of_Records //Anzahl Bytes
L 1
-I
L 38
*I
T LW [AR1,P#2.0]
L #t_DB_Number //Quell-DB
T LW [AR1,P#4.0]
L 2 //Anfang der Quelle
SLD 3 //schiebe 3 Byte nach links
T LD [AR1,P#6.0]
L B#16#84 //Speicherbereich (hier DB)
T LB [AR1,P#6.0]
L P##t_Movepointer_DSTBLK
LAR2 //zeiger ins adressregister laden
L W#16#10 //SyntaxID. bei S7 immer 10
T LB [AR1,P#0.0]
L W#16#6 //Typ
T LB [AR1,P#1.0]
L #i_No_of_Records //Anzahl Bytes
L 1
-I
L 38
*I
T LW [AR2,P#2.0]
L #t_DB_Number //Quell-DB
T LW [AR1,P#4.0]
L 40 //Anfang der Quelle
SLD 3 //schiebe 3 Byte nach links
T LD [AR1,P#6.0]
L B#16#84 //Speicherbereich (hier DB)
T LB [AR1,P#6.0]

CALL "BLKMOV"
SRCBLK :=P#DB146.DBX2.0 BYTE 874 // #t_Movepointer_SRCBLK
RET_VAL:=#t_Ret_Val
DSTBLK :=#t_Movepointer_DSTBLK //P#DB146.DBX40.0 BYTE 874
 
Hi Ralle,
danke für die Infos.
Leider komme ich immer noch nicht ganz dahinter wieso es nur funktioniert wenn ich:

CALL "BLKMOV"
SRCBLK :=P#DB146.DBX2.0 BYTE 874 //#t_Movepointer_SRCBLK //
RET_VAL:=#t_Ret_Val
DSTBLK :=#t_Movepointer_DSTBLK //P#DB146.DBX40.0 BYTE 874

oder

CALL "BLKMOV"
SRCBLK :=#t_Movepointer_SRCBLK //P#DB146.DBX2.0 BYTE 874
RET_VAL:=#t_Ret_Val
DSTBLK :=P#DB146.DBX40.0 BYTE 874 //#t_Movepointer_DSTBLK

und nicht

CALL "BLKMOV"
SRCBLK :=#t_Movepointer_SRCBLK //P#DB146.DBX2.0 BYTE 874
RET_VAL:=#t_Ret_Val
DSTBLK :=#t_Movepointer_DSTBLK
hast du auf diese frage eine Antwort?

Gruss
Thomas
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen,
ich habe leider das gleiche Problem mit zwei Zeigern. Habe es mehrmals überpürft und komme eingfach nicht dahinter was falsch ist.
Wer kann mir helfen?
L P##t_Movepointer_SRCBLK
LAR1 //zeiger ins adressregister laden
L W#16#10 //SyntaxID. bei S7 immer 10
T LB [AR1,P#0.0]
L W#16#6 //Typ
T LB [AR1,P#1.0]
L #i_No_of_Records //Anzahl Bytes
L 1
-I
L 38
*I
T LW [AR1,P#2.0]
L #t_DB_Number //Quell-DB
T LW [AR1,P#4.0]
L 2 //Anfang der Quelle
SLD 3 //schiebe 3 Byte nach links
T LD [AR1,P#6.0]
L B#16#84 //Speicherbereich (hier DB)
T LB [AR1,P#6.0]
L P##t_Movepointer_DSTBLK
LAR2 //zeiger ins adressregister laden
L W#16#10 //SyntaxID. bei S7 immer 10
T LB [AR1,P#0.0]
L W#16#6 //Typ
T LB [AR1,P#1.0]
L #i_No_of_Records //Anzahl Bytes
L 1
-I
L 38
*I
T LW [AR2,P#2.0]
L #t_DB_Number //Quell-DB
T LW [AR1,P#4.0]
L 40 //Anfang der Quelle
SLD 3 //schiebe 3 Byte nach links
T LD [AR1,P#6.0]
L B#16#84 //Speicherbereich (hier DB)
T LB [AR1,P#6.0]

CALL "BLKMOV"
SRCBLK :=P#DB146.DBX2.0 BYTE 874 // #t_Movepointer_SRCBLK
RET_VAL:=#t_Ret_Val
DSTBLK :=#t_Movepointer_DSTBLK //P#DB146.DBX40.0 BYTE 874

Ah so, ich denke, du hast kopiert und nicht überall AR1 in AR2 geändert!
 
hey Ralle..
..habs gefunden..
zu viel byte auf der "Latte":
Typ dword...habs aber in der Anzahl byte angegeben somit a --> DB 4x zu klein.
Gruss
 
Zuletzt bearbeitet:
Zurück
Oben