Back

生成 Modbus CRC16 校验码

By Ming 四月 11, 2024 Qt

在 Qt 中,如果你需要生成 Modbus CRC16 的校验码,你可以使用以下的方法:

首先,你需要有一个 CRC16 计算函数,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
uint16_t ModbusCRC16(QByteArray senddata)
{
int len=senddata.size();
uint16_t wcrc=0XFFFF;
uint8_t temp;
int i=0,j=0;
for(i=0;i<len;i++)
{
temp=senddata.at(i);
wcrc^=temp;
for(j=0;j<8;j++){
if(wcrc&0X0001){
wcrc>>=1;
wcrc^=0XA001;
}
else
wcrc>>=1;
}
}
temp=wcrc;
return wcrc;
}

这是一个可以计算数据的 CRC16 函数,预设的 16 位 crc 寄存器初值全部为 1。

在使用中,通常我们将一串 16 进制字符串转化为字节流后调用函数,生成 crc 校验码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
QString hexDataString =  head + address + num + sum + hexString1;
qDebug() << hexDataString;
QStringList hexDataList = hexDataString.split(" ");
QByteArray byteArray;

foreach (const QString& hexByte, hexDataList) {
bool ok;
int value = hexByte.toInt(&ok, 16);
if (ok) {
byteArray.append(static_cast<char>(value));
}
}
uint16_t wcrc = ModbusCRC16(byteArray);

QString hexString = QString("%1").arg(wcrc, 4, 16, QLatin1Char('0'));
QString lowByte = hexString.mid(hexString.length() - 2);
QString highByte = hexString.left(2);
if (lowByte.length() < 2) {
lowByte.prepend('0');
}
if (highByte.length() < 2) {
highByte.prepend('0');
}
QString combinedHex = (lowByte + " " + highByte).toUpper();

这段代码首先将十六进制字符串分割为一个列表,然后使用该列表创建一个字节数组。提取生成的 wcrc 的低、高位字节,然后将低、高位字节组合在一起(注意:按照小端方式进行组合,即低字节在前,高字节在后),最后得到校验码字符串。

许可协议

本文由 Ming 原创,采用 CC BY-NC-SA 4.0 协议。转载请注明出处。

PERMALINK

https://iming.eu.org/2024/04/11/qt-modbus-crc16/

Comments