CRC-16 / MODBUS :
- CRC寄存器的初始值为 0xFFFF;即16个字节全为1
- CRC-16 / MODBUS的多项式为 A001H(1010 0000 0000 0001B) 'H'表示16进制,'B'表示二进制
计算步骤:
(1). 预置 16 位寄存器为十六进制 0xFFFF,称此寄存器为 CRC 寄存器
(2). 把第一个 8 位数据与 16 位寄存器的低位 相异或,把结果放于 CRC 寄存器
(3). 检测相异或后的 CRC 寄存器的最低位,若最低位为1;则寄存器先右移一位,再与多项式 A001H 进行异或;若最低位为0;则寄存器右移一位,不与多项式A001H异
(4). 重复 步骤(3) ,直到右移 8 次,这样整个 8 位数据全部处理
(5). 重复 步骤(2) ~ 步骤(4) , 进行下一个 8 位数据处理
(6). 最后得到的 CRC 寄存器则为 CRC 码
uint16_t CRC16ModbusByteCalc(const uint8_t *data, uint8_t length) {
uint16_t tmp = 0xFFFF;
uint16_t ret1;
for (int n = 0; n < length; n++) {
tmp = data[n] ^ tmp;
for (int i = 0; i < 8; i++) {
if (tmp & 0x01) {
tmp = tmp >> 1;
tmp = tmp ^ 0xA001;
} else {
tmp = tmp >> 1;
}
}
}
/* CRC校验后的值 */
printf("CRC校验结果为: %X \n",tmp);
/* 如需要:将CRC校验小端输出 */
ret1 = tmp >> 8;
ret1 = ret1 | (tmp << 8);
printf("CRC校验结果小端: %X \n",ret1);
return (tmp);
}
测试
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
uint8_t tmp[6];
tmp[0] = 0x01;
tmp[1] = 0x03;
tmp[2] = 0x61;
tmp[3] = 0x00;
tmp[4] = 0x00;
tmp[5] = 0x02;
// 这个6为tmp的数据长度
int16_t reValue = CRC16ModbusByteCalc(tmp, 6);
printf("reValue :%d \n", reValue);
printf("reValue :%hX \n", reValue);
NSLog(@"reValue :%hX \n", reValue);
}
结果
CRC校验结果为: F7DB
CRC校验结果小端: DBF7
reValue :-2085
reValue :F7DB
CRCTest[6035:91382] reValue :F7DB