✨ feat(optic_mag): 集成光泵磁力仪驱动并重构数据包架构
- 新增光泵磁力仪驱动模块,通过 USART2 中断接收 BCD 编码数据,采样率 115200bps - 重构数据包架构:引入标准包与扩展包(含光泵数据)两种类型,通过帧头魔数区分 - 新增 DataPacketWithOptic_t、CorrectedDataPacketWithOptic_t 两种扩展数据包类型 - 数据存储改为通用字节流写入(方案Y),支持任意包类型混流存储 - 将编译期配置集中到 app_config.h,包括 UART 输出、SD 存储、GPS 位置等开关 - 移除 ADC_SYNC GPIO 引脚配置,释放 PA2 用于 USART2_TX - 主循环 ProcessAdcData 改为按需选择数据包类型,光泵数据快照在 ADC 中断前完成 - 新增 USART2 错误回调处理,支持接收异常时自动恢复
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#ifndef APP_CONFIG_H
|
||||
#define APP_CONFIG_H
|
||||
|
||||
// ============================================================
|
||||
// 系统编译期配置总入口
|
||||
// 所有可调参数集中在此文件,修改后重新编译生效。
|
||||
// 若需恢复 SD 卡运行时加载,将 CFG_LOAD_FROM_FILE 置 1,
|
||||
// 其余编译期值将作为加载失败时的 fallback 默认值。
|
||||
// ============================================================
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 配置加载方式
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// 是否在启动时从 SD 卡 CONFIG.TXT 加载配置
|
||||
// 1 = 运行时加载(文件内容覆盖以下编译期值)
|
||||
// 0 = 仅使用以下编译期值,不读取文件(安全,可重复)
|
||||
#define CFG_LOAD_FROM_FILE 0
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 数据输出控制
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// RS485 串口输出开关
|
||||
// 1 = 每帧 ADC 数据通过 USART1 以 2Mbps 发送
|
||||
// 0 = 禁用串口输出,降低功耗和 CPU 占用
|
||||
#define CFG_UART_OUTPUT_ENABLED 1
|
||||
|
||||
// SD 卡数据存储开关
|
||||
// 1 = 每帧数据写入 SD 卡 DATA/SESSION_xxx/ 目录下的文件
|
||||
// 0 = 禁用存储,SD 卡仅用于 USB MSC 访问
|
||||
#define CFG_STORAGE_ENABLED 1
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 功能模块开关
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// 系统监控统计模块
|
||||
// 1 = 启用:统计采样次数、丢帧数、SD 写入量、串口发送量,
|
||||
// 并定期输出到调试串口 / 写入 LOG.TXT
|
||||
// 0 = 禁用:相关代码被条件编译剔除,节省 Flash 和运行时开销
|
||||
#define CFG_ENABLE_SYSTEM_MONITOR 0
|
||||
|
||||
// 数据包中包含 GPS 经纬度和海拔字段
|
||||
// 1 = 每帧包含 latitude(float) + longitude(float) + altitude(float),包体增大 12 字节
|
||||
// 0 = 仅保留 GPS 时间戳(gps_time),包体更小,适合不需要位置信息的场景
|
||||
#define CFG_ENABLE_GPS_POSITION 0
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// 调试与监控定时参数
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// 调试信息通过 RS485 输出的时间间隔(毫秒)
|
||||
// 控制 DebugOutput_PrintSystemStats() 的调用频率
|
||||
// 建议范围:5000(5秒)~ 60000(1分钟)
|
||||
#define CFG_DEBUG_OUTPUT_INTERVAL_MS 30000
|
||||
|
||||
// 监控统计数据写入 SD 卡 LOG.TXT 的时间间隔(毫秒)
|
||||
// 间隔越短日志越详细,但 SD 卡写入操作越频繁
|
||||
// 建议范围:10000(10秒)~ 300000(5分钟)
|
||||
#define CFG_MONITOR_SAVE_INTERVAL_MS 30000
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SD 卡存储参数
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// SD 卡写入双缓冲区单个缓冲区大小(字节)
|
||||
// 更大的缓冲区可减少写入次数,提升吞吐量,但占用更多 RAM
|
||||
// STM32F405 RAM 为 192KB,建议不超过 65536(64KB)
|
||||
// 典型值:32768(32KB) / 65536(64KB)
|
||||
#define CFG_STORAGE_BUFFER_SIZE 32768
|
||||
|
||||
// 单个数据文件的最大大小(字节),超过后自动创建新文件
|
||||
// 较小的文件便于传输和分析,较大的文件减少文件切换开销
|
||||
// 典型值:100MB / 500MB / 1024MB
|
||||
#define CFG_STORAGE_FILE_MAX_SIZE (100 * 1024 * 1024)
|
||||
|
||||
|
||||
#endif // APP_CONFIG_H
|
||||
@@ -2,6 +2,7 @@
|
||||
#define CONFIG_MANAGER_H
|
||||
|
||||
#include "main.h"
|
||||
#include "app_config.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// 配置文件路径
|
||||
@@ -17,8 +18,8 @@ typedef struct {
|
||||
} SystemConfig_t;
|
||||
|
||||
// 默认配置值
|
||||
#define DEFAULT_UART_OUTPUT_ENABLED 1
|
||||
#define DEFAULT_STORAGE_ENABLED 0
|
||||
#define DEFAULT_UART_OUTPUT_ENABLED CFG_UART_OUTPUT_ENABLED
|
||||
#define DEFAULT_STORAGE_ENABLED CFG_STORAGE_ENABLED
|
||||
#define CONFIG_VERSION 0x00010000 // 版本 1.0.0
|
||||
|
||||
// 函数声明
|
||||
|
||||
+76
-92
@@ -2,8 +2,8 @@
|
||||
#include "stddef.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
// CRC16-MODBUS算法实现
|
||||
uint16_t Calculate_CRC16(const uint8_t *data, uint16_t len) {
|
||||
uint16_t Calculate_CRC16(const uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t crc = 0xFFFF;
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
crc ^= data[i];
|
||||
@@ -18,107 +18,91 @@ uint16_t Calculate_CRC16(const uint8_t *data, uint16_t len) {
|
||||
return crc;
|
||||
}
|
||||
|
||||
void PackData(DataPacket_t *packet, int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
// ─── 内部辅助宏:填充GPS位置字段(仅在宏开启时) ─────────────────────────────
|
||||
#ifdef ENABLE_GPS_POSITION
|
||||
#define FILL_GPS_POSITION(pkt, lat, lon, alt) \
|
||||
do { (pkt)->gps_latitude = (lat); (pkt)->gps_longitude = (lon); (pkt)->gps_altitude = (alt); } while(0)
|
||||
#else
|
||||
#define FILL_GPS_POSITION(pkt, lat, lon, alt) // 空操作
|
||||
#endif
|
||||
|
||||
// ─── 原始ADC数据包 ────────────────────────────────────────────────────────────
|
||||
|
||||
void PackData(DataPacket_t *packet,
|
||||
int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
|
||||
// 设置包头
|
||||
packet->start_byte = PACKET_START_BYTE;
|
||||
|
||||
// 设置时间戳
|
||||
// packet->timestamp = HAL_GetTick();
|
||||
|
||||
// 设置ADC数据
|
||||
packet->adc_data1 = adc1;
|
||||
packet->adc_data2 = adc2;
|
||||
packet->adc_data3 = adc3;
|
||||
|
||||
// 设置GPS数据
|
||||
packet->gps_time = gps_time;
|
||||
packet->gps_latitude = latitude;
|
||||
packet->gps_longitude = longitude;
|
||||
packet->gps_altitude = altitude;
|
||||
packet->start_byte = PACKET_TYPE_STANDARD;
|
||||
packet->adc_data1 = adc1;
|
||||
packet->adc_data2 = adc2;
|
||||
packet->adc_data3 = adc3;
|
||||
packet->gps_time = gps_time;
|
||||
FILL_GPS_POSITION(packet, latitude, longitude, altitude);
|
||||
}
|
||||
|
||||
void PackDataWithOptic(DataPacketWithOptic_t *packet,
|
||||
int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude,
|
||||
uint32_t optical_mag)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
packet->start_byte = PACKET_TYPE_WITH_OPTIC;
|
||||
packet->adc_data1 = adc1;
|
||||
packet->adc_data2 = adc2;
|
||||
packet->adc_data3 = adc3;
|
||||
packet->gps_time = gps_time;
|
||||
FILL_GPS_POSITION(packet, latitude, longitude, altitude);
|
||||
packet->optical_mag = optical_mag;
|
||||
}
|
||||
|
||||
// ─── 校正数据包 ───────────────────────────────────────────────────────────────
|
||||
|
||||
void PackCorrectedData(CorrectedDataPacket_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude)
|
||||
{
|
||||
PackCorrectedDataWithGPS(packet, x, y, z, gps_time, latitude, longitude, altitude);
|
||||
}
|
||||
|
||||
void PackCorrectedDataWithGPS(CorrectedDataPacketWithGPS_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
packet->start_byte = PACKET_TYPE_STANDARD;
|
||||
packet->corrected_x = x;
|
||||
packet->corrected_y = y;
|
||||
packet->corrected_z = z;
|
||||
packet->gps_time = gps_time;
|
||||
FILL_GPS_POSITION(packet, latitude, longitude, altitude);
|
||||
}
|
||||
|
||||
void PackCorrectedDataWithOptic(CorrectedDataPacketWithOptic_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude,
|
||||
uint32_t optical_mag)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
packet->start_byte = PACKET_TYPE_WITH_OPTIC;
|
||||
packet->corrected_x = x;
|
||||
packet->corrected_y = y;
|
||||
packet->corrected_z = z;
|
||||
packet->gps_time = gps_time;
|
||||
FILL_GPS_POSITION(packet, latitude, longitude, altitude);
|
||||
packet->optical_mag = optical_mag;
|
||||
}
|
||||
|
||||
// ─── 验证函数 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
uint8_t ValidatePacket(const DataPacket_t *packet)
|
||||
{
|
||||
if (packet == NULL) return 0;
|
||||
|
||||
// 检查包头
|
||||
if (packet->start_byte != PACKET_START_BYTE) return 0;
|
||||
|
||||
// 精简版数据包无校验和,仅检查包头
|
||||
return 1; // 包头正确,认为有效
|
||||
return (packet->start_byte == PACKET_TYPE_STANDARD) ? 1 : 0;
|
||||
}
|
||||
|
||||
uint8_t ValidateCorrectedPacket(const CorrectedDataPacket_t *packet)
|
||||
{
|
||||
if (packet == NULL) return 0;
|
||||
|
||||
// 检查包头
|
||||
if (packet->start_byte != PACKET_START_BYTE) return 0;
|
||||
|
||||
// 精简版数据包无校验和,仅检查包头
|
||||
return 1; // 包头正确,认为有效
|
||||
}
|
||||
|
||||
void PackCorrectedData(CorrectedDataPacket_t *packet, float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
|
||||
// 设置包头
|
||||
packet->start_byte = PACKET_START_BYTE;
|
||||
|
||||
// 设置时间戳
|
||||
// packet->timestamp = HAL_GetTick();
|
||||
|
||||
// 设置校正后数据
|
||||
packet->corrected_x = x;
|
||||
packet->corrected_y = y;
|
||||
packet->corrected_z = z;
|
||||
|
||||
// 设置GPS数据
|
||||
packet->gps_time = gps_time;
|
||||
packet->gps_latitude = latitude;
|
||||
packet->gps_longitude = longitude;
|
||||
packet->gps_altitude = altitude;
|
||||
}
|
||||
|
||||
void PackCorrectedDataWithGPS(CorrectedDataPacketWithGPS_t *packet, float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude)
|
||||
{
|
||||
if (packet == NULL) return;
|
||||
|
||||
// 设置包头
|
||||
packet->start_byte = PACKET_START_BYTE;
|
||||
|
||||
// 设置时间戳
|
||||
// packet->timestamp = HAL_GetTick();
|
||||
|
||||
// 设置校正后数据
|
||||
packet->corrected_x = x;
|
||||
packet->corrected_y = y;
|
||||
packet->corrected_z = z;
|
||||
|
||||
// 设置GPS数据
|
||||
packet->gps_time = gps_time;
|
||||
packet->gps_latitude = latitude;
|
||||
packet->gps_longitude = longitude;
|
||||
packet->gps_altitude = altitude;
|
||||
}
|
||||
|
||||
uint8_t ValidateCorrectedPacketWithGPS(const CorrectedDataPacketWithGPS_t *packet)
|
||||
{
|
||||
if (packet == NULL) return 0;
|
||||
|
||||
// 检查包头
|
||||
if (packet->start_byte != PACKET_START_BYTE) return 0;
|
||||
|
||||
// 精简版数据包无校验和,仅检查包头
|
||||
// 可以添加简单的数据合理性检查
|
||||
// 例如:检查GPS坐标是否在有效范围内等
|
||||
|
||||
return 1; // 包头正确,认为有效
|
||||
return (packet->start_byte == PACKET_TYPE_STANDARD) ? 1 : 0;
|
||||
}
|
||||
|
||||
+89
-39
@@ -2,59 +2,109 @@
|
||||
#define DATA_PACKET_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "app_config.h"
|
||||
|
||||
#define PACKET_START_BYTE 0xFFFFFFFF
|
||||
#define PACKET_END_BYTE 0x0000
|
||||
// 帧同步魔数(高3字节固定),低字节为类型标志
|
||||
#define PACKET_TYPE_STANDARD 0xFFFFFFFFUL // 标准包(无光泵)
|
||||
#define PACKET_TYPE_WITH_OPTIC 0xFFFFFFFEUL // 扩展包(含光泵,末尾追加 optical_mag)
|
||||
#define PACKET_SYNC_MASK 0xFFFFFF00UL // 同步检测掩码
|
||||
|
||||
// 兼容旧代码
|
||||
#define PACKET_START_BYTE PACKET_TYPE_STANDARD
|
||||
|
||||
// GPS位置字段由 app_config.h 中 CFG_ENABLE_GPS_POSITION 控制
|
||||
#if CFG_ENABLE_GPS_POSITION
|
||||
#define ENABLE_GPS_POSITION
|
||||
#endif
|
||||
|
||||
// ─── 原始ADC数据包 ────────────────────────────────────────────────────────────
|
||||
|
||||
// 数据包结构(精简版 - 有包头无校验和,含GPS)
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t start_byte; // 包头 (4字节) = 0xFFFFFFFF
|
||||
// uint32_t timestamp; // 系统时间戳 (4字节)
|
||||
int32_t adc_data1; // ADC1 数据 (4字节)
|
||||
int32_t adc_data2; // ADC2 数据 (4字节)
|
||||
int32_t adc_data3; // ADC3 数据 (4字节)
|
||||
uint32_t gps_time; // GPS时间戳 (4字节) HHMMSS格式
|
||||
float gps_latitude; // GPS纬度 (4字节)
|
||||
float gps_longitude; // GPS经度 (4字节)
|
||||
float gps_altitude; // GPS海拔 (4字节)
|
||||
uint32_t start_byte; // PACKET_TYPE_STANDARD
|
||||
int32_t adc_data1;
|
||||
int32_t adc_data2;
|
||||
int32_t adc_data3;
|
||||
uint32_t gps_time; // HHMMSS格式,始终存在
|
||||
#ifdef ENABLE_GPS_POSITION
|
||||
float gps_latitude;
|
||||
float gps_longitude;
|
||||
float gps_altitude;
|
||||
#endif
|
||||
} DataPacket_t;
|
||||
|
||||
// 校正后数据包结构(精简版 - 有包头无校验和,含GPS)
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t start_byte; // 包头 (4字节) = 0xFFFFFFFF
|
||||
// uint32_t timestamp; // 系统时间戳 (4字节)
|
||||
float corrected_x; // 校正后X轴数据 (4字节)
|
||||
float corrected_y; // 校正后Y轴数据 (4字节)
|
||||
float corrected_z; // 校正后Z轴数据 (4字节)
|
||||
uint32_t gps_time; // GPS时间戳 (4字节) HHMMSS格式
|
||||
float gps_latitude; // GPS纬度 (4字节)
|
||||
float gps_longitude; // GPS经度 (4字节)
|
||||
float gps_altitude; // GPS海拔 (4字节)
|
||||
uint32_t start_byte; // PACKET_TYPE_WITH_OPTIC
|
||||
int32_t adc_data1;
|
||||
int32_t adc_data2;
|
||||
int32_t adc_data3;
|
||||
uint32_t gps_time;
|
||||
#ifdef ENABLE_GPS_POSITION
|
||||
float gps_latitude;
|
||||
float gps_longitude;
|
||||
float gps_altitude;
|
||||
#endif
|
||||
uint32_t optical_mag; // 单位 0.0001 nT,例如 123456789 = 12345.6789 nT
|
||||
} DataPacketWithOptic_t;
|
||||
|
||||
// ─── 校正数据包 ───────────────────────────────────────────────────────────────
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t start_byte; // PACKET_TYPE_STANDARD
|
||||
float corrected_x;
|
||||
float corrected_y;
|
||||
float corrected_z;
|
||||
uint32_t gps_time;
|
||||
#ifdef ENABLE_GPS_POSITION
|
||||
float gps_latitude;
|
||||
float gps_longitude;
|
||||
float gps_altitude;
|
||||
#endif
|
||||
} CorrectedDataPacket_t;
|
||||
|
||||
// 带GPS信息的校正数据包结构(精简版 - 有包头无校验和)
|
||||
// 与 CorrectedDataPacket_t 相同,保留别名兼容旧代码
|
||||
typedef CorrectedDataPacket_t CorrectedDataPacketWithGPS_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t start_byte; // 包头 (4字节) = 0xFFFFFFFF
|
||||
// uint32_t timestamp; // 系统时间戳 (4字节)
|
||||
float corrected_x; // 校正后X轴数据 (4字节)
|
||||
float corrected_y; // 校正后Y轴数据 (4字节)
|
||||
float corrected_z; // 校正后Z轴数据 (4字节)
|
||||
uint32_t gps_time; // GPS时间戳 (4字节) HHMMSS格式
|
||||
float gps_latitude; // GPS纬度 (4字节)
|
||||
float gps_longitude; // GPS经度 (4字节)
|
||||
float gps_altitude; // GPS海拔 (4字节)
|
||||
} CorrectedDataPacketWithGPS_t;
|
||||
uint32_t start_byte; // PACKET_TYPE_WITH_OPTIC
|
||||
float corrected_x;
|
||||
float corrected_y;
|
||||
float corrected_z;
|
||||
uint32_t gps_time;
|
||||
#ifdef ENABLE_GPS_POSITION
|
||||
float gps_latitude;
|
||||
float gps_longitude;
|
||||
float gps_altitude;
|
||||
#endif
|
||||
uint32_t optical_mag; // 单位 0.0001 nT
|
||||
} CorrectedDataPacketWithOptic_t;
|
||||
|
||||
// ─── 函数声明 ─────────────────────────────────────────────────────────────────
|
||||
|
||||
// 函数声明
|
||||
uint16_t Calculate_CRC16(const uint8_t *data, uint16_t len);
|
||||
void PackData(DataPacket_t *packet, int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
|
||||
void PackData(DataPacket_t *packet,
|
||||
int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude);
|
||||
void PackCorrectedData(CorrectedDataPacket_t *packet, float x, float y, float z,
|
||||
|
||||
void PackDataWithOptic(DataPacketWithOptic_t *packet,
|
||||
int32_t adc1, int32_t adc2, int32_t adc3,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude,
|
||||
uint32_t optical_mag);
|
||||
|
||||
void PackCorrectedData(CorrectedDataPacket_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude);
|
||||
void PackCorrectedDataWithGPS(CorrectedDataPacketWithGPS_t *packet, float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float , float altitude);
|
||||
|
||||
void PackCorrectedDataWithGPS(CorrectedDataPacketWithGPS_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude);
|
||||
|
||||
void PackCorrectedDataWithOptic(CorrectedDataPacketWithOptic_t *packet,
|
||||
float x, float y, float z,
|
||||
uint32_t gps_time, float latitude, float longitude, float altitude,
|
||||
uint32_t optical_mag);
|
||||
|
||||
uint8_t ValidatePacket(const DataPacket_t *packet);
|
||||
uint8_t ValidateCorrectedPacket(const CorrectedDataPacket_t *packet);
|
||||
uint8_t ValidateCorrectedPacketWithGPS(const CorrectedDataPacketWithGPS_t *packet);
|
||||
|
||||
#endif // DATA_PACKET_H
|
||||
|
||||
@@ -113,6 +113,41 @@ HAL_StatusTypeDef DataStorage_WriteData(DataStorageHandle_t *handle, const DataP
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通用字节流写入,支持任意包长度(方案Y混流存储)
|
||||
* @param handle: 数据存储句柄指针
|
||||
* @param data: 数据缓冲区指针
|
||||
* @param size: 写入字节数
|
||||
* @retval HAL_StatusTypeDef
|
||||
*/
|
||||
HAL_StatusTypeDef DataStorage_WriteRawBytes(DataStorageHandle_t *handle, const uint8_t *data, uint16_t size)
|
||||
{
|
||||
if (handle == NULL || data == NULL || !handle->initialized || size == 0) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
if (handle->stats.state != DATA_STORAGE_RECORDING) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
DataBuffer_t *active_buf = &handle->buffers[handle->active_buffer];
|
||||
|
||||
if (active_buf->index + size > DATA_STORAGE_BUFFER_SIZE) {
|
||||
if (DataStorage_SwitchBuffer(handle) != HAL_OK) {
|
||||
handle->stats.error_count++;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
active_buf = &handle->buffers[handle->active_buffer];
|
||||
}
|
||||
|
||||
memcpy(&active_buf->data[active_buf->index], data, size);
|
||||
active_buf->index += size;
|
||||
active_buf->state = BUFFER_WRITING;
|
||||
handle->stats.total_samples++;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 写入校正后的数据包到存储
|
||||
* @param handle: 数据存储句柄指针
|
||||
|
||||
+7
-3
@@ -2,15 +2,16 @@
|
||||
#define DATA_STORAGE_H
|
||||
|
||||
#include "main.h"
|
||||
#include "app_config.h"
|
||||
#include "fatfs.h"
|
||||
#include "ff.h"
|
||||
#include "data_packet.h"
|
||||
#include "correction.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// 数据存储配置
|
||||
#define DATA_STORAGE_BUFFER_SIZE 32768 // 缓冲区大小(字节)
|
||||
#define DATA_STORAGE_FILE_MAX_SIZE (100*1024*1024) // 单个文件最大100MB
|
||||
// 数据存储配置(数值由 app_config.h 中 CFG_* 统一管理)
|
||||
#define DATA_STORAGE_BUFFER_SIZE CFG_STORAGE_BUFFER_SIZE
|
||||
#define DATA_STORAGE_FILE_MAX_SIZE CFG_STORAGE_FILE_MAX_SIZE
|
||||
#define DATA_STORAGE_BASE_PATH "0:/DATA" // 数据存储基础路径
|
||||
#define DATA_STORAGE_FILE_PREFIX "/ADC_DATA_" // 文件名前缀
|
||||
#define DATA_STORAGE_FOLDER_PREFIX "SESSION_" // 文件夹名前缀
|
||||
@@ -87,4 +88,7 @@ void DataStorage_ProcessBackgroundTasks(DataStorageHandle_t *handle);
|
||||
// 缓冲区可用性检查函数
|
||||
uint8_t DataStorage_IsBufferAvailable(DataStorageHandle_t *handle, uint32_t required_size);
|
||||
|
||||
// 通用字节流写入(支持任意包类型,方案Y混流存储)
|
||||
HAL_StatusTypeDef DataStorage_WriteRawBytes(DataStorageHandle_t *handle, const uint8_t *data, uint16_t size);
|
||||
|
||||
#endif // DATA_STORAGE_H
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "optic_mag_driver.h"
|
||||
|
||||
volatile uint32_t g_optic_mag_value = 0;
|
||||
volatile uint8_t g_optic_mag_fresh = 0;
|
||||
|
||||
typedef enum {
|
||||
OPTIC_STATE_IDLE = 0,
|
||||
OPTIC_STATE_COLLECTING,
|
||||
OPTIC_STATE_WAIT_END,
|
||||
} OpticState_t;
|
||||
|
||||
static UART_HandleTypeDef *s_huart;
|
||||
static uint8_t s_rx_byte;
|
||||
static uint8_t s_bcd_buf[OPTIC_MAG_DATA_BYTES];
|
||||
static uint8_t s_data_count;
|
||||
static OpticState_t s_state;
|
||||
|
||||
void OpticMag_Init(UART_HandleTypeDef *huart)
|
||||
{
|
||||
s_huart = huart;
|
||||
s_state = OPTIC_STATE_IDLE;
|
||||
s_data_count = 0;
|
||||
HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
|
||||
}
|
||||
|
||||
void OpticMag_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart != s_huart) return;
|
||||
|
||||
uint8_t byte = s_rx_byte;
|
||||
|
||||
switch (s_state) {
|
||||
case OPTIC_STATE_IDLE:
|
||||
if (byte == OPTIC_MAG_FRAME_START) {
|
||||
s_data_count = 0;
|
||||
s_state = OPTIC_STATE_COLLECTING;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTIC_STATE_COLLECTING:
|
||||
s_bcd_buf[s_data_count++] = byte;
|
||||
if (s_data_count == OPTIC_MAG_DATA_BYTES) {
|
||||
s_state = OPTIC_STATE_WAIT_END;
|
||||
}
|
||||
break;
|
||||
|
||||
case OPTIC_STATE_WAIT_END:
|
||||
if (byte == OPTIC_MAG_FRAME_END) {
|
||||
// 取前9位BCD数字(忽略第10位),每字节低nibble为有效数字
|
||||
uint32_t value = 0;
|
||||
for (uint8_t i = 0; i < 9; i++) {
|
||||
value = value * 10u + (s_bcd_buf[i] & 0x0Fu);
|
||||
}
|
||||
g_optic_mag_value = value;
|
||||
g_optic_mag_fresh = 1;
|
||||
}
|
||||
// 无论结束字节是否合法,均回到IDLE(非法帧直接丢弃)
|
||||
s_state = OPTIC_STATE_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
|
||||
}
|
||||
|
||||
void OpticMag_UART_ErrorCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart != s_huart) return;
|
||||
s_state = OPTIC_STATE_IDLE;
|
||||
HAL_UART_Receive_IT(s_huart, &s_rx_byte, 1);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef OPTIC_MAG_DRIVER_H
|
||||
#define OPTIC_MAG_DRIVER_H
|
||||
|
||||
#include "main.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#define OPTIC_MAG_FRAME_START 0x5A
|
||||
#define OPTIC_MAG_FRAME_END 0xA5
|
||||
#define OPTIC_MAG_DATA_BYTES 10
|
||||
|
||||
// 单位 0.0001 nT,忽略末位BCD数字,取前9位
|
||||
// 例如 123456789 表示 12345.6789 nT
|
||||
extern volatile uint32_t g_optic_mag_value;
|
||||
extern volatile uint8_t g_optic_mag_fresh;
|
||||
|
||||
void OpticMag_Init(UART_HandleTypeDef *huart);
|
||||
void OpticMag_UART_RxCpltCallback(UART_HandleTypeDef *huart);
|
||||
void OpticMag_UART_ErrorCallback(UART_HandleTypeDef *huart);
|
||||
|
||||
#endif // OPTIC_MAG_DRIVER_H
|
||||
Reference in New Issue
Block a user