198 lines
6.0 KiB
C
198 lines
6.0 KiB
C
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <stdlib.h>
|
||
#include <stdint.h>
|
||
#include <windows.h>
|
||
// 定义缓冲区大小(可以根据实际需求调整)
|
||
#define BUFFER_SIZE 1024 // 每次读取1024条记录
|
||
|
||
// MPU传感器数据结构
|
||
typedef struct {
|
||
int16_t ax; // 加速度计 X轴
|
||
int16_t ay; // 加速度计 Y轴
|
||
int16_t az; // 加速度计 Z轴
|
||
int16_t gx; // 陀螺仪 X轴
|
||
int16_t gy; // 陀螺仪 Y轴
|
||
int16_t gz; // 陀螺仪 Z轴
|
||
} sensor_data_t;
|
||
|
||
// 完整的数据记录结构
|
||
#pragma pack(1)
|
||
typedef struct {
|
||
uint8_t y; // 年(相对值,需要加上2000)
|
||
uint8_t month; // 月
|
||
uint8_t d; // 日
|
||
uint8_t h; // 时
|
||
uint8_t m; // 分
|
||
uint8_t s; // 秒
|
||
uint16_t ms; // 毫秒
|
||
int16_t deepth; // 深度
|
||
sensor_data_t data; // MPU传感器数据
|
||
} info_t;
|
||
#pragma pack()
|
||
|
||
void print_usage() {
|
||
printf("用法:\n");
|
||
printf("decode.exe -f <文件名> [-o <输出文件名>]\n");
|
||
printf("选项:\n");
|
||
printf(" -f <文件名> 指定输入文件\n");
|
||
printf(" -o <文件名> 指定输出文件(可选,默认输出到与输入同名的.csv文件)\n");
|
||
printf(" -h 显示帮助信息\n");
|
||
printf("\n示例:\n");
|
||
printf("decode.exe -f 20241112.BIN\n");
|
||
printf("decode.exe -f 20241112.BIN -o output.csv\n");
|
||
}
|
||
|
||
// 原有的decode函数保持不变
|
||
void decode(char *filename) {
|
||
FILE *file = fopen(filename, "rb");
|
||
if (!file) {
|
||
fprintf(stderr, "无法打开文件\n");
|
||
return;
|
||
}
|
||
|
||
// 获取文件大小
|
||
fseek(file, 0, SEEK_END);
|
||
long fileSize = ftell(file);
|
||
fseek(file, 0, SEEK_SET);
|
||
|
||
// 计算记录数量
|
||
int recordCount = fileSize / sizeof(info_t);
|
||
|
||
// 打印CSV格式的表头
|
||
printf("年,月,日,时,分,秒,毫秒,深度,ax,ay,az,gx,gy,gz\n");
|
||
|
||
// 使用缓冲区读取以提高效率
|
||
info_t buffer[BUFFER_SIZE];
|
||
size_t records_read;
|
||
|
||
while ((records_read = fread(buffer, sizeof(info_t), BUFFER_SIZE, file)) > 0) {
|
||
for (size_t i = 0; i < records_read; i++) {
|
||
// 直接使用小端序数据,无需转换
|
||
// 单字节数据:y, month, d, h, m, s
|
||
// 双字节数据:ms, deepth, ax, ay, az, gx, gy, gz 已经是正确的小端序
|
||
printf("%04d,%02d,%02d,%02d,%02d,%02d,%03d,%04d,%d,%d,%d,%d,%d,%d\n",
|
||
buffer[i].y + 2000, // 年份偏移2000
|
||
buffer[i].month, // 月
|
||
buffer[i].d, // 日
|
||
buffer[i].h, // 时
|
||
buffer[i].m, // 分
|
||
buffer[i].s, // 秒
|
||
buffer[i].ms, // 毫秒,uint16_t
|
||
buffer[i].deepth, // 深度,uint16_t
|
||
buffer[i].data.ax, // 加速度计x,int16_t
|
||
buffer[i].data.ay, // 加速度计y,int16_t
|
||
buffer[i].data.az, // 加速度计z,int16_t
|
||
buffer[i].data.gx, // 陀螺仪x,int16_t
|
||
buffer[i].data.gy, // 陀螺仪y,int16_t
|
||
buffer[i].data.gz // 陀螺仪z,int16_t
|
||
);
|
||
}
|
||
}
|
||
|
||
fclose(file);
|
||
|
||
fprintf(stderr, "共解析 %d 条记录\n", recordCount);
|
||
}
|
||
|
||
// 生成输出文件名
|
||
char* generate_output_filename(const char* input_file) {
|
||
size_t len = strlen(input_file);
|
||
char* output = (char*)malloc(len + 5); // +5 为了容纳 .csv 和结束符
|
||
|
||
// 复制输入文件名
|
||
strcpy(output, input_file);
|
||
|
||
// 找到最后一个点的位置
|
||
char* dot = strrchr(output, '.');
|
||
if (dot != NULL) {
|
||
// 如果找到点,在点的位置替换后缀
|
||
strcpy(dot, ".csv");
|
||
} else {
|
||
// 如果没有找到点,直接在末尾添加.csv
|
||
strcat(output, ".csv");
|
||
}
|
||
|
||
return output;
|
||
}
|
||
|
||
int main(int argc, char *argv[]) {
|
||
// 设置控制台输出代码页为 UTF-8
|
||
SetConsoleOutputCP(65001);
|
||
|
||
char *input_file = NULL;
|
||
char *output_file = NULL;
|
||
|
||
// 解析命令行参数
|
||
for (int i = 1; i < argc; i++) {
|
||
if (strcmp(argv[i], "-h") == 0) {
|
||
print_usage();
|
||
return 0;
|
||
}
|
||
else if (strcmp(argv[i], "-f") == 0) {
|
||
if (i + 1 < argc) {
|
||
input_file = argv[i + 1];
|
||
i++;
|
||
} else {
|
||
printf("错误:-f 参数后需要指定文件名\n");
|
||
print_usage();
|
||
return 1;
|
||
}
|
||
}
|
||
else if (strcmp(argv[i], "-o") == 0) {
|
||
if (i + 1 < argc) {
|
||
output_file = argv[i + 1];
|
||
i++;
|
||
} else {
|
||
printf("错误:-o 参数后需要指定文件名\n");
|
||
print_usage();
|
||
return 1;
|
||
}
|
||
}
|
||
else {
|
||
fprintf(stderr, "错误:未知参数 %s\n", argv[i]);
|
||
print_usage();
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
// 检查必需参数
|
||
if (input_file == NULL) {
|
||
fprintf(stderr, "错误:未指定输入文件\n");
|
||
print_usage();
|
||
return 1;
|
||
}
|
||
|
||
// 检查输入文件是否存在
|
||
FILE *file = fopen(input_file, "rb");
|
||
if (!file) {
|
||
printf("错误:无法打开输入文件 %s\n", input_file);
|
||
return 1;
|
||
}
|
||
fclose(file);
|
||
|
||
// 如果没有指定输出文件,生成默认的输出文件名
|
||
char *auto_output_file = NULL;
|
||
if (output_file == NULL) {
|
||
auto_output_file = generate_output_filename(input_file);
|
||
output_file = auto_output_file;
|
||
}
|
||
|
||
// 重定向标准输出到文件
|
||
if (freopen(output_file, "w", stdout) == NULL) {
|
||
printf("错误:无法创建输出文件 %s\n", output_file);
|
||
if (auto_output_file) free(auto_output_file);
|
||
return 1;
|
||
}
|
||
|
||
// 解析文件
|
||
decode(input_file);
|
||
|
||
// 清理
|
||
if (auto_output_file) {
|
||
free(auto_output_file);
|
||
}
|
||
|
||
return 0;
|
||
}
|