使用西门子 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

代码解释

  1. 定义变量和常量:
    • 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
  2. 读取输入状态:
    • 使用 FOR 循环遍历 inputs 数组的每个元素,从 I0.0 开始依次读取 8 个输入状态,并存储到 inputs 数组中。
    • 每次读取一个输入状态后,将其转换为 Modbus 格式,即将其二进制值左移 i 位,并与 mbTxData[7] 按位或运算,将结果存储到 mbTxData[7] 中。
  3. 发送 Modbus 请求帧,并等待响应帧:
    • 调用 COM_TX 函数发送 mbTxData 数组,长度为 8。
    • 调用 COM_RX 函数接收 mbRxData 数组,长度为 5 + mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ),即 Modbus 响应帧的长度。
  4. 检查 Modbus 响应帧的有效性:
    • 如果 COM_ERROR 为 0,且 mbRxData[0] 等于 mbAddrmbRxData[1] 等于 mbFuncmbRxData[2] 等于 mbCount / 8 + IF( mbCount MOD 8 > 0, 1, 0 ),则说明 Modbus 响应帧有效。
    • 调用 CRC16 函数计算 Modbus 帧的循环冗余校验码,并检查是否与响应帧中的校验码相等。
    • 如果 Modbus 响应帧有效,则可以根据其他设备的反馈进行处理,这里代码中使用 TODO 占位符。

注意事项

  • 确保 PLC 与其他设备的 Modbus 通信参数一致,例如地址、波特率、数据位、校验位等。
  • 需要根据实际情况修改代码中的 Modbus 地址、功能码、起始地址、数据长度等参数。
  • 确保 COM_TXCOM_RX 函数的正确使用。
  • 可以根据需要添加其他功能,例如错误处理、超时处理等。
  • 代码中使用了 CRC16 函数进行校验码计算,需要确保该函数的正确使用。
  • 本示例代码仅供参考,实际应用中需要根据具体需求进行调整和完善。

原文地址: https://www.cveoy.top/t/topic/nKiL 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录