微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

了解 Modbus RTU CRC

如何解决了解 Modbus RTU CRC

现在正在研究Modbus RTU和Modbus RTU的CRC16。

关于校验CRC的源代码,在High-Order Byte Table和Low-Order Byte Table中,不知道这个值是怎么生成的?在 Modbus 协议的文档中,这样解释:“一个数组包含 16 位 CRC 字段的高字节的所有 256 个可能的 CRC 值,另一个数组包含低字节的所有值。”>

我想怎么取这个值?帮帮我,非常感谢。

Low-Order Byte Table
High-Order Byte Table

解决方法

该 pdf 文件中包含对面向位的 CRC 实现的描述,但它可能需要进行一些清理:

1. Load a 16–bit register with FFFF hex (all 1’s). Call this the CRC register.

2. Exclusive OR the first 8–bit byte of the message with the low–order byte
   of the 16–bit CRC register,putting the result in the CRC register.

3. Save the LSB for step 4. Shift the CRC register one bit to the right 
   (toward the LSB),zero–filling the MSB.

4. (If the saved LSB is 0): Continue to step 5.
   (If the saved LSB is 1): Exclusive OR the CRC register with the polynomial
   value 0xA001 (1010 0000 0000 0001).

5. Repeat Steps 3 and 4 until 8 shifts have been performed.
   When this is done,a complete 8–bit byte will have been processed.

6. Repeat Steps 2 through 5 for the next 8–bit byte of the message.
   Continue doing this until all bytes have been processed.

7. The final content of the CRC register is the CRC value.

8. When the CRC is placed into the message,store the low order byte first,and the
   high order byte next.   (msg ...,crclo,crchi).

https://modbus.org/docs/Modbus_over_serial_line_V1_02.pdf

请注意,在使用表格的示例代码中,CRC 的字节被交换,因此被描述为“低字节”的实际上是“高字节”,反之亦然。这样做是为了允许将 CRC 作为 16 位值存储在大端处理器上的消息中。在小端处理器(例如 PC 上的 X86)上不需要交换字节,因为小端存储将交换字节(存储低字节、高字节)。

生成表格的示例代码:

#include <stdio.h>

typedef unsigned char    uint8_t;
typedef unsigned short  uint16_t;

uint8_t crclo[256];
uint8_t crchi[256];

    void gentbls(void)
    {
    uint16_t crc;
    uint16_t b;
    uint16_t c;
    uint16_t i;
        for(c = 0; c < 0x100; c++){
            crc = c;
            for(i = 0; i < 8; i++){
                b = crc & 1;
                crc >>= 1;
                if(b != 0) crc ^= 0xa001;
            }
            crchi[c] = crc & 0xff;
            crclo[c] = crc >> 8;
        }
    }

int main()
{
int i,j;
    gentbls();
    for(j = 0; j < 17; j++){
        for(i = 0; i < 15; i++)
            printf("%02x ",crclo[j*15+i]);
        printf("\n");
    }
    printf("%02x\n\n",crclo[255]);
    for(j = 0; j < 17; j++){
        for(i = 0; i < 15; i++)
            printf("%02x ",crchi[j*15+i]);
        printf("\n");
    }
    printf("%02x\n",crchi[255]);
    return 0;
}

输出:

00 c0 c1 01 c3 03 02 c2 c6 06 07 c7 05 c5 c4 
04 cc 0c 0d cd 0f cf ce 0e 0a ca cb 0b c9 09 
08 c8 d8 18 19 d9 1b db da 1a 1e de df 1f dd 
1d 1c dc 14 d4 d5 15 d7 17 16 d6 d2 12 13 d3 
11 d1 d0 10 f0 30 31 f1 33 f3 f2 32 36 f6 f7 
37 f5 35 34 f4 3c fc fd 3d ff 3f 3e fe fa 3a 
3b fb 39 f9 f8 38 28 e8 e9 29 eb 2b 2a ea ee 
2e 2f ef 2d ed ec 2c e4 24 25 e5 27 e7 e6 26 
22 e2 e3 23 e1 21 20 e0 a0 60 61 a1 63 a3 a2 
62 66 a6 a7 67 a5 65 64 a4 6c ac ad 6d af 6f 
6e ae aa 6a 6b ab 69 a9 a8 68 78 b8 b9 79 bb 
7b 7a ba be 7e 7f bf 7d bd bc 7c b4 74 75 b5 
77 b7 b6 76 72 b2 b3 73 b1 71 70 b0 50 90 91 
51 93 53 52 92 96 56 57 97 55 95 94 54 9c 5c 
5d 9d 5f 9f 9e 5e 5a 9a 9b 5b 99 59 58 98 88 
48 49 89 4b 8b 8a 4a 4e 8e 8f 4f 8d 4d 4c 8c 
44 84 85 45 87 47 46 86 82 42 43 83 41 81 80 
40

00 c1 81 40 01 c0 80 41 01 c0 80 41 00 c1 81 
40 01 c0 80 41 00 c1 81 40 00 c1 81 40 01 c0 
80 41 01 c0 80 41 00 c1 81 40 00 c1 81 40 01 
c0 80 41 00 c1 81 40 01 c0 80 41 01 c0 80 41 
00 c1 81 40 01 c0 80 41 00 c1 81 40 00 c1 81 
40 01 c0 80 41 00 c1 81 40 01 c0 80 41 01 c0 
80 41 00 c1 81 40 00 c1 81 40 01 c0 80 41 01 
c0 80 41 00 c1 81 40 01 c0 80 41 00 c1 81 40 
00 c1 81 40 01 c0 80 41 01 c0 80 41 00 c1 81 
40 00 c1 81 40 01 c0 80 41 00 c1 81 40 01 c0 
80 41 01 c0 80 41 00 c1 81 40 00 c1 81 40 01 
c0 80 41 01 c0 80 41 00 c1 81 40 01 c0 80 41 
00 c1 81 40 00 c1 81 40 01 c0 80 41 00 c1 81 
40 01 c0 80 41 01 c0 80 41 00 c1 81 40 01 c0 
80 41 00 c1 81 40 00 c1 81 40 01 c0 80 41 01 
c0 80 41 00 c1 81 40 00 c1 81 40 01 c0 80 41 
00 c1 81 40 01 c0 80 41 01 c0 80 41 00 c1 81 
40

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。