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