Qt Modbus协议0x00

一、一些概念

1.Modbus由施耐德旗下Modicon在1979年推出,工业现场最通用、免费开放的应用层问答式通信协议。

2.Modbus协议采用主从架构(CS架构)。通信过程中,由主站(客户端)发送指令包,从站(服务端)响应回报,构成一次完整的通信过程;

3.底层物理实现链路:

1)Modbus-RTU: 运行在RS485/RS232串口;

2)Modbus-TCP: 运行在以太网 TCP,默认端口 502;

3)Modbus-ASCII: 串口明文十六进制字符传输。

4.三者上层PDU(协议数据单元,功能码 + 数据部分)完全相同,仅底层帧封装、校验、链路规则不同而已;

5.四类存储寄存器

Modbus把所有设备数据划分成4类独立地址空间:

1)线圈Coils,可读、可写,数据位宽1bit;

2)离散输入Discrete Inputs,只读,数据位宽1bit;

3)输入寄存器Input Registers,只读,数据位宽16bit无符号整型;

4)保持寄存器Holding Registers,可读、可写,数据位宽16bit无符号整型。

二、 Modbus-RTU报文帧结构(串口二进制)

从站地址(1字节)] + PDU协议数据单元 + CRC16校验(2字节)

三、测试

整个测试流程:Qt程序是主站、SSCOM软件为从站。主站向从站发送Modbus协议帧报文,从站收到后分析。

1.例如 发送报文格式(查询命令) 01 03 00 00 00 02 C4 0B

第1字节01: 从站 ID = 1;

第2字节03: 功能码,读取保持寄存器;

第3、4字节00 00: 起始寄存器地址0;

第5、6字节00 02: 读取寄存器数量2个寄存器;

第7字节C4: CRC校验低字节;

第8字节0B: CRC校验高字节;

2.源码

main.cpp

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QtSerialBus/QModbusRtuSerialMaster>
#include <QtSerialBus/QModbusReply>
#include <QtSerialPort/QSerialPort>
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QModbusRtuSerialMaster master;
    // 绑定虚拟串口COM1
#if 1
    master.setConnectionParameter(QModbusDevice::SerialPortNameParameter, "COM1");
    master.setConnectionParameter(QModbusDevice::SerialBaudRateParameter, QSerialPort::Baud115200);
    master.setConnectionParameter(QModbusDevice::SerialDataBitsParameter, QSerialPort::Data8);
    master.setConnectionParameter(QModbusDevice::SerialStopBitsParameter, QSerialPort::OneStop);
    master.setConnectionParameter(QModbusDevice::SerialParityParameter, QSerialPort::NoParity);
    if (!master.connectDevice())
    {
        qDebug()<<"串口打开失败:"<<master.errorString();
        return -1;
    }
    qDebug()<<"RTU主站启动成功,准备发送报文";
    // 1.定义读取单元:保持寄存器、起始地址0、读取2个
    QModbusDataUnit readItem(QModbusDataUnit::HoldingRegisters, 0, 2);
    // 2.发送请求,从站ID = 1
    QModbusReply *reply = master.sendReadRequest(readItem, 1);
    // 3.必须先判空,再绑定finished信号,杜绝空指针connect报错
    if (reply)
    {
        QObject::connect(reply, &QModbusReply::finished, [reply]()
        {
            // 读取应答数据
            if(!reply->isFinished())
                return;
            const QModbusDataUnit res = reply->result();
            qDebug() << "读到寄存器数值:" << res.values();
            reply->deleteLater();
        });
    }
    else
    {
        qDebug() << "请求发送失败:" << master.errorString();
    }
#endif
    return a.exec();
}

3.程序运行结果

4.仿真环境搭建请参考<Qt实现串口通信及使用VSPD模拟调试>

四、开发工具及Qt版本

开发工具:Qt Creator 4.10.2

Qt版本:Qt_5_12_6

相关推荐
yushikong1 小时前
关于rust开发ch32x033f8p6的一些记录
开发语言·后端·rust
吴声子夜歌1 小时前
正则表达式——环视
开发语言·正则表达式
Zenova EdgeOS2 小时前
C++ 工业边缘 Qt 桌面应用实战:从 QWidget 到模型视图、网络与多线程
网络·c++·qt
福大大架构师每日一题2 小时前
agno v2.8.7 发布:顾问模型、精准路线、调度能力全面升级,10项关键修复一次看懂
java·开发语言·数据库
老洋葱Mr_Onion2 小时前
【C++】CSP-J复赛dp问题(含模板题)
开发语言·c++
李永奉10 小时前
C语言-嵌入式开发C语言常用预处理指令合集
c语言·开发语言
上海安当技术10 小时前
敏感数据怎么防拖库?信封加密(DEK+KEK 二层密钥)架构设计与 Java 实战
java·开发语言·python
我是唐青枫11 小时前
Java JCommander 实战详解:用注解解析命令行参数
java·开发语言
大鹏说大话11 小时前
C++ 内存布局详解:类、虚函数、虚表底层原理
java·开发语言