因项目需求研究了一下Modbus协议,用C++实现了简单的Modbus协议报文组织
Modbus协议允许在TCP连接下实现通信,使用ws2_32这个socket支持库,写法是普遍的网络编程TCP客户端连接写法
在Windows环境下,C++的TCP连接发起部分代码:作为主机(客户端),主动连接从机(服务端)
WORD version = MAKEWORD(2, 2);
WSADATA data;
if (SOCKET_ERROR == WSAStartup(version, &data))
{
_csock = INVALID_SOCKET;
qDebug("初始化Winsock环境失败");
return false;
}
_csock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_csock == INVALID_SOCKET) {
return false;
}
sockaddr_in _csin = {};
_csin.sin_family = AF_INET;
_csin.sin_port = htons(SLAVE_PORT);
_csin.sin_addr.S_un.S_addr = inet_addr(SLAVE_ADDRESS);
if (SOCKET_ERROR == connect(_csock, reinterpret_cast<sockaddr*>(&_csin), sizeof(_csin)))
{
_csock = INVALID_SOCKET;
qDebug("connect error");
return false;
}
return true;
TCP连接完成后,发送的数据包格式,即为ModbusTCP的协议格式,以下是协议完整格式:
Modbus协议头
事务处理标识 协议标识 长度 单元标识符
2字节 2字节 2字节 1字节
接下来就是Modbus协议主体
功能码 数据
所以举个例子:
//组织二进制Modbus协议报文
unsigned char sendBuf[21];//发送缓存
short temps = _seq_modbus++;//类似于TCP的seq序列号,让其自增即可
unsigned char* temp = reinterpret_cast<unsigned char*>(&temps);
//协议头
sendBuf[0] = *(temp+1);//前两位为事务处理标识,2个字节的序列号
sendBuf[1] = *(temp);
sendBuf[2] = 0;//协议标识,两个字节,0000即为Modbus TCP协议
sendBuf[3] = 0;
sendBuf[4] = 0;//长度字段(前半部分字节)
sendBuf[5] = 15;//随后字节数
sendBuf[6] = 0x01;//单元标志,定义连接目的节点的其他设备(这个设备是1号,所以是0x01)
//以上是Modbus协议头部分
//协议体
sendBuf[7] = 0x10;//Modbus功能码 ,这里是 写多个保持寄存器 操作
sendBuf[8] = 0x01; //写寄存器起始地址高字节
sendBuf[9] = 0x00; //写寄存器起始地址低字节(所以这里是往0x0100地址写寄存器)
sendBuf[10] = 0x00; //写寄存器数量高字节
sendBuf[11] = 0x04; //写寄存器数量低字节
sendBuf[12] = 0x08; //数据长度
//写四个值到报文中
temps = _offset.x;
sendBuf[13] = *(temp+1);
sendBuf[14] = *(temp);
temps = _offset.y;
sendBuf[15] = *(temp+1);
sendBuf[16] = *(temp);
temps = _offset.x + 50;
sendBuf[17] = *(temp+1);
sendBuf[18] = *(temp);
temps = 50 - _offset.y;
sendBuf[19] = *(temp+1);
sendBuf[20] = *(temp);
// ----------------
//最后发送出去
send(_csock, reinterpret_cast<char*>(sendBuf), sizeof(sendBuf), 0);//发送报文
大家看懂这个例子了吗,其实这个例子就是“使用ModbusTCP协议写4个字节的数据到0x0100 - 0x0103这四个寄存器中”
其实Modbus协议本身功能很多,这里只举例了一个写“多个寄存器”的操作,其实还有其他操作,具体的协议格式可以去官网或者其他地方查询。
记之备忘,希望有帮助到需要的同学