首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >了解Modbus RTU CRC

了解Modbus RTU CRC
EN

Stack Overflow用户
提问于 2021-01-15 18:40:37
回答 1查看 225关注 0票数 0

接下来对Modbus RTU和Modbus RTU的CRC16进行了研究。

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

我想知道如何取这个值?帮帮我,非常感谢。

Low-Order Byte Table

High-Order Byte Table

EN

回答 1

Stack Overflow用户

发布于 2021-01-16 00:26:01

在该pdf文件中包含了CRC的面向比特实现的描述,但它可能需要一些清理:

代码语言:javascript
复制
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 )上不需要交换字节,因为小端存储将交换字节(存储低字节、高字节)。

生成表的示例代码:

代码语言:javascript
复制
#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;
}

输出:

代码语言:javascript
复制
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
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65734589

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档