MODBUS: MB_CPSRV

: 2014-11-24

: komatic

: SCL



, .



modbus



, Siemens, Open MODBUS/TCP.
.





.



, Siemens, Open MODBUS/TCP.



modbus


MODBUSCP - ( MODBUSCP)

( pdf, 1Mb)





:



:



Name: FB107
Symbolic Name: MB_CPSRV
Symbol Comment:
Family: COMM
Version: 2.1
Author: SIEMENS
Last modified: 06/08/2011
Use: SFB4,FC10,FC50,FC60,SFC20,SFC24
Size in work memory: 9432 bytes
Object name: fb 107nc
Signature: generiert vom SCL Übersetzer Version: SCLCOMP K05.03.05.00_01.03.00.01 release



:



{
Scl_ResetOptions ;
Scl_OverwriteBlocks:= 'y' ;
Scl_GenerateReferenceData := 'y' ;
Scl_S7ServerActive:= 'y' ;
Scl_CreateObjectCode:= 'y' ;
Scl_OptimizeObjectCode:= 'y' ;
Scl_MonitorArrayLimits:= 'n' ;
Scl_CreateDebugInfo := 'n' ;
Scl_SetOKFlag:= 'n' ;
Scl_SetMaximumStringLength:= '254'
}
FUNCTION_BLOCK FB1107
TITLE ='MB_CPSRV'
{ S7_tasklist := 'OB100' }
AUTHOR : SIEMENS
FAMILY : COMM
NAME : MB_CPSRV
VERSION : '2.1'
//reversed by komatic
 
VAR_INPUT
ID : INT ;
LADDR : WORD ;
IDB_NR : BLOCK_DB ;
MONITOR : TIME ;
ENQ_ENR : BOOL ;
SERVER_CLIENT : BOOL ;
ANLAUF : BOOL ;
DATA_AREAS : DINT ;
SEND_BUFFER : DINT ;
RECV1_BUFFER : DINT ;
RECV2_BUFFER : DINT ;
SRCBLK_Struct : STRUCT
ANY_id : WORD ;
Length : WORD ;
DB_Number : WORD ;
Byte_Pointer : DWORD ;
END_STRUCT ;
SRCBLK_Struct_any AT SRCBLK_Struct : ANY;

AG_Struct : STRUCT
ANY_id : WORD ;
Length : WORD ;
DB_Number : WORD ;
Byte_Pointer : DWORD ;
END_STRUCT ;
AG_Struct_any AT AG_Struct : ANY;
DSTBLK_Struct : STRUCT
ANY_id : WORD ;
Length : WORD ;
DB_Number : WORD ;
Byte_Pointer : DWORD ;
END_STRUCT ;
DSTBLK_Struct_any AT DSTBLK_Struct : ANY;

END_VAR
VAR_OUTPUT
UNIT : BYTE ;
DATA_TYPE : BYTE ;
START_ADDRESS : WORD ;
LENGTH : WORD ;
TI : WORD ;
WRITE_READ : BOOL ;
DONE_NDR : BOOL ;
BUSY : BOOL ;
ERROR : BOOL ;
STATUS : WORD ;
STATUS_FUNC : STRING [8 ];
END_VAR
VAR
TON : SFB4;
TEST_DB : STRUCT
RET_WERT : INT ;
LENGTH : WORD ;
WRITE_PROTECT : BOOL ;
END_STRUCT ;
State : STRUCT
Auftrag_laeuft : BOOL ;
Send : BOOL ;
Recv1 : BOOL ;
Recv2 : BOOL ;
Except : BOOL ;
Comm_Delay : BOOL ;
END_STRUCT ;
AG_CNTRL : STRUCT
DONE : BOOL ;
ERROR : BOOL ;
STATUS : WORD ;
RESULT1 : DWORD ;
RESULT2 : DWORD ;
END_STRUCT ;
AG_Send_Length : INT ;
AG_Recv1_Length : INT ;
AG_Recv2_Length : INT ;
sCoil_On_Off : BYTE ;
sEXCEPTION_CODE : BYTE ;
sFUNC_CODE : BYTE ;
sDATA_TYPE : BYTE ;
sDATEN_DB : WORD ;
sIDB_Nr : WORD ;
sDATEN_START : DINT ;
sSTART_ADDRESS : DINT ;
sNUMBER_OF_VALUES : INT ;
sLEN_RECV2 : INT ;
sByteCount_Bit : INT ;
sMONITOR : TIME ;
sCP_DELAY_TIME : TIME := T#1S;
sTI : WORD ;
sUnit : BYTE ;
sVariable_1 : BYTE ;
sVariable_2 : BYTE ;
sShift_left : BYTE ;
sShift_rigth : BYTE ;
AG_Send_Done : BOOL ;
AG_Recv1_Ndr : BOOL ;
AG_Recv2_Ndr : BOOL ;
AG_Send_wait : BOOL ;
AG_Cntrl_wait : BOOL ;
sWRITE_READ : BOOL ;
sDisconnect : BOOL ;
sHeader_Check : BOOL ;
sSenden_Neustart : BOOL ;
sEnde_mit_Fehler : BOOL ;
sFirstBit_Grenze0 : BOOL ;
sLength_groesser_8 : BOOL ;
slength_Multiple_8 : BOOL ;
sEnde_mit_Disconnect : BOOL ;
sError_FC : BOOL ;
i : INT ;
j : INT ;
sBLKMOV_RET_VAL : INT ;
sOFFSET_DATEN : DINT ;
sFirst_Bit : INT ;
sFirst_Byte : INT ;
sLast_Bit : INT ;
sLast_Byte : INT ;
sStatus_FC : WORD ;
END_VAR
BEGIN
 
IF ANLAUF
THEN
State.Auftrag_laeuft:= false;
State.Send:=false;
State.Recv1:=false;
State.Recv2:=false;
State.Comm_Delay:=false;
ANLAUF:= false;
END_IF;
 
BUSY:=false;
ERROR:=false;
DONE_NDR:=false;
STATUS:=W#16#0;
STATUS_FUNC:='';
UNIT:=B#16#0;
DATA_TYPE:=B#16#0;
START_ADDRESS:=W#16#0;
LENGTH:=W#16#0;
TI:=W#16#0;
WRITE_READ:=false;
 
IF State.Comm_Delay
THEN
TON(IN:=true,PT:=sCP_DELAY_TIME);
IF TON.Q
THEN
TON(IN:=false,PT:=sCP_DELAY_TIME);
State.Comm_Delay:=false;
END_IF;
ELSE
DSTBLK_Struct.ANY_id:=W#16#1002;
SRCBLK_Struct.ANY_id:=W#16#1002;
AG_Struct.ANY_id:=W#16#1002;
AG_Struct.DB_Number:=BLOCK_DB_TO_WORD(IDB_NR);
sIDB_Nr:=BLOCK_DB_TO_WORD(IDB_NR);
 
IF NOT State.Auftrag_laeuft
THEN
sMONITOR:=MONITOR;
IF sMONITOR<T#20MS THEN sMONITOR:=T#1S200MS; END_IF;
State.Recv1:=true;
State.Auftrag_laeuft:=true;
END_IF;

IF State.Auftrag_laeuft OR sHeader_Check
THEN
IF State.Recv1
THEN
AG_Struct.Length:=W#16#6;
AG_Struct.Byte_Pointer:=SHL (IN:=DINT_TO_DWORD(RECV1_BUFFER), N:=3) AND DW#16#FFFFFF OR DW#16#84000000;
 
AG_LRECV(ID := ID
,LADDR := LADDR
,RECV := AG_Struct_any
,NDR := AG_Recv1_Ndr
,ERROR := sError_FC
,STATUS := sStatus_FC
,LEN := AG_Recv1_Length
);
 
IF sError_FC
THEN
sEnde_mit_Fehler:=true;
STATUS:=sStatus_FC;
STATUS_FUNC:='AG_RECV';
State.Comm_Delay:=true;
ELSE
IF AG_Recv1_Ndr
THEN
IF AG_Recv1_Length<>0
THEN
State.Recv1:=false;
IF AG_Recv1_Length=6
THEN
sHeader_Check:=true;
ELSE
STATUS:=W#16#A01E;
sEnde_mit_Disconnect:=true;
END_IF;
END_IF;
END_IF;
END_IF;
END_IF;

IF sHeader_Check
THEN
sHeader_Check:=false;
sTI:=IDB_NR.DW[RECV1_BUFFER];
IF IDB_NR.DW[RECV1_BUFFER+2]<>W#16#0
THEN
STATUS:=W#16#A00F;
sEnde_mit_Disconnect:=true;
END_IF;
sLEN_RECV2:=WORD_TO_INT(IDB_NR.DW[RECV1_BUFFER+4]);

IF sLEN_RECV2<3 OR sLEN_RECV2>253
THEN
sLEN_RECV2:=0;
STATUS:=W#16#A01A;
sEnde_mit_Disconnect:=true;
END_IF;

IF STATUS<>W#16#0
THEN
sEnde_mit_Fehler:=true;
ELSE
State.Recv1:=false;
State.Recv2:=true;
State.Auftrag_laeuft:=true;
END_IF;
END_IF;

IF State.Recv2
THEN
AG_Struct.Length:=INT_TO_WORD(sLEN_RECV2);
AG_Struct.Byte_Pointer:=SHL (IN:=DINT_TO_DWORD(RECV2_BUFFER), N:=3) AND DW#16#FFFFFF OR DW#16#84000000;

AG_LRECV(ID := ID
,LADDR := LADDR
,RECV := AG_Struct_any
,NDR := AG_Recv2_Ndr
,ERROR := sError_FC
,STATUS := sStatus_FC
,LEN := AG_Recv2_Length
);
 
IF sError_FC
THEN
sEnde_mit_Fehler:=true;
STATUS:=sStatus_FC;
STATUS_FUNC:='AG_RECV';
State.Comm_Delay:=true;
State.Recv2:=false;
ELSE
IF AG_Recv2_Ndr
THEN
IF AG_Recv2_Length<>0
THEN
TON(IN:=false,PT:=sMONITOR);
State.Recv2:=false;

IF NOT ENQ_ENR
THEN
State.Auftrag_laeuft:=false;
ELSE
sUnit:=IDB_NR.DB[RECV2_BUFFER];
sFUNC_CODE:=IDB_NR.DB[RECV2_BUFFER+1];
START_ADDRESS:=IDB_NR.DW[RECV2_BUFFER+2];
sSTART_ADDRESS:=WORD_TO_DINT(START_ADDRESS);

CASE BYTE_TO_INT(sFUNC_CODE) OF
1,2,3,4 :
sWRITE_READ:=false;
sDATA_TYPE:=sFUNC_CODE;
5,15 :
sWRITE_READ:=true;
sDATA_TYPE:=B#16#1;
6,16 :
sWRITE_READ:=true;
sDATA_TYPE:=B#16#3;
ELSE:
STATUS:=W#16#A00B;
sEXCEPTION_CODE:=B#16#1;
sEnde_mit_Disconnect:=true;
END_CASE;

IF sFUNC_CODE=B#16#6 OR sFUNC_CODE=B#16#5
THEN
sNUMBER_OF_VALUES:=1;
ELSE
sNUMBER_OF_VALUES:=WORD_TO_INT(IDB_NR.DW[RECV2_BUFFER+4]);
END_IF;

sByteCount_Bit:=(sNUMBER_OF_VALUES+7)/8;

FOR i:= 1 TO 8 BY 1 DO

sDATEN_START:=WORD_TO_DINT(IDB_NR.DW[DATA_AREAS+4+(i-1)*8]);

IF IDB_NR.DB[(i-1)*8+DATA_AREAS]<>0 AND
IDB_NR.DB[DATA_AREAS+(i-1)*8]=sDATA_TYPE AND
sSTART_ADDRESS>=sDATEN_START AND
sNUMBER_OF_VALUES+sSTART_ADDRESS-1<=WORD_TO_DINT(IDB_NR.DW[DATA_AREAS+6+(i-1)*8])
THEN
sDATEN_DB:=IDB_NR.DW[DATA_AREAS+2+(i-1)*8];
EXIT;
ELSIF i=8
THEN
sEXCEPTION_CODE:=B#16#2;
END_IF;
END_FOR;

IF sDATEN_DB=BLOCK_DB_TO_WORD(IDB_NR)
THEN
STATUS:=W#16#A07E;
sEXCEPTION_CODE:=B#16#2;
END_IF;
 
IF sEXCEPTION_CODE=B#16#0
THEN
sOFFSET_DATEN:=(sSTART_ADDRESS-sDATEN_START)*2;

TEST_DB.RET_WERT:=TEST_DB(
DB_NUMBER := sDATEN_DB
,DB_LENGTH := TEST_DB.LENGTH
,WRITE_PROT := TEST_DB.WRITE_PROTECT
);

IF TEST_DB.RET_WERT<>0 AND STATUS=W#16#0
THEN
STATUS:=INT_TO_WORD(TEST_DB.RET_WERT);
STATUS_FUNC:='TEST_DB';
sEXCEPTION_CODE:=B#16#2;
ELSE
IF sDATA_TYPE=B#16#3 OR sDATA_TYPE=B#16#4
THEN
IF sNUMBER_OF_VALUES*2+sOFFSET_DATEN-1>WORD_TO_DINT(TEST_DB.LENGTH)
THEN
STATUS:=W#16#A003;
sEXCEPTION_CODE:=B#16#2;
END_IF;
ELSIF (sOFFSET_DATEN/2+sNUMBER_OF_VALUES+7)/8>WORD_TO_DINT(TEST_DB.LENGTH)
THEN
STATUS:=W#16#A003;
sEXCEPTION_CODE:=B#16#2;
END_IF;

IF sWRITE_READ
THEN
IF sDATA_TYPE=B#16#3
THEN
IF sNUMBER_OF_VALUES<=0 OR sNUMBER_OF_VALUES>123
THEN
STATUS:=W#16#A005;
sEXCEPTION_CODE:=B#16#3;
ELSIF sFUNC_CODE=B#16#10 AND
sNUMBER_OF_VALUES*2 <> BYTE_TO_INT(IDB_NR.DB[RECV2_BUFFER+6])
THEN
STATUS:=W#16#A00C;
sEnde_mit_Disconnect:=true;
sEXCEPTION_CODE:=B#16#3;
ELSIF sFUNC_CODE=B#16#10 AND (sNUMBER_OF_VALUES*2+7 <> sLEN_RECV2) OR
(sFUNC_CODE=B#16#6 AND sLEN_RECV2 <> 6)
THEN
STATUS:=W#16#A00E;
sEnde_mit_Disconnect:=true;
END_IF;

IF sFUNC_CODE=B#16#6 AND NOT sEnde_mit_Fehler
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DW[sOFFSET_DATEN]:=IDB_NR.DW[RECV2_BUFFER+4];

ELSIF sFUNC_CODE=B#16#10 AND NOT sEnde_mit_Fehler
THEN
SRCBLK_Struct.Length:=INT_TO_WORD(sNUMBER_OF_VALUES*2);
SRCBLK_Struct.DB_Number:=sIDB_Nr;
SRCBLK_Struct.Byte_Pointer:=SHL(IN:=DINT_TO_DWORD(RECV2_BUFFER+7), N:=3) AND DW#16#FFFFFF OR DW#16#84000000;
DSTBLK_Struct.Length:=SRCBLK_Struct.Length;
DSTBLK_Struct.DB_Number:=sDATEN_DB;
DSTBLK_Struct.Byte_Pointer:=SHL(IN:=DINT_TO_DWORD(sOFFSET_DATEN), N:=3) AND DW#16#FFFFFF OR DW#16#84000000;

sBLKMOV_RET_VAL:=BLKMOV(SRCBLK :=SRCBLK_Struct_any,DSTBLK := DSTBLK_Struct_any);

IF sBLKMOV_RET_VAL<>0 AND STATUS=W#16#0
THEN
STATUS:=INT_TO_WORD(sBLKMOV_RET_VAL) ;
STATUS_FUNC:='BLKMOV';
sEXCEPTION_CODE:=B#16#2;
END_IF;
END_IF;
ELSIF sDATA_TYPE=B#16#1
THEN
IF sNUMBER_OF_VALUES<=0 OR sNUMBER_OF_VALUES>1968
THEN
STATUS:=W#16#A005;
sEXCEPTION_CODE:=B#16#3;
ELSIF sFUNC_CODE=B#16#F AND (sByteCount_Bit <> BYTE_TO_INT(IDB_NR.DB[RECV2_BUFFER+6]))
THEN
STATUS:=W#16#A00C;
sEXCEPTION_CODE:=B#16#3;
sEnde_mit_Disconnect:=true;
ELSIF (sFUNC_CODE=B#16#F AND sByteCount_Bit+7<>sLEN_RECV2) OR
(sFUNC_CODE=B#16#5 AND sLEN_RECV2<>6)
THEN
STATUS:=W#16#A00E;
sEnde_mit_Disconnect:=true;
END_IF;
sFirst_Byte:=DINT_TO_INT(sOFFSET_DATEN/16);
sFirst_Bit:=DINT_TO_INT(sOFFSET_DATEN/2 MOD 8);

IF sFUNC_CODE=B#16#5 AND NOT sEnde_mit_Fehler
THEN
sCoil_On_Off:=IDB_NR.DB[RECV2_BUFFER+4];
IF sCoil_On_Off=B#16#0
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte]:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte] AND ROL(IN:=B#16#FE,N:=sFirst_Bit);
ELSIF sCoil_On_Off=B#16#FF
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte]:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte] OR ROL(IN:=B#16#1,N:=sFirst_Bit);
ELSE
STATUS:=W#16#A01B;
sEXCEPTION_CODE:=B#16#3;
END_IF;
END_IF;

IF sFUNC_CODE=B#16#F AND NOT sEnde_mit_Fehler
THEN
sLast_Byte:=DINT_TO_INT((sOFFSET_DATEN/2+INT_TO_DINT(sNUMBER_OF_VALUES))/8);
sLast_Bit:=DINT_TO_INT((sOFFSET_DATEN/2+INT_TO_DINT(sNUMBER_OF_VALUES)) MOD 8);
sShift_rigth:=SHR(IN:=B#16#FF,N:=8-sLast_Bit);
sShift_left:=SHL(IN:=B#16#FF,N:=sLast_Bit);

slength_Multiple_8:=(sNUMBER_OF_VALUES MOD 8)=0;
sFirstBit_Grenze0:=(sFirst_Bit=0);
IF sFirstBit_Grenze0
THEN
j:=0;
FOR i:=sFirst_Byte TO sLast_Byte BY 1 DO
IF i=sLast_Byte OR sFirst_Byte=sLast_Byte
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DB[i]:=(sShift_left AND WORD_TO_BLOCK_DB(sDATEN_DB).DB[i]) OR (sShift_rigth AND IDB_NR.DB[RECV2_BUFFER+7+j]);
EXIT;
END_IF;
WORD_TO_BLOCK_DB(sDATEN_DB).DB[i]:=IDB_NR.DB[RECV2_BUFFER+7+j];
j:=j+1;
END_FOR;
ELSE
sVariable_1:=SHL(IN:=IDB_NR.DB[RECV2_BUFFER+7],N:=sFirst_Bit)
OR
(SHR(IN:=B#16#FF,N:=8-sFirst_Bit) AND WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte]);

IF sLast_Byte=sFirst_Byte
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte]:=(sVariable_1 AND sShift_rigth) OR
(WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte] AND sShift_left);
 
ELSE
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte]:=sVariable_1;
FOR i:=1 TO sLast_Byte-sFirst_Byte BY 1 DO
sVariable_1:=SHR(IN:=IDB_NR.DB[INT_TO_DINT(i)+6+RECV2_BUFFER],N:=(8-sFirst_Bit));
IF i=(sLast_Byte-sFirst_Byte)
THEN
IF sNUMBER_OF_VALUES>=8
THEN
sLength_groesser_8:=true;
ELSE
sLength_groesser_8:=false;
IF sLast_Bit=0
THEN
sShift_rigth:=SHR(IN:=B#16#FF,N:=8-(sLast_Bit+1));
sShift_left:=SHL(IN:=B#16#FF,N:=sLast_Bit+1);
END_IF;

WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i]:=(WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i] AND sShift_left) OR
(sShift_rigth AND sVariable_1);
EXIT;
END_IF;

ELSE
sLength_groesser_8:=false;
END_IF;

sVariable_1:=SHL(IN:=IDB_NR.DB[RECV2_BUFFER+7+i],N:=sFirst_Bit) OR sVariable_1;

IF sLength_groesser_8
THEN
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i]:=(WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i] AND sShift_left) OR
(sVariable_1 AND sShift_rigth);
ELSE
WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i]:=sVariable_1;
END_IF;
END_FOR;
END_IF;
END_IF;
END_IF;
ELSE
STATUS:=W#16#A01F;
sEnde_mit_Fehler:=true;
END_IF;
IF NOT sEnde_mit_Fehler AND NOT sEnde_mit_Disconnect
THEN
IDB_NR.DW[SEND_BUFFER]:=sTI;
IDB_NR.DW[SEND_BUFFER+2]:=W#16#0;
IDB_NR.DW[SEND_BUFFER+4]:=W#16#6;
AG_Send_Length:=12;
IDB_NR.DB[SEND_BUFFER+6]:=sUnit;
IDB_NR.DB[SEND_BUFFER+7]:=sFUNC_CODE;
IDB_NR.DW[SEND_BUFFER+8]:=START_ADDRESS;

IF sFUNC_CODE=B#16#F OR sFUNC_CODE=B#16#10
THEN
IDB_NR.DW[SEND_BUFFER+10]:=INT_TO_WORD(sNUMBER_OF_VALUES);
END_IF;

IF sFUNC_CODE=B#16#6
THEN
IDB_NR.DW[SEND_BUFFER+10]:=IDB_NR.DW[RECV2_BUFFER+4];
END_IF;

IF sFUNC_CODE=5
THEN
IDB_NR.DB[SEND_BUFFER+10]:=sCoil_On_Off;
IDB_NR.DB[SEND_BUFFER+11]:=B#16#0;
END_IF;

sSenden_Neustart:=true;
 
END_IF;
ELSE
IDB_NR.DW[SEND_BUFFER]:=sTI;
IDB_NR.DW[SEND_BUFFER+2]:=W#16#0;
IDB_NR.DB[SEND_BUFFER+6]:=sUnit;
IDB_NR.DB[SEND_BUFFER+7]:=sDATA_TYPE;

IF sDATA_TYPE=B#16#3 OR sDATA_TYPE=B#16#4
THEN
IF sNUMBER_OF_VALUES<=0 OR sNUMBER_OF_VALUES>125
THEN
STATUS:=W#16#A005;
sEXCEPTION_CODE:=B#16#3;
END_IF;
IF NOT sEnde_mit_Fehler
THEN
IDB_NR.DW[SEND_BUFFER+4]:=INT_TO_WORD(sNUMBER_OF_VALUES*2+3);
IDB_NR.DB[SEND_BUFFER+8]:=INT_TO_BYTE(sNUMBER_OF_VALUES*2);
AG_Send_Length:=sNUMBER_OF_VALUES*2+9;
SRCBLK_Struct.Length:=INT_TO_WORD(sNUMBER_OF_VALUES*2);
SRCBLK_Struct.DB_Number:=sDATEN_DB;
SRCBLK_Struct.Byte_Pointer:=SHL(IN:=DINT_TO_DWORD(sOFFSET_DATEN),N:=3) AND DW#16#FFFFFF OR DW#16#84000000;
DSTBLK_Struct.Length:=W#16#FA;
DSTBLK_Struct.DB_Number:=sIDB_Nr;
DSTBLK_Struct.Byte_Pointer:=SHL(IN:=DINT_TO_DWORD(SEND_BUFFER+9),N:=3) AND DW#16#FFFFFF OR DW#16#84000000;

sBLKMOV_RET_VAL:=BLKMOV(SRCBLK :=SRCBLK_Struct_any,DSTBLK :=DSTBLK_Struct_any);

IF sBLKMOV_RET_VAL<>0 AND STATUS=W#16#0
THEN
STATUS:=INT_TO_WORD(sBLKMOV_RET_VAL);
STATUS_FUNC:='BLKMOV';
sEXCEPTION_CODE:=B#16#2;
END_IF;
END_IF;
ELSIF sDATA_TYPE=B#16#1 OR sDATA_TYPE=B#16#2
THEN
IF sNUMBER_OF_VALUES<=0 OR sNUMBER_OF_VALUES>2000
THEN
STATUS:=W#16#A005;
sEXCEPTION_CODE:=B#16#3;
ELSE
IDB_NR.DW[SEND_BUFFER+4]:=INT_TO_BYTE(sByteCount_Bit+3);
IDB_NR.DB[SEND_BUFFER+8]:=INT_TO_BYTE(sByteCount_Bit);
AG_Send_Length:=9+sByteCount_Bit;
sLast_Bit:=DINT_TO_INT((sOFFSET_DATEN/2+INT_TO_DINT(sNUMBER_OF_VALUES)) MOD 8);

IF sOFFSET_DATEN=0 THEN sLast_Bit:=sLast_Bit-1; END_IF;

sFirst_Byte:=DINT_TO_INT(sOFFSET_DATEN/16);
sFirst_Bit:=DINT_TO_INT(sOFFSET_DATEN/2 MOD 8);
sLast_Byte:=DINT_TO_INT((sOFFSET_DATEN/2+INT_TO_DINT(sNUMBER_OF_VALUES))/8);

slength_Multiple_8:=(sNUMBER_OF_VALUES MOD 8) = 0;

sFirstBit_Grenze0:=sFirst_Bit=0 ;

IF NOT sFirstBit_Grenze0 AND NOT slength_Multiple_8
THEN
IF sLast_Byte=sFirst_Byte
THEN
IDB_NR.DB[SEND_BUFFER+9]:=SHR(IN:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte],N:=sFirst_Bit) AND SHR(IN:=B#16#FF,N:=8-sNUMBER_OF_VALUES);
ELSE

FOR i:= 0 TO sByteCount_Bit-1 BY 1 DO
sVariable_1:=SHR(IN:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i],N:=sFirst_Bit);
sVariable_2:=SHL(IN:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i+1],N:=8-sFirst_Bit) OR sVariable_1;

IF i=(sByteCount_Bit-1) AND 8*sByteCount_Bit>sNUMBER_OF_VALUES
THEN
sVariable_2:= SHR(IN:=B#16#FF,N:=8*sByteCount_Bit-sNUMBER_OF_VALUES) AND sVariable_2;
END_IF;

IDB_NR.DB[SEND_BUFFER+9+i]:=sVariable_2;
 
END_FOR;
END_IF;
ELSE
FOR i:= 0 TO sByteCount_Bit-1 BY 1 DO

IF i=(sByteCount_Bit-1) AND NOT slength_Multiple_8 AND sFirstBit_Grenze0
THEN
IDB_NR.DB[SEND_BUFFER+9+i]:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i] AND SHR(IN:=B#16#FF,N:=7-sLast_Bit);
ELSE
IDB_NR.DB[SEND_BUFFER+9+i]:=SHR(IN:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i],N:=sFirst_Bit) OR
SHL(IN:=WORD_TO_BLOCK_DB(sDATEN_DB).DB[sFirst_Byte+i+1],N:=8-sFirst_Bit);
END_IF;
END_FOR;
END_IF;
END_IF;
ELSE
STATUS:=W#16#A01F;
sEnde_mit_Fehler:=true;
END_IF;
IF NOT sEnde_mit_Fehler THEN sSenden_Neustart:=true; END_IF;
END_IF;
END_IF;
END_IF;

IF sEXCEPTION_CODE<>B#16#0
THEN
IF STATUS=W#16#0 THEN STATUS:=W#16#A006; END_IF;
ERROR:=true;
State.Recv2:=false;
State.Send:=true;
State.Except:=true;
IDB_NR.DW[SEND_BUFFER]:=sTI;
IDB_NR.DW[SEND_BUFFER+2]:=W#16#0;
IDB_NR.DW[SEND_BUFFER+4]:=W#16#3;
AG_Send_Length:=9;
IDB_NR.DB[SEND_BUFFER+6]:=sUnit;
IDB_NR.DB[SEND_BUFFER+7]:=sFUNC_CODE OR B#16#80;
IDB_NR.DB[SEND_BUFFER+8]:=sEXCEPTION_CODE;
sSenden_Neustart:=true;
sEXCEPTION_CODE:=B#16#0;
END_IF;
IF sSenden_Neustart THEN State.Send:=true; END_IF;
END_IF;
END_IF;
ELSE
TON(IN :=true,PT :=sMONITOR);
IF TON.Q
THEN
State.Recv2:=false;
State.Auftrag_laeuft:=false;
STATUS:=W#16#A008;
sEnde_mit_Disconnect:=true;
END_IF;
END_IF;
END_IF;
END_IF;

IF State.Send
THEN
AG_Struct.Length:=W#16#104;
AG_Struct.Byte_Pointer:=SHL(IN:=DINT_TO_DWORD(SEND_BUFFER),N:=3) AND DW#16#FFFFFF OR DW#16#84000000;
AG_LSEND(ACT :=sSenden_Neustart
,ID :=ID
,LADDR :=LADDR
,SEND :=AG_Struct_any
,LEN :=AG_Send_Length
,DONE :=AG_Send_Done
,ERROR :=sError_FC
,STATUS :=sStatus_FC
);

sSenden_Neustart:=false;

IF (sStatus_FC<>W#16#7000) AND sError_FC
THEN
IF NOT AG_Send_wait
THEN
AG_Send_wait:=true;
State.Comm_Delay:=true;
sSenden_Neustart:=true;
ELSE
AG_Send_wait:=false;
STATUS:=sStatus_FC;
STATUS_FUNC:='AG_SEND';

IF DWORD_TO_DINT(sStatus_FC) >= 32768
THEN
State.Comm_Delay:=true;
END_IF;
sEnde_mit_Fehler:=true;
END_IF;
ELSIF AG_Send_Done
THEN
State.Auftrag_laeuft:=false;
State.Send:=false;
AG_Send_wait:=false;
IF NOT State.Except
THEN
DATA_TYPE:=sDATA_TYPE;
START_ADDRESS:=DINT_TO_WORD(sSTART_ADDRESS);
LENGTH:=INT_TO_WORD(sNUMBER_OF_VALUES);
UNIT:=sUnit;
TI:=sTI;
WRITE_READ:=sWRITE_READ;
DONE_NDR:=true;
ELSE
State.Except:=false;
END_IF;
END_IF;
END_IF;
IF NOT State.Send AND
NOT State.Recv1 AND
NOT State.Recv2 AND
State.Auftrag_laeuft AND
NOT sEnde_mit_Fehler AND
NOT sEnde_mit_Disconnect
THEN
STATUS:=W#16#A01F;
sEnde_mit_Fehler:=true;
END_IF;
END_IF;

IF sEnde_mit_Fehler
THEN
sEnde_mit_Fehler:=false;
State.Send:=false;
State.Recv1:=false;
State.Recv2:=false;
State.Auftrag_laeuft:=false;
TON(IN :=false,PT :=sMONITOR);
ERROR:=true;
END_IF;

IF NOT State.Send AND sEnde_mit_Disconnect
THEN
State.Auftrag_laeuft:=false;
State.Send:=false;
State.Recv1:=false;
State.Recv2:=false;
AG_CNTRL(ACT :=true
,ID :=ID
,LADDR :=LADDR
,CMD :=2
,DONE :=AG_CNTRL.DONE
,ERROR :=AG_CNTRL.ERROR
,STATUS :=AG_CNTRL.STATUS
,RESULT1 :=AG_CNTRL.RESULT1
,RESULT2 :=AG_CNTRL.RESULT2
);
IF AG_CNTRL.ERROR
THEN
IF NOT AG_Cntrl_wait
THEN
AG_Cntrl_wait:=true;
State.Comm_Delay:=true;
ELSE
AG_Cntrl_wait:=false;
STATUS:=AG_CNTRL.STATUS;
STATUS_FUNC:='AG_CNTRL';
END_IF;
END_IF;

IF NOT AG_Cntrl_wait AND AG_CNTRL.ERROR OR AG_CNTRL.DONE
THEN
TON(IN :=false,PT :=sMONITOR);
ERROR:=true;
AG_Cntrl_wait:=false;
sEnde_mit_Disconnect:=false;
END_IF;
END_IF;

BUSY:=State.Auftrag_laeuft;
IF DWORD_TO_DINT(STATUS) >= 40960
THEN
STATUS_FUNC:='MODBUSCP';
ERROR:=true;
END_IF;

END_IF;
 

END_FUNCTION_BLOCK



:



- :). - .



:





modbus

Block checksum .





, (zip, 3Mb)







: 6024

: -    : 2014-12-02

Modbus RTU?

: komatic    : 2014-12-02

RTU dda_dda@mail.ru - RTU

:

(4000 max):

: