You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

372 lines
11 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QByteArray>
#include <QDataStream>
#include <QDate>
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QFileDialog>
#include <QMessageBox>
#include <QTime>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
ui->hourSpinBox->setMaximum(23);
ui->minuteSpinBox->setMaximum(59);
ui->secondSpinBox->setMaximum(59);
folderPath = "";
}
MainWindow::~MainWindow() { delete ui; }
void MainWindow::ReadDat(QString fileName) {
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
int hour = ui->hourSpinBox->value();
int minute = ui->minuteSpinBox->value();
int second = ui->secondSpinBox->value();
QTime time(hour, minute, second);
QDate date(year + 2000, month, day);
QDateTime targetTime(date, time);
// 转化为16进制
uint8_t hexYear = IntToHex(year);
uint8_t hexMonth = IntToHex(month);
uint8_t hexDay = IntToHex(day);
uint8_t hexHour = IntToHex(hour);
uint8_t hexMinute = IntToHex(minute);
uint8_t hexSecond = IntToHex(second);
// QString filename = outputDir+"/"+fileName;
// // 一个示例日期年月日分别为2023年、12月、3日
// QDate date(year+2000, month, day);
// // 将日期格式化为yymmdd
// QString formattedDate = date.toString("yyyyMMdd");
// //修改文件名的时间信息
// QString f1 = fileName;
// f1.remove(11,f1.length()-11);
// QString f2 = fileName;
// f2.remove(0,11+8);
// QString str = f1+formattedDate+f2;
QString outputFileName =
GetOutputFileName(fileName, year, month, day, hour, minute, second);
// 创建修改后的dat文件
QFile writeFile(outputDir + "/" + outputFileName);
QDataStream outStream;
if (writeFile.open(QIODevice::WriteOnly)) {
// 创建数据流,用于写入二进制数据
// outStream = QDataStream(&writeFile);
outStream.setDevice(&writeFile);
outStream.setByteOrder(QDataStream::LittleEndian);
}
int len = 265;
quint8 *data = new quint8[len];
QFile file1 = QFile(folderPath + "/" + fileName);
// QFile file1 = QFile("E:\\dat\\output\\下行遥测_0_1_0_20230619230109.dat");
file1.open(QIODevice::ReadOnly);
QDataStream readStream = QDataStream(&file1);
readStream.setVersion(QDataStream::Qt_5_15); // 设置数据流的版本
readStream.setByteOrder(QDataStream::LittleEndian);
int i = 0;
quint8 *content = new quint8[28]; // 创建一个28字节的数据缓冲区
// int sub1 = 0;
// int sub2 = 0;
bool bFirstTime = true;
qint64 offsetTime = 0;
while (!readStream.atEnd()) {
readStream.readRawData((char *)data, len); // 读取一帧
QTime time(data[5], data[6], data[7]);
QDate date(int(data[2]) + 2000, data[3], data[4]);
QDateTime curTime(date, time);
if (bFirstTime) {
offsetTime = curTime.secsTo(targetTime);
bFirstTime = false;
}
QTime tmp0 = curTime.time();
curTime = curTime.addSecs(offsetTime);
QTime tmp1 = curTime.time();
// i++;
// 四个子帧解析
// int id1 = 16;
// int id2 = id1+32;
// int id3 = id2+32;
// int id4 = id3+32;
int startID = 16;
for (int var = 0; var < 4; ++var) {
startID = 16 + 32 * var;
quint8 zhenID = data[startID + 4];
if (zhenID == 0x87 || zhenID == 0x89 || zhenID == 0x8A) {
if (data[startID + 17] == 0x02) // 子帧2
{
// QTime time(data[startID + 21], data[startID + 22],
// data[startID + 23]);
// QDate date(int(data[startID + 20]) + 2000, data[startID + 19],
// data[startID + 18]);
// QDateTime tmpTime(date, time);
// tmpTime = tmpTime.addSecs(offsetTime);
// 修改UTC年月日数据
if (hexDay > 0)
data[startID + 18] = hexDay;
if (hexMonth > 0)
data[startID + 19] = hexMonth;
if (hexYear > 0)
data[startID + 20] = hexYear;
// // 修改UTC时分秒数据
// if (hexHour > 0)
// data[startID + 21] = IntToHex(tmpTime.time().hour());
// if (hexMinute > 0)
// data[startID + 22] = IntToHex(tmpTime.time().minute());
// if (hexSecond > 0)
// data[startID + 23] = IntToHex(tmpTime.time().second());
// 计算CRC16校验位
for (int i = 0; i < 28; i++) // 提取数据帧内容
{
content[i] = data[startID + 2 + i];
}
quint16 crc = GetCrcSum(content, 28); // 计算校验码
// 提取高位和低位
quint8 highByte = static_cast<quint8>((crc >> 8) & 0xFF);
quint8 lowByte = static_cast<quint8>(crc & 0xFF);
// 修改CRC校验位
data[startID + 30] = lowByte;
data[startID + 31] = highByte;
}
}
}
// 修改系统时间戳
if (hexYear > 0)
data[2] = hexYear;
if (hexMonth > 0)
data[3] = hexMonth;
if (hexDay > 0)
data[4] = hexDay;
if (hexHour > 0)
data[5] = IntToHex(curTime.time().hour());
if (hexMinute > 0)
data[6] = IntToHex(curTime.time().minute());
if (hexSecond > 0)
data[7] = IntToHex(curTime.time().second());
// 修改最后校验位
data[len - 1] = GetDataCheckCRC(data, len);
// 写入文件
outStream.writeRawData((char *)data, len);
}
file1.close();
writeFile.close();
// qDebug()<<"*********************i:"<<i;
}
uint8_t MainWindow::IntToHex(int data) {
// 将十进制整数转换为十六进制表示
QByteArray hexData = QByteArray::number(data, 16);
// 将十六进制表示转换为 uint8_t 类型
bool ok;
return hexData.toUInt(&ok, 16);
}
/*******************************************************************************
函数名称: GetCrcSum
函数功能: 生成CRC校验字
入口参数: 需要校验的字符指针及数据长度
出口参数: CRC校验字
备注:
*******************************************************************************/
quint16 MainWindow::GetCrcSum(quint8 *dataptr, quint16 len) {
qint16 count = 0;
quint8 C0 = 0, C1 = 0, Y0 = 0, Y1 = 0, Z0 = 0, Z1 = 0;
C0 = C1 = Y0 = Y1 = Z0 = Z1 = 0;
while (count < len) {
Y0 = (CRCLIST[2 * (*dataptr)] ^ C1) & 0x00FF;
Y1 = (CRCLIST[2 * (*dataptr) + 1]) & 0x00FF;
Z0 = CRCLIST[2 * C0] & 0x00FF;
Z1 = CRCLIST[2 * C0 + 1] & 0x00FF;
C0 = (Y0 ^ Z0) & 0x00FF;
C1 = (Y1 ^ Z1) & 0x00FF;
dataptr++;
count++;
}
return (C0 + C1 * 256); /* return crc result */
}
quint8 MainWindow::GetDataCheckCRC(quint8 *dataptr, quint16 len) {
quint8 sum = 0;
for (int i = 0; i < 264; i++) {
sum += quint8(dataptr[i]);
}
return quint8(~(sum & 0xFF) + 1);
}
/**
* 判断指定年份是否是闰年
*
* @param year 年份
* @return true是闰年false不是闰年
*/
bool MainWindow::isLeapYear(int year) {
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
return true;
} else {
return false;
}
}
/**
* 判断指定整数是否为合法的日
*
* @param year 年份
* @param month 月份
* @param day 日
* @return true是合法的日false不是合法的日
*/
bool MainWindow::isValidDay(int year, int month, int day) {
if (month == 2) {
if (isLeapYear(year)) {
if (day >= 1 && day <= 29) {
return true;
}
} else {
if (day >= 1 && day <= 28) {
return true;
}
}
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
if (day >= 1 && day <= 30) {
return true;
}
} else {
if (day >= 1 && day <= 31) {
return true;
}
}
return false;
}
QString MainWindow::GetOutputFileName(QString fileName, int year, int month,
int day, int hour, int minute,
int second) {
// QString str = "下行遥测_0_17_0_20221114024453.dat";
QStringList strList = fileName.split("_");
QString endstr = strList.constLast();
QString lastStr = endstr.mid(14, -1);
if (year == 0)
year = endstr.mid(0, 4).toInt() - 2000;
// QString year0 = endstr.mid(0,4);
if (month == 0)
month = endstr.mid(4, 2).toInt();
if (day == 0)
day = endstr.mid(6, 2).toInt();
// QString month = endstr.mid(4,2);
// QString day = endstr.mid(6,2);
if (hour == 0)
hour = endstr.mid(8, 2).toInt();
if (minute == 0)
minute = endstr.mid(10, 2).toInt();
if (second == 0)
second = endstr.mid(12, 2).toInt();
// 一个示例日期年月日分别为2023年、12月、3日
QDate date(year + 2000, month, day);
// 将日期格式化为yymmdd
QString formattedDate = date.toString("yyyyMMdd");
QTime time(hour, minute, second);
QString formattedTime = time.toString("hhmmss");
QString outputFileName = "";
strList.removeLast();
strList.append(formattedDate + formattedTime);
outputFileName = strList.join("_") + lastStr;
// for (int var = 0; var < strList.length()-2; ++var) {
// outputFileName += strList.at(var);
// }
return outputFileName;
}
void MainWindow::on_openDirBtn_clicked() {
// 创建一个QFileDialog对象
QFileDialog dialog;
// 设置对话框的标题
dialog.setWindowTitle("Select Folder");
// 设置对话框模式为选择文件夹
dialog.setFileMode(QFileDialog::Directory);
// 打开对话框
if (dialog.exec()) {
// 获取用户选择的文件夹路径
folderPath = dialog.selectedFiles().at(0);
qDebug() << "Selected Folder: " << folderPath;
} else {
qDebug() << "User canceled the operation.";
}
}
void MainWindow::CreateDir() {
// 创建一个QDir对象
QDir dir;
outputDir = folderPath + "/output";
// 设置目录路径
dir.setPath(outputDir);
// 创建文件夹
if (dir.mkpath(outputDir)) {
qDebug() << "Folder created successfully.";
} else {
qDebug() << "Failed to create folder.";
}
// QDir directory(folderPath+"/output");
}
void MainWindow::on_startModifyBtn_clicked() {
int year = ui->yearSpinBox->value();
int month = ui->monthSpinBox->value();
int day = ui->daySpinBox->value();
if (year <= 0 && month <= 0 && day <= 0) {
QMessageBox::information(NULL, "提示", "请设置要修改的年月日!!!");
return;
}
if (folderPath == "") {
QMessageBox::information(NULL, "提示", "请先设置文件夹!!!");
return;
}
// 检查Day是否正确
if (day > 0 && !isValidDay(year + 2000, month, day)) {
QMessageBox::information(NULL, "提示", "日期有误,请重新设置!!!");
return;
}
// 创建一个 QDir 对象
QDir directory(folderPath);
// 获取文件夹中的所有文件
QStringList files = directory.entryList(QDir::Files);
int numFiles = files.length();
if (numFiles == 0) {
QMessageBox::information(NULL, "提示", "该文件夹没有dat文件!!!");
return;
}
// 新建output文件夹
CreateDir();
// 开始处理
for (int n = 0; n < numFiles; ++n) {
ReadDat(files.at(n));
}
QMessageBox::information(NULL, "提示", "处理结束!!!");
}