You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TwinCAT 3中计算CheckSum8 Xor?CRC_GEN函数异常求助

问题与解决方案

问题描述

我正在使用类似$02WSLD00000$03的命令,已知该命令的校验和应为ASCII字符=(十进制61、十六进制3D)。尝试用OSCAT库的CRC_GEN函数计算时完全无效,但某在线计算器能得到正确值。当前代码如下:

IF StartCheckSum THEN
    CommandARRAY := MAXSTRING_TO_BYTEARR(GVL_SERIAL.HexCommand1);
    CheckSumResult := CRC_GEN(
        ADR(GVL_SERIAL.HexCommand1), 
        SIZEOF(GVL_SERIAL.HexCommand1),
        16#1021, 16#8F, 16#0000, REV_IN, REV_OUT, 16#0000
    );
END_IF

StartCheckSum := FALSE;

问题分析与修正步骤

1. 数据长度错误

SIZEOF(GVL_SERIAL.HexCommand1)返回的是字符串变量的总分配内存长度(包含未使用的空字节),而非实际有效字符数,这会导致计算时包含多余的无效字节,结果自然错误。

修正:用LEN(GVL_SERIAL.HexCommand1)替代SIZEOF,确保仅计算命令中的有效字符。另外需确认计算范围:比如是否需要排除命令首尾的特殊字符(如$02或$03),需与在线计算器的计算范围完全一致。

2. CRC参数不匹配

你的校验和是单字节(ASCII=对应十六进制3D),说明使用的是8位CRC算法,但当前代码配置的是16位CRC参数(多项式16#1021),且反转模式、初始值等参数大概率和在线计算器不匹配。

修正:

  • 先确认在线计算器的具体CRC配置:多项式、初始值、输入是否反转、输出是否反转、结果是否异或。
  • 改用OSCAT的8位CRC参数(或直接使用CRC8_GEN函数,如果库中存在),示例配置(需根据实际计算器参数调整):
    CheckSumResult := CRC_GEN(
        ADR(GVL_SERIAL.HexCommand1), 
        CommandLength,
        16#07, 16#00, 16#00, NO_REV_IN, NO_REV_OUT, 16#00
    );
    

3. 结果转换为ASCII字符

CRC_GEN返回的是数值型结果,需要将其低8位转换为对应的ASCII字符,才能得到=。

修正:添加转换逻辑:

CheckSumChar := BYTE_TO_CHAR(CheckSumResult AND 16#FF);

修正后完整代码示例

IF StartCheckSum THEN
    // 获取有效命令长度
    CommandLength := LEN(GVL_SERIAL.HexCommand1);
    // 调用CRC_GEN,参数需与在线计算器完全匹配
    CheckSumResult := CRC_GEN(
        ADR(GVL_SERIAL.HexCommand1), 
        CommandLength,
        16#07, 16#00, 16#00, NO_REV_IN, NO_REV_OUT, 16#00
    );
    // 转换为ASCII字符
    CheckSumChar := BYTE_TO_CHAR(CheckSumResult AND 16#FF);
END_IF

StartCheckSum := FALSE;

关键注意事项

  • 务必1:1匹配在线计算器的CRC参数,任何参数差异都会导致结果错误。
  • 验证字符串的编码格式:确保GVL_SERIAL.HexCommand1是ASCII编码,避免UTF-8等多字节编码导致的字节值错误。

内容的提问来源于stack exchange,提问作者Ivan Félix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 03:20:25