当前位置: 首页 > 知识库问答 >
问题:

CRC16(ModBus)-计算算法

叶国兴
2023-03-14

我正在使用ModBus RTU,并试图找出如何计算CRC16。我不需要代码示例。我只是对机制很好奇。我已经了解到,基本的CRC是数据字的多项式除法,根据多项式的长度,用零填充。下面的测试示例应该检查我的基本理解是否正确:

  • 数据字:01001011
  • 多项式:1001(x3+1)
  • 由于最高指数x3
  • 而被填充3位
  • 计算:0100 1011 000/1001->余数:011

计算。

01001011000
 1001
 0000011000
      1001
      01010
       1001
       0011 
    null

第二次尝试:由于初始值,用1填充16位。二进制计算余数为0000000000110100,十六进制为0064,不正确。

如果有人能解释或澄清我的假设,那就太好了。老实说,我确实花了很多时间寻找答案,但每个解释都是基于C/C++或其他html" target="_blank">语言中的代码示例,我不明白这一点。提前谢了。

编辑2:马克·阿德勒斯的回答做到了这一点。但是,现在我可以计算CRC16/Modbus,还有一些问题需要澄清。不是需要而是感激。

    null

共有1个答案

闻人望
2023-03-14

让我们一步一步来。您现在知道如何正确计算CRC-16/BuyPass了,所以我们将从那里开始。

让我们来看看CRC-16/CCITT-FALSE。它的初始值不是零,但仍然有RefIn和RefOut为false,如CRC-16/BUYPASS。要计算数据的CRC-16/CCITT-FALSE值,可以使用Init值0xFFFF对数据的前16位进行独占。它给出fe ef C0.030001。现在使用多项式0x11021执行您所知道的操作。您将得到表中的内容0xb53f

现在您知道如何应用init了。下一步是处理RefIn和RefOut是否为真。我们将使用CRC-16/ARC作为一个例子。RefIn意味着我们反映输入的每个字节中的位。RefOut意味着我们反映了剩余部分的比特。然后输入消息为:800803 C00080。除以多项式0x18005,我们得到0xb34b。现在我们反映所有这些位(不是在每个字节中,而是在所有16位中),我们得到0xd2cd。这就是您在表中看到的结果。

 类似资料:
  • 这给出了一个值-107。我对C还比较陌生,我还在做一些实验 谢谢你。

  • 这是代码 更新的答案

  • 我试图将一个旧代码从C移植到C#,它基本上接收一个字符串并返回一个CRC16... 我的移植C#代码如下: 测试字符串是“OPN”...它必须返回一个uint,ofc)2字节a8a9,#CRC_MASK是该计算的多项式。我确实在这里和网上找到了几个CRC16的例子,但没有一个达到这个结果,因为这个CRC计算必须与我们连接的设备匹配。 错在哪里?我真的很感激任何帮助。 cmd变量的值是我试图发送到设

  • 因此,我的问题是:如何从整数结果到所需的双十六进制结果?我试了几个选择,都没有成功。 注意:我使用的是Qt,所以如果有人能找到实现QByteArray或其他Qt友好代码的解决方案,我会很高兴的。无论哪种方式,不使用Qt、C或C++的解决方案都是无用的:P

  • 我正在用Lua编写一个Wireshark协议解析器。它解析的协议包含crc16校验和。解剖者应检查crc是否正确。 我在这里发现了一个用C编写的crc16实现,其中已经包含了lua包装器代码。我已经成功编译并运行了它(例如)。问题是它需要一个字符串作为输入。从wireshark中,我得到了一个似乎是lua类型的缓冲区。所以当我这么做的时候 Lua抱怨。 crc16实现中的如下所示:

  • 我有字符串:。我需要计算这个字符串的CRC。 我有一个计算CRC的函数: 我想将一个字符串强制转换为ushort数组: 但是返回给我的是这样一个数组:。 请告诉我为了正确计算CRC我应该做些什么。