Browse Source

修改了一部分注释

master
鹏鹏 李 2 weeks ago
parent
commit
8253fee023
4 changed files with 62 additions and 28 deletions
  1. +1
    -1
      modbus.pro.user
  2. +2
    -2
      serialcommunicator.cpp
  3. +59
    -20
      widget.cpp
  4. +0
    -5
      widget.ui

+ 1
- 1
modbus.pro.user View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject>
<!-- Written by QtCreator 4.0.3, 2025-07-29T09:40:16. -->
<!-- Written by QtCreator 4.0.3, 2025-07-29T20:12:44. -->
<qtcreator> <qtcreator>
<data> <data>
<variable>EnvironmentId</variable> <variable>EnvironmentId</variable>


+ 2
- 2
serialcommunicator.cpp View File

@@ -1,5 +1,5 @@
/******************************* /*******************************
* Copyright (C) 2023-, XINJE Electronic Co., Ltd.
* Copyright (C) 2025.
* *
* File Name: serialcommunicator.cpp * File Name: serialcommunicator.cpp
* Description: 串口通信管理类实现文件 * Description: 串口通信管理类实现文件
@@ -238,9 +238,9 @@ void SerialCommunicator::onReadyRead()
void SerialCommunicator::onRecvTimeout() void SerialCommunicator::onRecvTimeout()
{ {
// 接收完成,发送完整数据信号,停止重发定时器 // 接收完成,发送完整数据信号,停止重发定时器
resendTimer_->stop();
emit dataReceived(recvBuffer_); emit dataReceived(recvBuffer_);
recvBuffer_.clear(); recvBuffer_.clear();
resendTimer_->stop();
} }


/** /**


+ 59
- 20
widget.cpp View File

@@ -24,23 +24,30 @@ Widget::Widget(QWidget *parent) :
serialComm->setResendTimeout(1000); // 重发间隔1s serialComm->setResendTimeout(1000); // 重发间隔1s


// 连接信号槽(串口->界面) // 连接信号槽(串口->界面)
//当串口接收到完整数据后,SerialCommunicator会发出dataReceived信号
connect(serialComm, &SerialCommunicator::dataReceived, this, &Widget::onSerialDataReceived); connect(serialComm, &SerialCommunicator::dataReceived, this, &Widget::onSerialDataReceived);
//当串口状态改变时,SerialCommunicator会发出statusChanged信号
connect(serialComm, &SerialCommunicator::statusChanged, this, &Widget::onSerialStatusChanged); connect(serialComm, &SerialCommunicator::statusChanged, this, &Widget::onSerialStatusChanged);
//当发送数据超过超时重发次数后仍未收到数据,SerialCommunicator会发出timeoutOccurred信号
connect(serialComm, &SerialCommunicator::timeoutOccurred, this, &Widget::onSerialTimeout); connect(serialComm, &SerialCommunicator::timeoutOccurred, this, &Widget::onSerialTimeout);
//当串口连接出现错误时(例如串口突然断开),SerialCommunicator会发出physicalDisconnected信号
connect(serialComm, &SerialCommunicator::physicalDisconnected, this, [=](){ connect(serialComm, &SerialCommunicator::physicalDisconnected, this, [=](){
ui->btnConnect->setText("连接"); ui->btnConnect->setText("连接");
ui->btn_read->setEnabled(false); ui->btn_read->setEnabled(false);
ui->pushWrite->setEnabled(false); ui->pushWrite->setEnabled(false);
QMessageBox::warning(this, "警告", "物理连接已断开");
QMessageBox::warning(this, "警告", "串口已断开连接");
}); });


//设置默认波特率、数据位、校验位
ui->comboBox_baudRate->setCurrentIndex(3); ui->comboBox_baudRate->setCurrentIndex(3);
ui->comboBox_dataBit->setCurrentIndex(3); ui->comboBox_dataBit->setCurrentIndex(3);
ui->comboBox_xiaoyan->setCurrentIndex(2); ui->comboBox_xiaoyan->setCurrentIndex(2);


//串口未连接前锁定读取和写入按钮
ui->btn_read->setEnabled(0); ui->btn_read->setEnabled(0);
ui->pushWrite->setEnabled(0); ui->pushWrite->setEnabled(0);


//检查当前可用串口
QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts(); QList<QSerialPortInfo> serialList = QSerialPortInfo::availablePorts();
for(QSerialPortInfo serialInfo : serialList) for(QSerialPortInfo serialInfo : serialList)
{ {
@@ -101,43 +108,53 @@ void Widget::on_btnConnect_clicked()
//写线圈和写寄存器 //写线圈和写寄存器
void Widget::on_pushWrite_clicked() void Widget::on_pushWrite_clicked()
{ {
switch (ui->comboBox_gongnengma->currentIndex())
switch (ui->comboBox_gongnengma->currentIndex()) //判断当前功能码
{ {
case 2: //写多个线圈 case 2: //写多个线圈
{ {
QString sendData = ui->lineEdit->text().trimmed();
QString sendData = ui->lineEdit->text().trimmed(); //读取输入框中的数据
//判断输入框中是否为空
if (sendData.isEmpty()) if (sendData.isEmpty())
{ {
QMessageBox::warning(this, "提示", "请至少输入一个数据"); QMessageBox::warning(this, "提示", "请至少输入一个数据");
return; return;
} }
for (QChar ch : sendData) {
if (ch != '0' && ch != '1') {
sendData.remove(" "); //移除输入数据中的空格
//判断输入数据是否为二进制格式
for (QChar ch : sendData)
{
if (ch != '0' && ch != '1')
{
QMessageBox::warning(this, "提示", "只允许输入 0 或 1!"); QMessageBox::warning(this, "提示", "只允许输入 0 或 1!");
return; return;
} }
} }


//拆分数据
QVector<bool> coils; QVector<bool> coils;
for (QChar ch : sendData) for (QChar ch : sendData)
{ {
coils.append(ch == '1'); coils.append(ch == '1');
} }


//配置从站参数
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt();
quint16 functionCode = 0x0f; quint16 functionCode = 0x0f;
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt();
quint16 length = ui->lineEdit_length->text().toInt(); quint16 length = ui->lineEdit_length->text().toInt();


//判断输入数据长度与设置的长度是否一致
if (coils.size() != length) if (coils.size() != length)
{ {
QMessageBox::warning(this, "提示", "输入数据数与设置的长度不匹配"); QMessageBox::warning(this, "提示", "输入数据数与设置的长度不匹配");
return; return;
} }
//将从站参数传入modbus中
modbus->Set(stationAddress,functionCode,stratAddress,length); modbus->Set(stationAddress,functionCode,stratAddress,length);
modbus->WriteCoil(coils);
modbus->WriteCoil(coils); //使用WriteCoil方法生成命令报文


serialComm->sendData(modbus->SendCommand());
serialComm->sendData(modbus->SendCommand()); //发送生成的命令报文
//锁定按钮
ui->btn_read->setEnabled(0); ui->btn_read->setEnabled(0);
ui->pushWrite->setEnabled(0); ui->pushWrite->setEnabled(0);


@@ -146,13 +163,15 @@ void Widget::on_pushWrite_clicked()


case 3: //写多个寄存器 case 3: //写多个寄存器
{ {
QString sendData = ui->lineEdit->text().trimmed();
QString sendData = ui->lineEdit->text().trimmed(); //读取数据
//判断输入框中是否为空
if (sendData.isEmpty()) if (sendData.isEmpty())
{ {
QMessageBox::warning(this, "提示", "请输入完整的寄存器数据"); QMessageBox::warning(this, "提示", "请输入完整的寄存器数据");
return; return;
} }


//拆分输入的寄存器数据
QStringList sl = sendData.split(','); QStringList sl = sendData.split(',');
QVector<quint16> values; QVector<quint16> values;
bool ok; bool ok;
@@ -169,6 +188,7 @@ void Widget::on_pushWrite_clicked()
} }
} }


//若判断输入的数据不是10进制,则按16进制数据处理
for (const QString &s : sl) for (const QString &s : sl)
{ {
quint16 v; quint16 v;
@@ -195,20 +215,24 @@ void Widget::on_pushWrite_clicked()
values.append(v); values.append(v);
} }


//配置从站参数
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt();
quint16 functionCode = 0x10; quint16 functionCode = 0x10;
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt();
quint16 length = ui->lineEdit_length->text().toInt(); quint16 length = ui->lineEdit_length->text().toInt();


//判断输入数据长度与设置的长度是否一致
if (values.size() != length) if (values.size() != length)
{ {
QMessageBox::warning(this, "提示", "输入数据数与设置的长度不匹配"); QMessageBox::warning(this, "提示", "输入数据数与设置的长度不匹配");
return; return;
} }
//将从站参数传入modbus中
modbus->Set(stationAddress,functionCode,stratAddress,length); modbus->Set(stationAddress,functionCode,stratAddress,length);
modbus->WriteRegister(values); //要发送的报文
modbus->WriteRegister(values); //使用WriteRegister方法生成命令报文


serialComm->sendData(modbus->SendCommand());
serialComm->sendData(modbus->SendCommand()); //发送生成的命令报文
//锁定按钮
ui->btn_read->setEnabled(0); ui->btn_read->setEnabled(0);
ui->pushWrite->setEnabled(0); ui->pushWrite->setEnabled(0);


@@ -216,6 +240,7 @@ void Widget::on_pushWrite_clicked()
} }
default: default:
{ {
//若当前操作设置错误则进行提示
QMessageBox::warning(this, "提示", "请将“操作”切换为写线圈或写寄存器"); QMessageBox::warning(this, "提示", "请将“操作”切换为写线圈或写寄存器");
break; break;
} }
@@ -226,17 +251,18 @@ void Widget::on_pushWrite_clicked()
//发送读线圈和寄存器报文 //发送读线圈和寄存器报文
void Widget::on_btn_read_clicked() void Widget::on_btn_read_clicked()
{ {
//若当前操作设置错误则进行提示
if (ui->comboBox_gongnengma->currentIndex() == 2 || if (ui->comboBox_gongnengma->currentIndex() == 2 ||
ui->comboBox_gongnengma->currentIndex() == 3) ui->comboBox_gongnengma->currentIndex() == 3)
{ {
QMessageBox::warning(this, "提示", "请将“操作”切换为读线圈或读寄存器"); QMessageBox::warning(this, "提示", "请将“操作”切换为读线圈或读寄存器");
return; return;
} }
//设置从站参数
quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt(); quint16 stationAddress = ui->lineEdit_stationAddress->text().toInt();
quint16 functionCode; quint16 functionCode;
quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt(); quint16 stratAddress = ui->lineEdit_stratAddress->text().toInt();
quint16 length = ui->lineEdit_length->text().toInt(); quint16 length = ui->lineEdit_length->text().toInt();

if (ui->comboBox_gongnengma->currentIndex() == 0) //读线圈 if (ui->comboBox_gongnengma->currentIndex() == 0) //读线圈
{ {
functionCode = 0x01; functionCode = 0x01;
@@ -246,46 +272,58 @@ void Widget::on_btn_read_clicked()
functionCode = 0x03; functionCode = 0x03;
} }


//将从站参数传入modbus中
modbus->Set(stationAddress,functionCode,stratAddress,length); modbus->Set(stationAddress,functionCode,stratAddress,length);
modbus->ReadCoilAndReg();
modbus->ReadCoilAndReg(); //使用ReadCoilAndReg方法生成命令报文


serialComm->sendData(modbus->SendCommand());
serialComm->sendData(modbus->SendCommand()); //发送生成的命令报文
//锁定按钮
ui->btn_read->setEnabled(0); ui->btn_read->setEnabled(0);
ui->pushWrite->setEnabled(0); ui->pushWrite->setEnabled(0);


} }


//保存通信历史数据
void Widget::on_btn_SaveDate_clicked() void Widget::on_btn_SaveDate_clicked()
{ {
SaveDate(this,ui->textEdit_2); SaveDate(this,ui->textEdit_2);
} }


//读取通信历史数据
void Widget::on_btn_ReadDate_clicked() void Widget::on_btn_ReadDate_clicked()
{ {
ReadDate(this,ui->textEdit_2); ReadDate(this,ui->textEdit_2);
} }


//清空状态通知文本框中的信息
void Widget::on_btn_ClearDate_clicked() void Widget::on_btn_ClearDate_clicked()
{ {
ui->textEdit_2->clear(); ui->textEdit_2->clear();
} }


//清空数据读取文本框中的信息
void Widget::on_btn_ClearRead_clicked() void Widget::on_btn_ClearRead_clicked()
{ {
ui->textEdit->clear(); ui->textEdit->clear();
} }


//处理接收到的返回报文
void Widget::onSerialDataReceived(const QByteArray &data) void Widget::onSerialDataReceived(const QByteArray &data)
{ {
QByteArray revMessage = modbus->Receive(data); // 交给Modbus解析
if (revMessage.isEmpty()) return;

QByteArray revMessage = modbus->Receive(data); // 接收的原始数据交给Modbus解析
// 启用操作按钮 // 启用操作按钮
ui->btn_read->setEnabled(true); ui->btn_read->setEnabled(true);
ui->pushWrite->setEnabled(true); ui->pushWrite->setEnabled(true);
if (revMessage.isEmpty()) //若modbus检测响应报文格式错误则丢弃数据,返回值为空
{
QMessageBox::warning(this, "提示", "返回报文站地址或CRC校验错误,请重试");
return;
}

//显示接收到的响应报文
ui->textEdit_2->append("接收报文:" + revMessage.toHex().toUpper()); ui->textEdit_2->append("接收报文:" + revMessage.toHex().toUpper());


// 检查Modbus错误码
// 检查响应报文中是否带有错误码
int exCode = modbus->ErrorCheck(); int exCode = modbus->ErrorCheck();
if (exCode) if (exCode)
{ {
@@ -307,7 +345,7 @@ void Widget::onSerialDataReceived(const QByteArray &data)
{ {
case 0: case 0:
{ // 读线圈 { // 读线圈
QVector<bool> coils = modbus->AnalReadCoil();
QVector<bool> coils = modbus->AnalReadCoil(); //使用AnalReadCoil方法解析线圈数据
ui->textEdit->append("线圈状态:"); ui->textEdit->append("线圈状态:");
for (int i = 0; i < coils.size(); i++) for (int i = 0; i < coils.size(); i++)
{ {
@@ -317,7 +355,7 @@ void Widget::onSerialDataReceived(const QByteArray &data)
} }
case 1: case 1:
{ // 读寄存器 { // 读寄存器
QVector<quint16> regs = modbus->AnalReadReg();
QVector<quint16> regs = modbus->AnalReadReg(); //使用AnalReadReg方法解析寄存器数据
ui->textEdit->append("寄存器值:"); ui->textEdit->append("寄存器值:");
for (int i = 0; i < regs.size(); i++) for (int i = 0; i < regs.size(); i++)
{ {
@@ -328,12 +366,13 @@ void Widget::onSerialDataReceived(const QByteArray &data)
} }
} }


//显示串口状态
void Widget::onSerialStatusChanged(const QString &status) void Widget::onSerialStatusChanged(const QString &status)
{ {
ui->textEdit_2->append(status); // 显示状态信息(如连接成功、超时重发等) ui->textEdit_2->append(status); // 显示状态信息(如连接成功、超时重发等)
} }


//超过超时重发次数后触发
void Widget::onSerialTimeout() void Widget::onSerialTimeout()
{ {
QMessageBox::warning(this, "提示", "等待响应超时,请检查设备"); QMessageBox::warning(this, "提示", "等待响应超时,请检查设备");


+ 0
- 5
widget.ui View File

@@ -232,11 +232,6 @@
<string>8</string> <string>8</string>
</property> </property>
</item> </item>
<item>
<property name="text">
<string>NONE</string>
</property>
</item>
</widget> </widget>
</item> </item>
<item row="3" column="0"> <item row="3" column="0">


Loading…
Cancel
Save