CRC校验
CRC在嵌入式开发中用得非常频繁,但仔细想想,我们很少真正去写它。要么抄个查表法,要么调个现成函数,代码靠Ctrl+C/V,调通就再也不动。
可一旦被问起原理,我却讲不明白。多项式为什么是那个数?初始值为什么是0xFFFF?查表法到底在查什么?
1. CRC
CRC(Cyclic Redundancy Check,循环冗余校验) 是一种根据数据产生固定长度校验码的算法,主要用于检测数据传输或存储过程中的偶然错误。
优点:计算开销小,只需要异或和移位。纠错能力强。结果确定。 缺点:无法纠错。校验码位数限值,数据较长时必然会出现碰撞(校验码重复)。
2. MODBUS CRC-16
MODBUS CRC-16,这是我常用的CRC规格,MODBUS官方指定使用CRC-16-IBM多项式
- 多项式:0x8005,实际为
x^16 + x^15 + x^2 + 1,LSB优先; - 初始值:0xFFFF;
简单来说:
- 发送方:数据 / 固定多项式 → 得到余数(= CRC),附在数据后面发出去;
- 接收方:收到数据 / 同一个固定多项式 → 求余数;
- 余数为0 → 数据正确;
- 余数非0 → 有错误。
假设要计算0x02, 0x07 这两个数据的MODBUS CRC-16
- 初始CRC寄存器 = 0xFFFF 1.
举个栗子。