西门子 PLC 通过 Modbus-RTU 发送 I0.0-I0.7 输入状态
使用西门子 PLC 通过 Modbus-RTU 发送 I0.0-I0.7 输入状态
本示例代码演示如何使用西门子 PLC 通过 Modbus-RTU 协议将输入状态 I0.0-I0.7 发送到其他设备。
PROGRAM SendInputsToModbusRTU
VAR
i: INT;
inputs: ARRAY[0..7] OF BOOL;
mbAddr: BYTE := 1; (* Modbus 地址 *)
mbFunc: BYTE := 3; (* Modbus 读取线圈的功能码 *)
mbStart: WORD := 0; (* Modbus 起始地址 *)
mbCount: WORD := 8; (* Modbus 读取线圈的数量 *)
mbCRC: WORD;
mbTxData: ARRAY[0..7] OF BYTE := ( mbAddr, mbFunc, mbStart / 256, mbStart MOD 256, mbCount / 256, mbCount MOD 256, 0, 0 ); (* Modbus 请求帧 *)
mbRxData: ARRAY[0..255] OF BYTE; (* Modbus 响应帧 *)
END_VAR
(* 读取输入状态,并将其转换为 Modbus 格式,发送给其他设备 *)
FOR i := 0 TO 7 DO
inputs[i] := I0.0 + i; (* 读取输入状态 *)
mbTxData[7] := mbTxData[7] OR (BYTE(inputs[i]) SHL i); (* 转换为 Modbus 格式 *)
END_FOR
(* 发送 Modbus 请求帧,并等待响应帧 *)
COM_TX( txData := mbTxData, txLen := 8 );
COM_RX( rxData := mbRxData, rxLen := 5 + mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ) );
(* 检查 Modbus 响应帧的有效性 *)
IF ( COM_ERROR = 0 AND mbRxData[0] = mbAddr AND mbRxData[1] = mbFunc AND mbRxData[2] = mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ) ) THEN
mbCRC := CRC16( data := mbRxData, len := 3 + mbRxData[2] );
IF ( mbCRC = WORD_TO_UINT(mbRxData[3 + mbRxData[2]]) * 256 + WORD_TO_UINT(mbRxData[4 + mbRxData[2]]) ) THEN
(* Modbus 响应帧有效,处理其他设备的反馈 *)
(* TODO *)
END_IF
END_IF
代码解释
- 定义变量和常量:
inputs数组用于存储输入状态,长度为 8,类型为BOOL。mbAddr常量代表 Modbus 地址,这里设为 1。mbFunc常量代表 Modbus 功能码,读取线圈的功能码为 3。mbStart常量代表 Modbus 起始地址,这里设为 0。mbCount常量代表 Modbus 读取线圈的数量,这里设为 8。mbCRC变量用于存储 Modbus 帧的循环冗余校验码。mbTxData数组用于存储 Modbus 请求帧,长度为 8,类型为BYTE。mbRxData数组用于存储 Modbus 响应帧,长度为 256,类型为BYTE。
- 读取输入状态:
- 使用
FOR循环遍历inputs数组的每个元素,从I0.0开始依次读取 8 个输入状态,并存储到inputs数组中。 - 每次读取一个输入状态后,将其转换为 Modbus 格式,即将其二进制值左移 i 位,并与
mbTxData[7]按位或运算,将结果存储到mbTxData[7]中。
- 使用
- 发送 Modbus 请求帧,并等待响应帧:
- 调用
COM_TX函数发送mbTxData数组,长度为 8。 - 调用
COM_RX函数接收mbRxData数组,长度为 5 + mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ),即 Modbus 响应帧的长度。
- 调用
- 检查 Modbus 响应帧的有效性:
- 如果
COM_ERROR为 0,且mbRxData[0]等于mbAddr,mbRxData[1]等于mbFunc,mbRxData[2]等于 mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ),则说明 Modbus 响应帧有效。 - 调用
CRC16函数计算 Modbus 帧的循环冗余校验码,并检查是否与响应帧中的校验码相等。 - 如果 Modbus 响应帧有效,则可以根据其他设备的反馈进行处理,这里代码中使用
TODO占位符。
- 如果
注意事项
- 确保 PLC 与其他设备的 Modbus 通信参数一致,例如地址、波特率、数据位、校验位等。
- 需要根据实际情况修改代码中的 Modbus 地址、功能码、起始地址、数据长度等参数。
- 确保
COM_TX和COM_RX函数的正确使用。 - 可以根据需要添加其他功能,例如错误处理、超时处理等。
- 代码中使用了
CRC16函数进行校验码计算,需要确保该函数的正确使用。 - 本示例代码仅供参考,实际应用中需要根据具体需求进行调整和完善。
原文地址: https://www.cveoy.top/t/topic/nKiL 著作权归作者所有。请勿转载和采集!