项目描述:
使用qt来进行串口ModeBus的相关通信。
网上查找相关的资料有ModeBus的相关的库。有第三方库,也有Qt自己的库。
但是ModeBus说到底只是一种协议,本质还是串口通信。所以为了方便自己日后修改代码,自己写协议的解析。
简单介绍:
我使用的是Modbus RTU(Remote Terminal Unit 远程终端单元)
这种方式常采用RS-485做为物理层,一般利用芯片的串口实现数据报文的收发,报文数据采用二进制数据进行通信。
Modebus相关的协议结构:
例如:01 03 02 03 E8 B8 FA
01:地址
03 02:功能码
03 E8:数据
B8 FA:crc校验
整体的结构相对简单,在工程运用上的命令也不会很长。这样解码的难点就在crc校验上了。
校验原理就不细说了。经过上网查找相关资料,以下是自己感觉比较好的crc校验的代码。
输入:命令和命令长度
输出:一个字符类型的CRC的值
// 计算crc校验值
QString MainWindow::CRC16_2(uchar *buf, int len) {unsigned short crc = 0xFFFF;for (int pos = 0; pos < len; pos++) {crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crcfor (int i = 8; i != 0; i--) { // Loop over each bitif ((crc & 0x0001) != 0) { // If the LSB is setcrc >>= 1; // Shift right and XOR 0xA001crc ^= 0xA001;} else { // Else LSB is not setcrc >>= 1; // Just shift right}}}//高低字节转换crc = ((crc & 0x00ff) << 8) | ((crc & 0xff00) >> 8);uchar high = (crc >> 8) & 0x000ff;uchar low = crc & 0xFF;QString str = QString("%1%2").arg(high, 2, 16, QLatin1Char('0')).arg(low, 2, 16, QLatin1Char('0'));return str;
}