updateapp.h

  1. #ifndef UPDATEAPP_H
  2. #define UPDATEAPP_H
  3. #include <QWidget>
  4. #include <QDialog>
  5. #include <QFile>
  6. #include <QTimer>
  7. #include <QList>
  8. namespace Ui {
  9. class UpdateApp;
  10. }
  11. class UpdateApp : public QDialog
  12. {
  13. Q_OBJECT
  14. public:
  15. explicit UpdateApp(QWidget *parent = 0);
  16. ~UpdateApp();
  17. qint16 Xmodem = 128;
  18. QString tempData = NULL; // 临时存储
  19. QFile file; // 文件对象
  20. QString fileName; // 文件名字
  21. qint64 fileSize; // 文件大小
  22. qint64 sendSize; // 已发送文件大小
  23. qint32 sendCount; // 要发送几次
  24. qint32 num = 0; // 累计发送的次数
  25. qint64 len = 0; // 每次发送的长度
  26. //QTimer timer4; // 更新程序定时器
  27. //void sendUpdateAppData(); // 发送数据函数
  28. void sliceData();
  29. // 接收返回的数据
  30. void recevedData(char);
  31. // 定义变量枚举
  32. enum ID_Enum
  33. {
  34. ID_C = 'C',
  35. ID_ACK = 1,
  36. ID_NAK = 2
  37. };
  38. signals:
  39. void sendCloseSig(void);
  40. void sendUpdateData(QString);
  41. private slots:
  42. void on_selectFile_clicked();
  43. void on_sendData_clicked();
  44. void on_cancle_clicked();
  45. private:
  46. Ui::UpdateApp *ui;
  47. void closeEvent(QCloseEvent*event);
  48. };
  49. #endif // UPDATEAPP_H

updateapp.c

  1. #include "updateapp.h"
  2. #include "ui_updateapp.h"
  3. #include <QFileDialog>
  4. #include <QDebug>
  5. UpdateApp::UpdateApp(QWidget *parent) :
  6. QDialog(parent),
  7. ui(new Ui::UpdateApp)
  8. {
  9. ui->setupUi(this);
  10. this->setWindowTitle("更新程序");
  11. ui->sendData->setEnabled(false); // 禁用发送数据按钮
  12. }
  13. UpdateApp::~UpdateApp()
  14. {
  15. delete ui;
  16. }
  17. void UpdateApp::on_selectFile_clicked()
  18. {
  19. ui->progressBar->setValue(0); // 当前值
  20. ui->sendData->setEnabled(false);
  21. ui->fileName->setText("...");
  22. // 文件路径
  23. QString filePath = QFileDialog::getOpenFileName(this, "open", "../");
  24. // 如果选择文件路径有效
  25. if(filePath.isEmpty() == false)
  26. {
  27. // 先清空前面的内容
  28. fileName.clear();
  29. fileSize = 0;
  30. // 获取文件信息
  31. QFileInfo info(filePath);
  32. fileName = info.fileName(); // 文件名
  33. fileSize = info.size(); // 文件大小
  34. sendCount = fileSize/Xmodem + (fileSize%Xmodem ? 1 : 0); // 要发送几次
  35. ui->fileName->setText(fileName); // 设置文件名
  36. qDebug() << "文件大小" << fileSize;
  37. qDebug() << "总数" << sendCount;
  38. sendSize = 0; // 初始化发送文件的大小
  39. // 只读方式打开, 指定文件的名字
  40. file.setFileName(filePath);
  41. // 打开文件
  42. bool isOk = file.open(QIODevice::ReadOnly);
  43. if(isOk == false)
  44. {
  45. qDebug() << "只读方式打开文件失败";
  46. ui->sendData->setEnabled(false);
  47. }else
  48. {
  49. qDebug() << "文件打开成功";
  50. ui->sendData->setEnabled(true);
  51. }
  52. }
  53. }
  54. void UpdateApp::on_sendData_clicked()
  55. {
  56. // 先发送固件升级请求
  57. emit sendUpdateData("11 00 4D 00 01");
  58. // 设置进度条当前值为0
  59. ui->progressBar->setValue(0);
  60. ui->sendData->setEnabled(false); // 确定按钮禁用
  61. // 设置进度条
  62. ui->progressBar->setMinimum(0); // 最小值
  63. ui->progressBar->setMaximum(sendCount);
  64. ui->progressBar->setValue(0); // 当前值
  65. //timer4.start(100);
  66. num = 0;
  67. }
  68. void UpdateApp::recevedData(char sig)
  69. {
  70. switch (sig)
  71. {
  72. case ID_C:
  73. sliceData(); // 文件发送
  74. break;
  75. case ID_ACK:
  76. sliceData(); // 文件发送
  77. break;
  78. case ID_NAK:
  79. emit sendUpdateData(tempData); // 重发文件
  80. break;
  81. }
  82. // 是否发送文件完毕
  83. if(sendSize == fileSize)
  84. {
  85. qDebug() << "文件发送完毕";
  86. file.close();
  87. // timer4.stop(); // 停止定时器
  88. }
  89. }
  90. void UpdateApp::sliceData()
  91. {
  92. // 每次发送数据的大小
  93. char buf[Xmodem] = {0};
  94. len = 0;
  95. // 往文件中读数据
  96. len = file.read(buf, sizeof(buf));
  97. if(len == 0)
  98. {
  99. //timer4.stop(); // 停止定时器
  100. return;
  101. }
  102. // 发送数据, 读多少发多少
  103. QString sendCounts = QString("%1").arg(sendCount, 4, 16, QLatin1Char('0'));
  104. QString numst = QString("%1").arg(num, 4, 16, QLatin1Char('0'));
  105. // 更新进度条
  106. ui->progressBar->setValue(num +1);
  107. qDebug() << numst;
  108. QByteArray bit_arr;
  109. int size = sizeof(buf);
  110. int i = 0;
  111. do
  112. {
  113. bit_arr.append(buf[i]); // 将二进制文件添加到数组中
  114. i++;
  115. }while(i<size);
  116. QString str_Data = QString("55 %1 %2 %3").arg(sendCounts)
  117. .arg(numst)
  118. .arg(QString(bit_arr.toHex())); // 将数组的数据转hex发送
  119. num++;
  120. tempData = str_Data;
  121. emit sendUpdateData(str_Data);
  122. // 发送的数据累加
  123. sendSize += len;
  124. }
  125. void UpdateApp::on_cancle_clicked()
  126. {
  127. // qDebug() << "点击取消";
  128. this->close();
  129. }
  130. void UpdateApp::closeEvent(QCloseEvent* event)
  131. {
  132. // 初始化文件
  133. ui->fileName->setText("...");
  134. fileName.clear();
  135. file.close();
  136. ui->sendData->setEnabled(false);
  137. ui->progressBar->setValue(0);
  138. // qDebug() << "点击关闭" << event;
  139. emit sendCloseSig(); // 发送取消信号
  140. }

主程序.h

  1. #include "updateapp.h"
  2. public:
  3. // 更新程序窗口
  4. UpdateApp *updateapp;
  5. signals:
  6. void receveData(char);

主程序.c

  1. ...
  2. // 读取串口返回的数据
  3. QObject::connect(&mSerialPort, &QSerialPort::readyRead,
  4. this, &Dx1000_dialogSP::on_SerialPort_readyRead);
  5. // 当updateapp弹框关闭时,就重启定时器
  6. connect(updateapp, &UpdateApp::sendCloseSig, this, [=](){
  7. int time = ui->setTime->text().toInt();
  8. timer->start(time); // 重启定时器
  9. });
  10. connect(updateapp, &UpdateApp::sendUpdateData, this, [=](QString str){
  11. QString sendData = merge(str);
  12. isSendData = QString2Hex(sendData).toHex();
  13. mSerialPort.write(QString2Hex(sendData));
  14. qDebug() << "sendUpdateData";
  15. qDebug() << isSendData;
  16. qDebug() << "read" << mSerialPort.readAll();
  17. });
  18. // 将接收到的指令返回到updateapp提示框中
  19. connect(this, &Dx1000_dialogSP::receveData, updateapp, &UpdateApp::recevedData);
  20. // 接收数据槽函数
  21. void Dx1000_dialogSP::on_SerialPort_readyRead()
  22. {
  23. // 判断返回的是否是要的数据
  24. QByteArray recvData = mSerialPort.readAll();
  25. qDebug() << "recvData" << recvData;
  26. qint8 reD = recvData[2];
  27. qDebug() << "reD" << reD;
  28. if( 67 == reD)
  29. {
  30. emit receveData(updateapp->ID_C); // 数据接收成功
  31. qDebug() << "接收C指令成功";
  32. return;
  33. }else if( 6 == reD)
  34. {
  35. emit receveData(updateapp->ID_ACK); // 数据接收成功
  36. qDebug() << "接收ACK指令成功";
  37. return;
  38. }else if( 21 == reD)
  39. {
  40. emit receveData(updateapp->ID_NAK); // 数据接收成功
  41. qDebug() << "接收NAK指令成功";
  42. return;
  43. }
  44. ...
  45. }