QT:BMS_TTL

BMS工程的QT文件

mainwindow.cpp

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QTextCodec>
#include <QMessageBox>
#include <QThread>
#include <QSerialPort>          // 补充串口头文件
#include <QSerialPortInfo>
#include <QFileDialog>
#include <QTimer>
#include <QTextBrowser>         // 若UI用QTextBrowser,需包含
#include <QLineEdit>            // 若UI用QLineEdit,需包含
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    COM = new QSerialPort(this);

    // 初始化串口列表
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->COM->addItem(info.portName());
    }
    // 连接串口接收信号(defbug)
    connect(COM, SIGNAL(readyRead()), this, SLOT(Ser_COMDebug_RX()));
}

MainWindow::~MainWindow()
{
    delete ui;
}




//刷新串口按钮

void MainWindow::on_Refresh_COM_clicked()
{
    ui->COM->clear();
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->COM->addItem(info.portName());
    }
}
//点击连接按钮
void MainWindow::on_connect_COM_clicked()
{
    QSerialPort::BaudRate baudRate;
    QSerialPort::StopBits stopBits = QSerialPort::OneStop;
    QSerialPort::DataBits dataBits = QSerialPort::Data8;
    QSerialPort::Parity checkBits = QSerialPort::NoParity;
    QSerialPort::FlowControl flowControl = QSerialPort::NoFlowControl;

    // 设置波特率 currentText获得文本中的内容
    if(ui->Baud_rate->currentText() == "9600"){
        baudRate = QSerialPort::Baud9600;
    }
    else if(ui->Baud_rate->currentText() == "115200"){
        baudRate = QSerialPort::Baud115200;
    }
    else{
        QMessageBox::warning(this, "参数错误", "仅支持9600/115200波特率!");
        return;
    }

    // 配置串口参数
    COM->setPortName(ui->COM->currentText());
    COM->setBaudRate(baudRate);
    COM->setStopBits(stopBits);
    COM->setDataBits(dataBits);
    COM->setParity(checkBits);
    COM->setFlowControl(flowControl);

    // 打开串口逻辑
    if(ui->connect_COM->text() == "连接BMS"){
        if(COM->open(QIODevice::ReadWrite)){
            ui->connect_COM->setText("断开BMS");
          ui->connect_COM->setStyleSheet("QPushButton  { background-color: red }");
        }else{
            QMessageBox::critical(this, "错误", "串口打开失败:\r\n" + COM->errorString());
        }
    }
    // 关闭串口逻辑 text 单行文本,简单控件返回的是QString类型的文本。
    else if(ui->connect_COM->text() == "断开BMS"){
        if(COM->isOpen()){
            COM->close();
            ui->connect_COM->setText("连接BMS");
           ui->connect_COM->setStyleSheet("QPushButton  { background-color: white;  }");
        }
    }
}
//清空调试信息的文本
void MainWindow::on_connect_COM_2_clicked()
{
      ui->Debug_text->clear();
}
void MainWindow::Ser_COMDebug_RX()
{
    QByteArray buf = COM->readAll();
    if (buf.isEmpty()) return;

    // ========== 新增:处理STM32的MOS控制确认反馈(Aok/Bok/Cok/Dok) ==========
    QString feedback = QString::fromUtf8(buf); // 或用GB2312解码,根据实际串口编码
    if (feedback.contains("Aok")) {
        // 充电MOS打开确认
        ui->label_73->setText("打开");
        ui->Debug_text->insertPlainText("[反馈] 充电MOS已打开\n");
    }
    else if (feedback.contains("Bok")) {
        // 充电MOS关闭确认
        ui->label_73->setText("关闭");
        ui->Debug_text->insertPlainText("[反馈] 充电MOS已关闭\n");
    }
    else if (feedback.contains("Cok")) {
        // 放电MOS打开确认
        ui->label_72->setText("打开");
        ui->Debug_text->insertPlainText("[反馈] 放电MOS已打开\n");
    }
    else if (feedback.contains("Dok")) {
        // 放电MOS关闭确认
        ui->label_72->setText("关闭");
        ui->Debug_text->insertPlainText("[反馈] 放电MOS已关闭\n");
    }

    // 1. 解码数据并追加到缓存
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QString newData = codec->toUnicode(buf).trimmed();
    m_dataBuffer += newData;  // 拼接新接收的数据到缓存
    // ui->Debug_text->insertPlainText("[接收片段] " + newData + "\n"); // 注释:隐藏接收片段提示

    // 2. 检查缓存中是否包含完整帧结束符(AAAA)
    int endPos = m_dataBuffer.indexOf("AAAA");
    if (endPos == -1) {
        // 未找到结束符,继续缓存
        // ui->Debug_text->insertPlainText("[缓存] 数据未完整,继续缓存\n"); // 注释:隐藏缓存提示
        ui->Debug_text->moveCursor(QTextCursor::End);
        return;
    }

    // 3. 提取完整帧(从开头到AAAA结束)
    QString completeFrame = m_dataBuffer.left(endPos + 4);  // +4是"AAAA"的长度
    m_dataBuffer = m_dataBuffer.mid(endPos + 4);  // 剩余数据保留到缓存(防止多帧重叠)
    // 注释掉完整帧的输出,不再显示
    // ui->Debug_text->insertPlainText("[完整帧] " + completeFrame + "\n"); // 注释:隐藏完整帧提示

    // 4. 清理完整帧中的无关内容(如"电流+温度+全部电压"这类提示)
    completeFrame = completeFrame.remove("电流+温度+全部电压").trimmed();
    completeFrame = completeFrame.remove("AAAA");  // 移除结束符

    // 5. 分割数据并校验格式
    QStringList dataList = completeFrame.split("-", QString::SkipEmptyParts);
    if (dataList.size() < 10) {  // 至少10个电池字段
        // ui->Debug_text->insertPlainText("[错误] 完整帧格式错误,字段不足:" + completeFrame + "\n"); // 注释:隐藏错误提示
        ui->Debug_text->moveCursor(QTextCursor::End);
        return;
    }

    // 6. 解析并显示电池数据(恢复setText,显示数据)
    auto updateBattery = [this](int batteryNum, const QString &value) {
        QTextBrowser *batteryWidget = findChild<QTextBrowser*>(QString("battery%1").arg(batteryNum));
        if (batteryWidget) {
            batteryWidget->setText(value);  // 恢复显示
        } else {
            // ui->Debug_text->insertPlainText("[警告] 未找到电池" + QString::number(batteryNum) + "控件\n"); // 注释:隐藏控件未找到警告
        }
    };

    // 电池1~9对应数据列表前9项(根据实际数据调整索引)
    updateBattery(1, dataList[0]);
    updateBattery(2, dataList[1]);
    updateBattery(3, dataList[2]);
    updateBattery(4, dataList[3]);
    updateBattery(5, dataList[4]);
    updateBattery(6, dataList[5]);
    updateBattery(7, dataList[6]);
    updateBattery(8, dataList[7]);
    updateBattery(9, dataList[8]);

    // 6. 总电压(TOL_V)
       if (ui->battery_All) {
           ui->battery_All->setText(dataList[9] );
       } else {
           // ui->Debug_text->insertPlainText("[警告] 未找到总电压控件:TOL_V\n"); // 注释:隐藏控件未找到警告
       }

       // 7. 电流(cur)
       if (ui->electricity) {
           ui->electricity->setText(dataList[10] );
       } else {
           // ui->Debug_text->insertPlainText("[警告] 未找到电流控件:cur\n"); // 注释:隐藏控件未找到警告
       }

       // 8. 温度(Temp)
       if (ui->Tem) {
           ui->Tem->setText(dataList[11] + " °C");
       } else {
           // ui->Debug_text->insertPlainText("[警告] 未找到温度控件:Temp\n"); // 注释:隐藏控件未找到警告
       }
       if (ui->Tem_2) {
           ui->Tem_2->setText(dataList[12] + " %");
           // 设置大字体
           QFont font = ui->Tem_2->font(); // 获取控件当前字体
           font.setPointSize(22); // 设置字体大小(可根据需求调整数值,如16、18等)
           // 可选:加粗字体
           // font.setBold(true);
           ui->Tem_2->setFont(font); // 应用字体设置
       } else {
           // ui->Debug_text->insertPlainText("[警告] 未找到温度控件:Temp\n"); // 注释:隐藏控件未找到警告
       }
    ui->Debug_text->insertPlainText("[完成] 数据解析成功\n");
    ui->Debug_text->moveCursor(QTextCursor::End);
}
//开始采集按钮
// 示例:发送GB2312编码的文本(比如"测试数据")
// 发送GB2312编码的文本(例如"测试数据")
void MainWindow::on_startgather_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xBB 0x13 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
}
//停止采集数据按键
void MainWindow::on_connect_COM_4_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xBB 0x14 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
}
//清空按键的全部数据
void MainWindow::on_clearData_clicked()
{



    // 2. 清空数据缓存(防止残留数据干扰后续解析)
    m_dataBuffer.clear();

    // 3. 清空所有单体电池控件(battery1~battery9)
    for (int i = 1; i <= 9; ++i) {
        QTextBrowser *batteryWidget = findChild<QTextBrowser*>(QString("battery%1").arg(i));
        if (batteryWidget) {
            batteryWidget->clear();  // 清空电池控件内容
        }
    }

    // 4. 清空总电压控件
    if (ui->battery_All) {
        ui->battery_All->clear();
    }

    // 5. 清空电流控件
    if (ui->electricity) {
        ui->electricity->clear();
    }

    // 6. 清空温度控件
    if (ui->Tem) {
        ui->Tem->clear();
    }


}
//打开放电MOS
void MainWindow::on_connect_COM_5_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xAB 0x03 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
   // ui->label_72->setText("打开");
}
//打开充电mos
void MainWindow::on_connect_COM_7_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xAB 0x01 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
    // ui->label_73->setText("打开");
}
//关闭放电mos
void MainWindow::on_connect_COM_6_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xAB 0x04 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
   //  ui->label_72->setText("关闭");
}
//关闭充电mos
void MainWindow::on_connect_COM_8_clicked()
{
    if (!COM->isOpen()) {
        QMessageBox::warning(this, "提示", "串口未连接,请先打开串口!");
        return;
    }

    QString sendText = "0xAA 0xAB 0x02 0xCC\r\n"; // 要发送的文本
    // 关键:用GB2312编码转为字节数组
    QTextCodec *codec = QTextCodec::codecForName("GB2312");
    QByteArray sendData = codec->fromUnicode(sendText); // 转为GB2312编码的字节

    COM->write(sendData);
    ui->Debug_text->insertPlainText("已发送GB2312文本:" + sendText + "\n");
     //ui->label_73->setText("关闭");
}

mainwindow.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QSerialPort>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:


    void on_Refresh_COM_clicked();

    void on_connect_COM_clicked();

    void on_connect_COM_2_clicked();
    void Ser_COMDebug_RX();



    void on_startgather_clicked();

    void on_connect_COM_4_clicked();

    void on_clearData_clicked();

    void on_connect_COM_5_clicked();

    void on_connect_COM_7_clicked();

    void on_connect_COM_6_clicked();

    void on_connect_COM_8_clicked();

private:
    Ui::MainWindow *ui;
     QSerialPort *COM;                  // 串口对象
     QString m_dataBuffer;  // 串口数据缓存,用于拼接分段数据

};
#endif // MAINWINDOW_H
相关推荐
用户805533698031 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner1 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz6 天前
QML Hello World 入门示例
qt
xcyxiner9 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner10 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner10 天前
DicomViewer (添加模型类)3
qt
xcyxiner11 天前
DicomViewer (目录调整) 2
qt
xcyxiner11 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00613 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术13 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript