赞
踩
ModBus 协议目的:
报文头(MBAP)(分为6个部分):
帧结构(PDU)(主要是将上面的报文头进行举例)
软件仿真
使用:
Qt 5.13.2的实现,以TCP为例:
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
-
- #include <QMainWindow>
- #include <QModbusTcpClient> // 软件是客户端,PLC是服务端,这个得搞清楚
- namespace Ui {
- class MainWindow;
- }
-
- class MainWindow : public QMainWindow
- {
- Q_OBJECT
-
- public:
- explicit MainWindow(QWidget *parent = nullptr);
- ~MainWindow();
-
- private slots:
- void on_pushButton_clicked();
-
- void on_pushButton_2_clicked();
- void replyData(); //读取异步槽函数
- private:
- Ui::MainWindow *ui;
- QModbusTcpClient *client; // 声明一个客户端实例作为子类成员
- };
-
- #endif // MAINWINDOW_H
- #include "mainwindow.h"
- #include "ui_mainwindow.h"
- #include <QDebug>
- MainWindow::MainWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MainWindow)
- {
- ui->setupUi(this);
- client = new QModbusTcpClient(this);//实例化对象
- client->setConnectionParameter(QModbusDevice::NetworkAddressParameter,"127.0.0.1");// 设置连接信息:服务端IP
- client->setConnectionParameter(QModbusDevice::NetworkPortParameter,502);// 设置连接信息:服务端端口
- client->connectDevice();
- }
-
- MainWindow::~MainWindow()
- {
- if(client->state()==QModbusTcpClient::ConnectedState) //如果设备连接,则要断开
- {
- client->disconnectDevice();
- }
- delete ui;
- }
-
- void MainWindow::on_pushButton_clicked() // 读
- {
- QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,500,2);// 定义数据单元:保持寄存器类型、PLC的开始地址和地址读取数
- QModbusReply* reply = client->sendReadRequest(unit,1); // 参数二为设备号
- if(reply)
- {
- if(!reply->isFinished())
- {
- connect(reply,&QModbusReply::finished,this,&MainWindow::replyData); //异步处理槽函数
- return;
- }
- reply->deleteLater(); // 针对广播消息
- }
- }
-
- void MainWindow::on_pushButton_2_clicked() // 写
- {
- QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,500,1);// 定义数据单元:保持寄存器类型、PLC的开始地址和地址读取数
- unit.setValue(0,ui->lineEdit->text().toUInt()); // 向一个地址写一个值
- // QVector<quint16> data;
- // data<<100<<124;
- // QModbusDataUnit unit(QModbusDataUnit::HoldingRegisters,500,data);
- // unit.setValues(data);//向连续地址写多个值 集合的元素个数需要和unit中的地址读取数保持一致
- QModbusReply* reply = client->sendWriteRequest(unit,1); // 参数二为设备号
- if(reply)
- {
- reply->deleteLater(); // 针对广播消息
- }
- }
-
- void MainWindow::replyData() // 处理读的数据
- {
- QModbusReply* reply = (QModbusReply*)(sender());
- if(reply)
- {
- QModbusDataUnit unit = reply->result(); // 提取reply数据
- reply->deleteLater(); // 释放内存
- if(unit.valueCount()>0)
- {
- QVector<quint16> data = unit.values();
- QString s;
- Q_FOREACH(quint16 i,data)
- {
- s.append(QString::number(i)).append(" "); // 把所有值放到一个字符串中
- }
- ui->lineEdit->setText(s);
- //ui->lineEdit->setText(QString::number(unit.value(0)));
- }
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。