CRC循环冗余校验码计算器:http://www.ip33.com/crc.html
C++和QT实现的CRC-16/MODBUS的代码:
#include "mainwindow.h" #include <QApplication> #include <QByteArray> #include <QDebug> #include <string> #include <stdio.h> uint16_t MODBUS_crc16(uint8_t *ptr, uint16_t len) { unsigned char i; unsigned short crc = 0xFFFF; if (len == 0) { len = 1; } while (len--) { crc ^= *ptr; for (i = 0; i<8; i++){ if (crc & 1) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } ptr++; } return(crc); } int main(int argc, char *argv[]) { QApplication a(argc, argv); QByteArray ba; //0~18为校验数据,19~20为低校验位和高校验位 ba.resize(21); ba[0] = \'\x09\'; ba[1] = \'\x03\'; ba[2] = \'\x10\'; ba[3] = \'\x00\'; ba[4] = \'\x00\'; ba[5] = \'\x00\'; ba[6] = \'\x00\'; ba[7] = \'\x00\'; ba[8] = \'\x00\'; ba[9] = \'\x00\'; ba[10] = \'\x00\'; ba[11] = \'\x00\'; ba[12] = \'\x00\'; ba[13] = \'\x00\'; ba[14] = \'\x00\'; ba[15] = \'\x00\'; ba[16] = \'\x00\'; ba[17] = \'\x00\'; ba[18] = \'\x00\'; ba[19] = \'\x06\'; ba[20] = \'\x38\'; //将低校验位和高校验位交换位置 QByteArray crc_real_tmp; crc_real_tmp.append(ba[ba.size() - 1]); crc_real_tmp.append(ba[ba.size() - 2]); bool ok; uint16_t crc_real = crc_real_tmp.toHex().toInt(&ok,16); uint8_t data [19]; memcpy(&data, ba.mid(0,19), 19); uint16_t crc_res = MODBUS_crc16(data, 19); if(crc_res == crc_real) { qDebug()<<"true"; }else { qDebug()<<"false"; } return 0; }