iOS CRC16 MODBUS 校验

CRC-16 / MODBUS :
  1. CRC寄存器的初始值为 0xFFFF;即16个字节全为1
  2. 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 

你可能感兴趣的:(iOS CRC16 MODBUS 校验)