(* 1、III型Modbus TCP服务端模块 2、为了实现通用化 *) FUNCTION_BLOCK ModbusTCP_Client VAR_IN_OUT IPAddr: STRING; //IP wPort: WORD; //端口 UnitID: UINT; //ID Address: DWORD; //起始地址 NumBits: INT; //线圈状态寄存器个数 NumInputBits: INT; //输入状态寄存器个数 NumRegisters: INT; //保持寄存器个数 NumInputRegisters: INT; //输入寄存器个数 //寄存器 tab_bits: ARRAY[0..149] OF BOOL; //线圈状态寄存器 1位,最高300个,客户端只写,服务端只读 tab_inputbits: ARRAY[0..149] OF BOOL; //输入状态寄存器1位,最高300个,客户端只读,服务端只写 tab_regs: ARRAY[0..149] OF INT; //保持寄存器 16位,最高300个,客户端只写,服务端只读 tab_inputregs: ARRAY[0..149] OF INT; //输入寄存器16位,最高300个,客户端只读,服务端只写 END_VAR VAR_OUTPUT Status: INT; errorID: UINT := 0; END_VAR VAR //客户端通信(实例化) aMBUS_TCP_REQ: ARRAY[0..5] OF HSMBUS.ModbusTcpClient; iCounter: INT; //计数器 iMdbRegStatus: INT; //状态机 abDoneConnect: ARRAY[0..10] OF INT; tab_bits1: ARRAY[0..149] OF BOOL; //线圈状态寄存器 1位,最高300个,客户端只写,服务端只读 END_VAR
CASE iMdbRegStatus OF 0: //初始化 (*4种寄存器*) FOR iCounter:= 0 TO 3 BY 1 DO aMBUS_TCP_REQ[iCounter]( iId:= 1, strIpAddr:= IPAddr, iPort:= wPort, bEnable:= FALSE, iRspTimeout:= 1000); END_FOR iMdbRegStatus:=1; //下一状态机 1://读或者写数据 //读取线圈寄存器 aMBUS_TCP_REQ[0]( bEnable:= TRUE, iFuncCode:= ModbusCmd.MODBUS_READ_DISCRETE_INPUTS,//功能码, Address1:= Address,//起始地址 iDataSize1:= NumBits,//线圈寄存器个数, dataPtr1:= ADR(tab_bits),//存储数据, iStatus=> Status, iDone=> abDoneConnect[0], iError=> errorID); IF abDoneConnect[0]=1 AND Status=1 THEN iMdbRegStatus:= 2; aMBUS_TCP_REQ[0]( iId:= 1, strIpAddr:= IPAddr, iPort:= wPort, bEnable:= FALSE, iRspTimeout:= 1000); END_IF 2: //写入线圈寄存器 aMBUS_TCP_REQ[0]( bEnable:= TRUE, iFuncCode:= ModbusCmd.MODBUS_WRITE_MULTIPLE_COILS,//功能码, Address1:= Address,//起始地址 iDataSize1:= NumInputBits,//线圈寄存器个数, dataPtr1:= ADR(tab_inputbits),//存储数据, iStatus=> Status, iDone=> abDoneConnect[0], iError=> errorID); IF abDoneConnect[0]=1 AND Status=1 THEN iMdbRegStatus:= 3; aMBUS_TCP_REQ[0]( iId:= 1, strIpAddr:= IPAddr, iPort:= wPort, bEnable:= FALSE, iRspTimeout:= 1000); END_IF 3: //读取写入寄存器 aMBUS_TCP_REQ[0]( bEnable:= TRUE, iFuncCode:= ModbusCmd.MODBUS_READ_INPUT_REGISTERS,//功能码, Address1:= Address,//起始地址 iDataSize1:= NumRegisters,//线圈寄存器个数, dataPtr1:= ADR(tab_regs),//存储数据, iStatus=> Status, iDone=> abDoneConnect[0], iError=> errorID); IF abDoneConnect[0]=1 AND Status=1 THEN iMdbRegStatus:= 4; aMBUS_TCP_REQ[0]( iId:= 1, strIpAddr:= IPAddr, iPort:= wPort, bEnable:= FALSE, iRspTimeout:= 1000); END_IF 4: //写入寄存器 aMBUS_TCP_REQ[0]( bEnable:= TRUE, iFuncCode:= ModbusCmd.MODBUS_WRITE_MULTIPLE_REGISTERS,//功能码, Address1:= Address,//起始地址 iDataSize1:= NumInputRegisters,//线圈寄存器个数, dataPtr1:= ADR(tab_inputregs),//存储数据, iStatus=> Status, iDone=> abDoneConnect[0], iError=> errorID); //各类寄存器读或写完成 IF abDoneConnect[0]=1 AND Status=1 THEN iMdbRegStatus:=1; aMBUS_TCP_REQ[0]( iId:= 1, strIpAddr:= IPAddr, iPort:= wPort, bEnable:= FALSE, iRspTimeout:= 1000); END_IF END_CASE (* CASE iMdbRegStatus OF 0: //初始化 (*4种寄存器*) FOR iCounter:= 0 TO 3 BY 1 DO aMBUS_TCP_REQ[iCounter]( ReqEnable:=FALSE, UnitID:=1, Port:=wPort, IPAddr:=IPAddr, RspTimeOut:=1000, DataTimeOut:=1000 ); END_FOR iMdbRegStatus:=1; //下一状态机 1://读或者写数据 //读取线圈寄存器 aMBUS_TCP_REQ[0]( ReqEnable:=TRUE, Command:=HNCMBUS.MODBUS_READ_DISCRETE_INPUTS, Address0:=Address, DataSize0:=NumBits, DataPtr0:=ADR(tab_bits), Status =>Status, ErrorID =>errorID, Done =>abDoneConnect[0] ); //写入线圈寄存器 aMBUS_TCP_REQ[1]( ReqEnable:=TRUE, Command:=HNCMBUS.MODBUS_WRITE_MULTIPLE_COILS, Address0:=Address, DataSize0:=NumInputBits, DataPtr0:=ADR(tab_inputbits), Status =>Status, ErrorID =>errorID, Done =>abDoneConnect[1] ); //读取写入寄存器 aMBUS_TCP_REQ[2]( ReqEnable:=TRUE, Command:=HNCMBUS.MODBUS_READ_INPUT_REGISTERS, Address0:=Address, DataSize0:=NumRegisters, DataPtr0:=ADR(tab_regs), Status =>Status, ErrorID =>errorID, Done =>abDoneConnect[2] ); //写入寄存器 aMBUS_TCP_REQ[3]( ReqEnable:=TRUE, Command:=HNCMBUS.MODBUS_WRITE_MULTIPLE_REGISTERS, Address0:=Address, DataSize0:=NumInputRegisters, DataPtr0:=ADR(tab_inputregs), Status =>Status, ErrorID =>errorID, Done =>abDoneConnect[3] ); //各类寄存器读或写完成 IF (*abDoneConnect[0] AND abDoneConnect[1] AND abDoneConnect[2] AND*) abDoneConnect[3] THEN iMdbRegStatus:=0; END_IF END_CASE *)