接下来对Modbus RTU和Modbus RTU的CRC16进行了研究。
关于源码校验CRC,在高位字节表和低位字节表中,不知道这个值是怎么产生的?在Modbus协议的文件中,这样解释:“一个数组包含16位CRC字段的高位字节的所有256个可能的CRC值,另一个数组包含所有低位字节的值。”
我想知道如何取这个值?帮帮我,非常感谢。
发布于 2021-01-16 00:26:01
在该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
40https://stackoverflow.com/questions/65734589
复制相似问题