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 <QModbusTcpClient> //modbusTCP客户端
#include <QModbusDataUnit>  //数据容器
#include <QModbusReply> 
  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();
}
  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值