如何在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
相关产品推荐
相关产品推荐

