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

相关推荐
FreeTinker11 分钟前
Java文件服务器的技术选型与实现路径:从嵌入式工具到企业级系统
java·服务器·开发语言
2501_9065651212 分钟前
小创 · 智能助手
开发语言·c#
benchmark_cc26 分钟前
1000只ETF的5分钟K线如何批量获取?QuantDash分页策略与高性能Python实践
开发语言·人工智能·爬虫·python·算法·quantdash·量化数据源
Coodor30 分钟前
如何在web浏览器使用js操作CPU卡
开发语言·前端·javascript·cpu卡
我星期八休息42 分钟前
Linux I/O多路转接—epoll
java·linux·运维·服务器·开发语言·jvm·算法
大模型码小白1 小时前
AI 提示词专栏:使用系统指令(System Prompt)实现全局约束
java·大数据·运维·开发语言·人工智能·python·prompt
HugoStudio_SWAN1 小时前
C++ CMD 互动动画:按键触发爆炸效果
开发语言·c++·学习·程序人生
互联网中的一颗神经元1 小时前
10. Large 对象分配:直接路径
开发语言·golang
mayaairi3 小时前
JS BOM完全指南(二):事件轮询、三大尺寸家族与浏览器对象详解
开发语言·javascript·ecmascript