- 新增光泵磁力仪驱动模块,通过 USART2 中断接收 BCD 编码数据,采样率 115200bps - 重构数据包架构:引入标准包与扩展包(含光泵数据)两种类型,通过帧头魔数区分 - 新增 DataPacketWithOptic_t、CorrectedDataPacketWithOptic_t 两种扩展数据包类型 - 数据存储改为通用字节流写入(方案Y),支持任意包类型混流存储 - 将编译期配置集中到 app_config.h,包括 UART 输出、SD 存储、GPS 位置等开关 - 移除 ADC_SYNC GPIO 引脚配置,释放 PA2 用于 USART2_TX - 主循环 ProcessAdcData 改为按需选择数据包类型,光泵数据快照在 ADC 中断前完成 - 新增 USART2 错误回调处理,支持接收异常时自动恢复
109 lines
4.2 KiB
C
109 lines
4.2 KiB
C
#include "data_packet.h"
|
||
#include "stddef.h"
|
||
#include "stm32f4xx_hal.h"
|
||
|
||
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];
|
||
for (uint8_t j = 0; j < 8; j++) {
|
||
if (crc & 0x0001) {
|
||
crc = (crc >> 1) ^ 0xA001;
|
||
} else {
|
||
crc = crc >> 1;
|
||
}
|
||
}
|
||
}
|
||
return crc;
|
||
}
|
||
|
||
// ─── 内部辅助宏:填充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_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;
|
||
return (packet->start_byte == PACKET_TYPE_STANDARD) ? 1 : 0;
|
||
}
|
||
|
||
uint8_t ValidateCorrectedPacket(const CorrectedDataPacket_t *packet)
|
||
{
|
||
if (packet == NULL) return 0;
|
||
return (packet->start_byte == PACKET_TYPE_STANDARD) ? 1 : 0;
|
||
}
|