一、CRC(循环冗余校验)
1 CRC16实现流程
XOR = 异或
N = 字节的信息位
POLY = CRC16 多项式计算 = 1010 0000 0000 0001
(生成多项式 = 1 + x2 + x15 + x16)
在CRC16中,发送的第一个字节位低字节
2 CRC16实例推导
3 CRC16代码实现
unsigned short CRC16(unsigned char *auchMsg, unsigned short usDataLen)
{
unsigned short ushCRC = 0xFFFF;
char chLSB = 0; //最低有效位
while (usDataLen--)
{
ushCRC ^= *auchMsg++;
for (int i = 0; i < 8; i++)
{
chLSB = (ushCRC & 0x1); //在右移之前求进位
ushCRC = ushCRC >> 1;
if (1 == chLSB)
{
ushCRC ^= 0xA001;
}
}
}
return ushCRC;
}
怀疑自己写得不好,若有其他更好的实现,请务必留言告诉我。
二、LRC(纵向冗余校验)
1 LRC原理
将报文中的所有字节相加,忽略任何进位,然后将累加值取反加1。
2 LRC代码实现
unsigned char LRC(unsigned char* auchMsg, unsigned short usDataLen)
{
unsigned char uchLRC = 0;
while (usDataLen--)
{
uchLRC += *auchMsg++;
}
return (~uchLRC) + 1;
}
怀疑自己写得不好,若有其他更好的实现,请务必留言告诉我。
三、验证
1 CRC在线计算工具
CRC在线计算工具
这里有个疑问。文档中建议的 POLY 值为 0xA001,而在线工具中的为 0x8005。代码是按照文档流程写的,但是测试结果与工具一致。
两者 POLY 值不一样啊,结果确一致。难道各自算法不同?
2 LRC在线计算工具
LRC在线计算工具
四、参考文档《Modbus协议中文版》
参考内容
2.5.1.2 CRC 校验 第55页
6.2.2 CRC 的生成 第81页
2.5.2.2 LRC 校验 第58页
6.2.1 LRC 的生成 第80页
及网上其他资料(大多不权威)
文档下载地址
Modbus协议中文版
文档没有编辑书签,建议阅读时逐一添加。
就像这样,是我自己编辑的,很简单。
同时,文档中也有一些误导人的地方。请阅读时多思考,多验证。(毕竟是翻译文)