Modbus RTU:动态配置
在树中插入 Modbus COM 端口设备时,只能对参数进行静态分配。
如果分配必须是动态的,那么完整的处理必须在 IEC 代码中实现
请注意,I/O 管理器不会同步动态配置中的不同进程。
这可能会导致变量的更新行为与静态配置不同,尤其是在从多个任务访问时。
- 创建标准项目并选择 CODESYS Control Win V3作为设备。
- 通过网络扫描连接目标系统。

- 打开库管理器并添加 Network库。 IoDrvModbus SysCom SysTypes2 Interfaces

- 修改 PLC_PRG 如下:
声明
VAR
xComPortOpen : BOOL;
xComPortError : BOOL;
rtsResult : RTS_IEC_RESULT;
stComPortSettings : SysCom.ComSettings;
hComPort : RTS_IEC_HANDLE;
awReadBuffer : ARRAY[0..31] OF WORD; //note: adjsut to your requirements, max. is 128 Modbus Registers
awWriteBuffer : ARRAY[0..31] OF WORD;
xExec : BOOL;
fbModbusRequest : IoDrvModbus.ModbusRequest2;
eComError : IoDrvModbus.MB_ErrorCodes;
END_VAR
实现
IF(NOT xComPortOpen AND NOT xComPortError) THEN
stComPortSettings.sPort := 3;
stComPortSettings.byStopBits := 1;
stComPortSettings.byParity := 0; //EVEN:=2, ODD:=1 or NONE:=0*
stComPortSettings.ulBaudRate := 19200; //1200, 2400, 4800, ..., 115000 bps
stComPortSettings.ulTimeout := 0;
stComPortSettings.ulBufferSize := 256; //Equals max size of Modbus packet
hComPort := SysCom.SysComOpen2( pSettings := ADR(stComPortSettings), pSettingsEx := 0, pResult := ADR(rtsResult));
xComPortError := (hComPort = RTS_INVALID_HANDLE OR rtsResult <> 0);
xComPortOpen := NOT xComPortError;
END_IF
IF(xComPortOpen) THEN
//apply new command
fbModbusRequest.modbusCommand.uiFunctionCode := 23; //Reda/Write Multiple Register
fbModbusRequest.modbusCommand.uiReadOffset := 0;
fbModbusRequest.modbusCommand.uiReadLen := 2;
fbModbusRequest.modbusCommand.uiWriteOffset := 0;
fbModbusRequest.modbusCommand.uiWriteLen := 2;
fbModbusRequest.pRecvData := ADR(awReadBuffer);
fbModbusRequest.pSendData := ADR(awWriteBuffer);
fbModbusRequest.tResponseTimeout := T#500MS;
//note: if different tasks access the IO-Buffers then use some intermediate buffers
// that are thread safe (use e.g mutex or semaphore) before calling the FB
fbModbusRequest(
hComPort := hComPort,
xExecute := xExec,
usiSlaveAddr := 2,
byModbusError => eComError);
IF(fbModbusRequest.xDone) THEN
//here you get valid data
IF(awWriteBuffer[0] = awReadBuffer[0]) THEN
;
END_IF
ELSIF(fbModbusRequest.xError) THEN
IF(eComError = MB_ErrorCodes.RESPONSE_TIMEOUT) THEN //no cable plugged, wrong Com-Port settings ?
;
END_IF
END_IF
END_IF
- 启动项目并测试功能。