CRC16(ModBus) - 计算算法

问题描述 投票:2回答:1

我正在使用ModBus RTU,我正在试图弄清楚如何计算CRC16。我不需要代码示例。我只是好奇这个机制。我已经知道基本CRC是数据字的多项式除法,用零填充,取决于多项式的长度。以下测试示例应该检查我的基本理解是否正确:

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

计算。

01001011000
 1001
 0000011000
      1001
      01010
       1001
       0011 

编辑1:到目前为止,Mark Adler在之前的评论/答案中进行了验证。

寻找答案我已经看到了许多不同的方法,包括逆转,依赖于小端或大端等,这改变了给定的011的结果。

Modus RTU KRS16

当然我很想了解不同版本的CRC是如何工作的,但我的主要兴趣是简单地理解这里应用的机制。到目前为止,我知道:

  • x16 + x15 + x2 + 1是多项式:0x18005或0b11000000000000101
  • 初始值为0xFFFF
  • 十六进制示例消息:01 10 C0 03 00 01
  • 以上十六进制消息的CRC16:C9CD

我像上面的例子一样手动计算了这个,但我宁愿不在这个问题中用二进制写下来。我认为我对二进制的转换是正确的。我不知道的是如何合并初始值 - 它是用来填充数据字而不是零?或者我是否需要撤消答案?别的什么?

  • 第一次尝试:用零填充16位。以二进制计算的余数为1111 1111 1001 1011,其为十六进制的FF9B,对于CrC16 / Modbus不正确,但对于CRC16 /旁路是正确的
  • 第二次尝试:由于初始值,用16位填充。以二进制计算的余数为0000 0000 0110 0100,其为十六进制的0064且不正确。

如果有人可以解释或澄清我的假设,那将是很好的。老实说,我花了很多时间寻找答案,但每个解释都是基于C / C ++或其他的代码示例,我不明白。提前致谢。

编辑1:根据this网站,“第一次尝试”指向另一个具有相同多项式但具有不同初始值(0x0000)的CRC16方法,这告诉我,计算应该是正确的。 crccalc如何合并初始值?

EDIT2:马克阿德勒斯答案就行了。但是,现在我可以计算CRC16 / Modbus,还有一些问题需要澄清。不需要,但赞赏。

A)计算的顺序是:......?

  • 首次应用RefIn进行完整输入(包括填充位)
  • 第二个xor InitValue(在CRC16中)为前16位
  • 第3次应用RefOut获得完整输出/余数(CRC16中剩余最多16位)

B)参考RefIne和RefOut:它是否始终反映8位输入和所有输出位仍然使用CRC 8或CRC16或CRC32?

C)我指的网站中的第3(检查)和第8(XorOut)列是什么意思?后者似乎相当容易,我猜测它在RefOut之后计算值xor就像InitValue一样?

modbus crc16 boolean-polynomials
1个回答
0
投票

让我们一步一步迈出这一步。您现在知道如何正确计算CRC-16 / BUYPASS,因此我们将从那里开始。

我们来看看CRC-16 / CCITT-FALSE。那个的初始值不为零,但仍然将RefIn和RefOut设为false,如CRC-16 / BUYPASS。要计算数据的CRC-16 / CCITT-FALSE,请使用0xffff的Init值对数据的前16位进行异或。这给了fe ef C0 03 00 01。现在做你所知道的,但用多项式0x11021。你会得到表格中的内容,0xb53f

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

我们现在有了计算CRC-16 / MODBUS所需的东西,它具有非零的初始值(0xffff)和RefIn和RefOut都为真。我们从消息开始,每个字节中的位被反射,前16位被反转。那就是7f f7 03 c0 00 80。除以0x18005,你得到剩余的0xb393。反映这些位,我们得到0xc9cd,预期的结果。

在反射之后应用Init或者Init,您可以使用该表中的CRC-16 / RIELLO进行验证。

增加问题的答案:

A)RefIn与填充位无关。您反映输入字节。但是,在实际计算中,您会反映多项式,它会处理两种反射。

B)是的。

C)是的,XorOut是您的独家或最终结果。检查是ASCII中九个字节“123456789”的CRC。

© www.soinside.com 2019 - 2024. All rights reserved.