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
相关推荐
sali-tec1 小时前
C# 基于halcon的视觉工作流-章65 点云匹配-基于形状
开发语言·人工智能·算法·计算机视觉·c#
不会c嘎嘎1 小时前
【C++】深入理解多态:从用法到原理
开发语言·c++
武子康1 小时前
Java-179 FastDFS 高并发优化思路:max_connections、线程、目录与同步
java·开发语言·nginx·性能优化·系统架构·fastdfs·fdfs
缺点内向1 小时前
如何在C#中为文本内容添加行号?
开发语言·c#·word·.net
h***8561 小时前
Rust在Web中的前端开发
开发语言·前端·rust
Chasing Aurora2 小时前
Python连接云端Linux服务器进行远程 (后端开发/深度学习)时候的注意事项
linux·开发语言·python·ubuntu·ai编程
key062 小时前
从数据安全体系逆推数据自由度的权力本质
java·开发语言
C++ 老炮儿的技术栈2 小时前
用密码学安全随机数生成256位密钥
c语言·开发语言·c++·windows·安全·密码学·visual studio
z***43842 小时前
java与mysql连接 使用mysql-connector-java连接msql
java·开发语言·mysql