Qt modbus TCP协议应用

Qt modbus TCP协议应用

协议简介

Modbus由MODICON公司(现施耐德公司)于1979年开发,是一种工业现场总线协议标准。主要分为了RTU,ASCII,TCP三种协议类型。本文我们只探讨Qt框架下modbusTCP的应用。 modbusTcp协议采用master/slave模型。在modbus总线中是以"一主多从"关系存在的。通讯方式是主站发出请求(广播或者单播),从站收到请求后应答。

报文分析

请求 :19 15 00 00 00 06 01 03 05 4A 00 01
应答:19 15 00 00 00 05 01 03 02 11 22
	请求:
		19 15 为报文标识符,一般每次通信加1来表示区别不同报文
		00 00 表示modbusTCP协议
		00 06 表示后面的数据长度
		01 从站号
		03 功能码。
		05 4A 读取数据的起始地址
		00 01 读几位地址(读连续的地址)
		
	应答:
		19 15 为报文标识符
		00 00 表示modbusTCP协议
		00 05 表示后面的数据长度
		01 从站号
		03 功能码
		02 表示读到的数据长度
		11 22 表示读到的数据

不同于RTU协议,不需要进行CRC校验

功能码 含义
01 读线圈
05 写单个线圈
0F 写多个线圈
02 读离散量输入
04 读输入寄存器
03 读保持寄存器
06 写单个保持寄存器
10 写多个保持寄存器

modbusTCP master实现

一般来说上位机作为客户端和主站进行连接

  1. 在pro文件中加入serialbus模块
QT += serialport serialbus
  1. 包含头文件
#include  //modbusTCP客户端
#include   //数据容器
#include  
  1. tcp连接
//创建套接字
QModbusTcpClient* m_MyClient;
//判断是否已连接
if(m_Myclient->state() != QModbusDevice::ConnectedState)
    {
    	//连接ip和端口 ip为QStirng类型,port为uint类型
        m_Myclient->setConnectionParameter(QModbusDevice::NetworkAddressParameter,IP_address);
        m_Myclient->setConnectionParameter(QModbusDevice::NetworkPortParameter,Port);
        //连接超时和重连次数
        m_Myclient->setTimeout(2000);
        m_Myclient->setNumberOfRetries(3);
        //连接设备
        m_Myclient->connectDevice();
    }
  1. 读保持寄存器寄存器和线圈
//参数:读线圈 地址 地址长度
QModbusDataUnit ReadUnit(QModbusDataUnit::QModbusDataUnit::Coils,510,1);
//参数:读寄存器 地址 地址长度
QModbusDataUnit ReadUnit(QModbusDataUnit::HoldingRegisters,510,22);

    if (auto *reply = m_Myclient->sendReadRequest(ReadUnit, 1))     //1是从站号(不设置默认1)
    {
        if (!reply->isFinished())
        {
            connect(reply, SIGNAL(finished()),this,SLOT(readReady()));
        }
        else
        {
            delete reply;
        }
    }
void ModbusTcpClient::readReady()
{
    QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
    if (!reply){
        return ;
    }
    if (reply->error() == QModbusDevice::NoError)
    {
    	//接收数据
        const QModbusDataUnit unit = reply->result();

        for(int i=0; i< unit.valueCount();i++ )

        {
        
      		//解析数据
            quint16 data =unit.value(i);
        }
    }
       
    reply->deleteLater();
}

5.写线圈和保持寄存器

//参数:写线圈 地址 地址长度
QModbusDataUnit WriteUnit(QModbusDataUnit::QModbusDataUnit::Coils,510,1);
//参数:写寄存器 地址 地址长度
QModbusDataUnit WriteUnit(QModbusDataUnit::HoldingRegisters,510,22);
//设置发送要数据
writeUnit.setValue(i,data);//i 第几个数据 data数据 qunit16类型
//也可以
writeUnit.setValues(QVector<qint16>);
//发送数据
if (auto *reply = m_boxclient->sendWriteRequest(writeUnit, 1))
    {
        if (!reply->isFinished())
        {
            connect(reply,SIGNAL(finished()),this,SLOT(slot_WriteData()));
        }
        else
        {
            reply->deleteLater();
        }
    }
void ModbusTcpClient::slot_WriteData()
{
    QModbusReply *reply = qobject_cast<QModbusReply *>(sender());
    if (!reply){
        return ;
    }
    if (reply->error() == QModbusDevice::NoError)
    {
    	//写入成功
    } 
    reply->deleteLater();
}

你可能感兴趣的:(qt,tcp/ip,开发语言,c++,网络)