Sfoglia il codice sorgente

封装了modbus生成报文的代码

master
鹏鹏 李 2 settimane fa
parent
commit
0f59612c5d
6 ha cambiato i file con 246 aggiunte e 256 eliminazioni
  1. +1
    -1
      modbus.pro.user
  2. +0
    -54
      mymodbus.cpp
  3. +0
    -3
      mymodbus.h
  4. +18
    -9
      widget.cpp
  5. +4
    -0
      widget.h
  6. +223
    -189
      widget.ui

+ 1
- 1
modbus.pro.user Vedi File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.0.3, 2025-07-26T12:31:36. -->
<!-- Written by QtCreator 4.0.3, 2025-07-26T17:06:45. -->
<qtcreator>
<data>
<variable>EnvironmentId</variable>


+ 0
- 54
mymodbus.cpp Vedi File

@@ -107,20 +107,6 @@ int MyModbus::ErrorCheck()
}
}

int MyModbus::ErrorCheck(QByteArray rev)
{
if ((rev.at(1) & 0x80) == 0x80)
{
// MODBUS异常响应结构:地址 | 功能码+0x80 | 异常码 | CRC
quint8 exCode = rev.at(2);
return exCode;
}
else
{
return 0;
}
}

QVector<bool> MyModbus::AnalReadCoil()
{
quint8 byteCount = static_cast<quint8>(receive[2]);
@@ -158,43 +144,3 @@ QVector<quint16> MyModbus::AnalReadReg()

return registers;
}

QVector<bool> MyModbus::AnalReadCoil(QByteArray rev)
{
quint8 byteCount = static_cast<quint8>(rev[2]);
QVector<bool> coil;

for (int byteIndex = 0; byteIndex < byteCount; byteIndex++)
{
quint8 byteValue = static_cast<quint8>(rev[3 + byteIndex]);

// 解析每个字节的8个位
for (int bitIndex = 0; bitIndex < 8; bitIndex++)
{
int coilIndex = byteIndex * 8 + bitIndex;
if (coilIndex < length)
{
bool state = byteValue & (1 << bitIndex);
coil.append(state);
}
}
}
return coil;
}

QVector<quint16> MyModbus::AnalReadReg(QByteArray rev)
{
int byteCount = rev.at(2);
QByteArray data = rev.mid(3, byteCount);

QVector<quint16> registers;
for (int i = 0; i < data.size(); i += 2)
{
quint16 value = (static_cast<quint8>(data[i]) << 8) | static_cast<quint8>(data[i+1]);
registers.append(value);
}

return registers;
}



+ 0
- 3
mymodbus.h Vedi File

@@ -25,11 +25,8 @@ public:
QByteArray SendCommand();
QByteArray Receive(const QByteArray &revMessage);
int ErrorCheck();
int ErrorCheck(QByteArray rev);
QVector<bool> AnalReadCoil();
QVector<quint16> AnalReadReg();
QVector<bool> AnalReadCoil(QByteArray rev);
QVector<quint16> AnalReadReg(QByteArray rev);
};

#endif // MYMODBUS_H

+ 18
- 9
widget.cpp Vedi File

@@ -20,8 +20,10 @@ Widget::Widget(QWidget *parent) :
ui->setupUi(this);
serialPort = new QSerialPort(this);
modbus = new MyModbus();
recvTimer = new QTimer(this);

connect(serialPort,&QSerialPort::readyRead,this,&Widget::on_SerialData_ReadyToRead);
connect(serialPort, &QSerialPort::readyRead, this, &Widget::onReadyRead);
connect(recvTimer, &QTimer::timeout, this, &Widget::on_SerialData_ReadyToRead);
QObject::connect(&timer, &QTimer::timeout, [&]{
if (comCount < 3)
{
@@ -155,11 +157,10 @@ void Widget::on_pushWrite_clicked()
ui->pushWrite->setEnabled(0);

comCount = 0;
Sleep(200);
Sleep(100);
timer.isActive();
timer.start(1000); // 1 s 后触发超时

qDebug() << "SenOk" <<sendData;
break;
}

@@ -200,7 +201,7 @@ void Widget::on_pushWrite_clicked()
ui->pushWrite->setEnabled(0);

comCount = 0;
Sleep(200);
Sleep(100);
timer.isActive();
timer.start(1000); // 1 s 后触发超时

@@ -219,7 +220,9 @@ void Widget::on_pushWrite_clicked()
//处理回复报文
void Widget::on_SerialData_ReadyToRead()
{
QByteArray revMessage = modbus->Receive(serialPort->readAll());
QByteArray revMessage = recvBuffer;
recvBuffer.clear();
revMessage = modbus->Receive(revMessage);
if (!revMessage.isEmpty())
{
ui->btn_read->setEnabled(1);
@@ -235,7 +238,7 @@ void Widget::on_SerialData_ReadyToRead()
ui->textEdit_2->append("接收报文"+hexData);

qDebug() << "接收成功";
int exCode = modbus->ErrorCheck(revMessage);
int exCode = modbus->ErrorCheck();
if (exCode)
{
QString errorMsg;
@@ -261,7 +264,7 @@ void Widget::on_SerialData_ReadyToRead()
//解析读线圈的返回报文
case 0:
{
QVector<bool> coil = modbus->AnalReadCoil(revMessage);
QVector<bool> coil = modbus->AnalReadCoil();

ui->textEdit->append("线圈状态:");
for (int i = 0; i < coil.size(); i++)
@@ -275,7 +278,7 @@ void Widget::on_SerialData_ReadyToRead()
//解析读寄存器的返回报文
case 1:
{
QVector<quint16> registers = modbus->AnalReadReg(revMessage);
QVector<quint16> registers = modbus->AnalReadReg();

ui->textEdit->append("寄存器的值:");
for (int i = 0; i < registers.size(); i++)
@@ -322,7 +325,7 @@ void Widget::on_btn_read_clicked()
ui->pushWrite->setEnabled(0);

comCount = 0;
Sleep(200);
Sleep(100);
timer.isActive();
timer.start(1000); // 1 s 后触发超时
}
@@ -383,3 +386,9 @@ void Widget::on_pushButton_3_clicked()
{
ui->textEdit_2->clear();
}

void Widget::onReadyRead()
{
recvBuffer.append(serialPort->readAll());
recvTimer->start(50); // 50ms 内无新数据即认为接收完成
}

+ 4
- 0
widget.h Vedi File

@@ -33,12 +33,16 @@ private slots:

void on_pushButton_3_clicked();

void onReadyRead();

private:
Ui::Widget *ui;
QSerialPort *serialPort;
MyModbus *modbus;
QTimer timer;
int comCount;
QByteArray recvBuffer;
QTimer *recvTimer;
};

#endif // WIDGET_H

+ 223
- 189
widget.ui Vedi File

@@ -26,7 +26,7 @@
<widget class="QPushButton" name="pushWrite">
<property name="geometry">
<rect>
<x>350</x>
<x>340</x>
<y>470</y>
<width>93</width>
<height>28</height>
@@ -40,16 +40,19 @@
<property name="geometry">
<rect>
<x>40</x>
<y>250</y>
<y>280</y>
<width>251</width>
<height>211</height>
<height>191</height>
</rect>
</property>
<property name="readOnly">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="btn_read">
<property name="geometry">
<rect>
<x>110</x>
<x>200</x>
<y>470</y>
<width>93</width>
<height>28</height>
@@ -59,12 +62,220 @@
<string>读</string>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<widget class="QLabel" name="label_13">
<property name="geometry">
<rect>
<x>340</x>
<y>330</y>
<width>311</width>
<height>101</height>
</rect>
</property>
<property name="text">
<string>写线圈时,使用1、0代表线圈的开关状态,
从左到右依次输入每个线圈的开关;
写寄存器时要写入所有寄存器的16进制数值,
相邻寄存器的值之间用英文&quot;,&quot;分离。</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>40</x>
<y>10</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>串口配置</string>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>40</x>
<y>100</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>从站配置</string>
</property>
</widget>
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>40</x>
<y>115</y>
<width>672</width>
<y>150</y>
<width>72</width>
<height>15</height>
</rect>
</property>
<property name="text">
<string>状态通知</string>
</property>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>42</x>
<y>32</y>
<width>406</width>
<height>58</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>串口</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="2">
<widget class="QComboBox" name="comboBox_serialNum"/>
</item>
<item row="0" column="3" colspan="2">
<widget class="QLabel" name="label_2">
<property name="text">
<string>波特率</string>
</property>
</widget>
</item>
<item row="0" column="5" colspan="2">
<widget class="QComboBox" name="comboBox_baudRate">
<item>
<property name="text">
<string>1200</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
</widget>
</item>
<item row="0" column="7">
<widget class="QLabel" name="label_3">
<property name="text">
<string>数据位</string>
</property>
</widget>
</item>
<item row="0" column="8">
<widget class="QComboBox" name="comboBox_dataBit">
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>NONE</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QLabel" name="label_7">
<property name="text">
<string>校验位</string>
</property>
</widget>
</item>
<item row="1" column="2" colspan="2">
<widget class="QComboBox" name="comboBox_xiaoyan">
<item>
<property name="text">
<string>无校验(N)</string>
</property>
</item>
<item>
<property name="text">
<string>奇校验(O)</string>
</property>
</item>
<item>
<property name="text">
<string>偶校验(E)</string>
</property>
</item>
</widget>
</item>
<item row="1" column="4" colspan="2">
<widget class="QLabel" name="label_8">
<property name="text">
<string>停止位</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QComboBox" name="comboBox_stopBit">
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget>
</item>
<item row="1" column="7" colspan="2">
<widget class="QPushButton" name="btnConnect">
<property name="text">
<string>连接</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>41</x>
<y>116</y>
<width>687</width>
<height>23</height>
</rect>
</property>
@@ -186,198 +397,21 @@
</item>
</layout>
</widget>
<widget class="QLabel" name="label_13">
<property name="geometry">
<rect>
<x>340</x>
<y>330</y>
<width>311</width>
<height>101</height>
</rect>
</property>
<property name="text">
<string>写线圈时,使用1、0代表线圈的开关状态,
从左到右依次输入每个线圈的开关;
写寄存器时要写入所有寄存器的16进制数值,
相邻寄存器的值之间用英文&quot;,&quot;分离。</string>
</property>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>40</x>
<y>30</y>
<width>378</width>
<height>62</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>串口</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_serialNum"/>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>波特率</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_baudRate">
<item>
<property name="text">
<string>1200</string>
</property>
</item>
<item>
<property name="text">
<string>2400</string>
</property>
</item>
<item>
<property name="text">
<string>4800</string>
</property>
</item>
<item>
<property name="text">
<string>9600</string>
</property>
</item>
<item>
<property name="text">
<string>19200</string>
</property>
</item>
<item>
<property name="text">
<string>38400</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>数据位</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_dataBit">
<item>
<property name="text">
<string>5</string>
</property>
</item>
<item>
<property name="text">
<string>6</string>
</property>
</item>
<item>
<property name="text">
<string>7</string>
</property>
</item>
<item>
<property name="text">
<string>8</string>
</property>
</item>
<item>
<property name="text">
<string>NONE</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_7">
<property name="text">
<string>校验位</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_xiaoyan">
<item>
<property name="text">
<string>无校验(N)</string>
</property>
</item>
<item>
<property name="text">
<string>奇校验(O)</string>
</property>
</item>
<item>
<property name="text">
<string>偶校验(E)</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string>停止位</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_stopBit">
<item>
<property name="text">
<string>1</string>
</property>
</item>
<item>
<property name="text">
<string>2</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnConnect">
<property name="text">
<string>连接</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="">
<property name="geometry">
<rect>
<x>40</x>
<y>150</y>
<width>671</width>
<x>41</x>
<y>164</y>
<width>691</width>
<height>91</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTextEdit" name="textEdit_2"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">


Caricamento…
Annulla
Salva