4. 原始数据采集:DCA1000数据格式、LVDS接口、数据解析、Bin文件结构

做毫米波雷达开发,第一步就是拿到原始数据。这一步要是搞错了,后面所有算法都是白搭。我见过不少新手,算法仿真跑得飞起,一上硬件就抓瞎——说白了,就是数据格式没吃透。

今天咱们就聊聊DCA1000采集卡、LVDS接口、数据解析,还有那个让人又爱又恨的bin文件。嗯,这里要注意,不同TI芯片的bin文件结构其实有细微差别,我会把通用的规律讲清楚。

4.1 DCA1000是什么?为什么需要它?

DCA1000是TI官方出的数据采集卡。它的作用很简单:把雷达芯片的LVDS信号转成USB或者以太网数据,送到PC上。

你可能会问:雷达芯片自己不是能处理数据吗?为什么还要外挂采集卡?

原因有两个:

  • 调试阶段需要看原始数据——芯片内部的DSP处理完就丢了,你根本不知道中间发生了什么
  • 算法开发需要大量数据——采集真实场景数据,离线跑算法,调参数

我在项目里遇到过一件事:客户说目标检测不准,我拿DCA1000抓了原始数据一看,原来是ADC饱和了。要是没有原始数据,这种问题根本查不出来。

4.2 LVDS接口——高速数据传输的通道

LVDS全称是Low-Voltage Differential Signaling,低压差分信号。说白了,就是用两根线传一个信号,抗干扰能力强,速率高。

TI的毫米波芯片(比如IWR6843、AWR1843)都支持LVDS输出。典型配置是这样的:

参数 典型值 说明
LVDS通道数 2或4 取决于芯片型号
数据速率 600 Mbps / 通道 4通道可达2.4 Gbps
数据格式 12位或16位 I/Q两路交替
时钟 差分时钟 与数据同步

DCA1000通过FPC排线连接到雷达板,把LVDS信号接收下来,再打包成以太网帧发出去。这个过程是硬件自动完成的,我们只需要关心数据到了PC端怎么解析。

我的经验:LVDS布线要特别注意等长。我吃过一次亏,排线太长导致数据错位,折腾了两天才发现是物理连接的问题。建议排线长度控制在15cm以内。

4.3 DCA1000的数据格式——以太网包结构

DCA1000通过千兆以太网发送数据。每个以太网包的结构是这样的:

以太网帧结构:
+------------------+------------------+------------------+
|  UDP Header      |  DCA1000 Header  |  Raw Data        |
|  8 bytes         |  36 bytes        |  1460 bytes max  |
+------------------+------------------+------------------+

DCA1000 Header里包含关键信息:

  • Magic Word:固定值0xA5A5,用来校验同步
  • Frame Number:帧序号,检查丢包
  • Packet Number:包序号,一帧可能拆成多个包
  • Data Length:有效数据长度

我建议你在解析时先检查Magic Word。如果不对,说明同步丢了,需要重新开始。这个坑我踩过——有一次网线接触不良,数据全是乱的,程序还在傻傻地解析。

4.4 Bin文件结构——数据存储的格式

DCA1000采集软件(mmWave Studio)会把数据存成.bin文件。这个文件的结构很多人搞不清楚,其实很简单:

Bin文件结构:
+------------------+
|  Header (可选)    |  <-- 有些版本没有
+------------------+
|  Frame 0          |
|    +-- Chirp 0   |
|    +-- Chirp 1   |
|    +-- ...       |
|    +-- Chirp N-1 |
+------------------+
|  Frame 1          |
|    ...            |
+------------------+
|  Frame M-1        |
|    ...            |
+------------------+

每个Chirp的数据排列方式:

  • 单通道模式:I0, Q0, I1, Q1, I2, Q2, ...
  • 双通道模式:Rx0_I, Rx0_Q, Rx1_I, Rx1_Q, ...
  • 四通道模式:四个接收通道交替排列

数据是12位或16位整数,以小端格式存储。嗯,这里要注意:TI的芯片默认是12位ADC,但DCA1000会左对齐成16位,所以解析时按16位读就行。

避坑指南:我曾经遇到过bin文件解析出来全是噪声,查了半天发现是字节序搞反了。TI用的是小端(Little Endian),如果你用大端解析,数据就全乱了。记得用struct.unpack('<H', data)而不是'>H'。

4.5 数据解析实战——Python代码

下面是我常用的解析代码,你可以直接拿去用:

import numpy as np
import struct

def parse_dca1000_bin(file_path, num_chirps, num_samples, num_rx=4):
    """
    解析DCA1000采集的bin文件
    
    参数:
        file_path: bin文件路径
        num_chirps: 每帧的chirp数
        num_samples: 每个chirp的采样点数
        num_rx: 接收通道数(1/2/4)
    
    返回:
        data: 复数数组,形状为(num_frames, num_chirps, num_rx, num_samples)
    """
    # 读取原始二进制数据
    raw_data = np.fromfile(file_path, dtype=np.int16)
    
    # 计算每帧需要的采样点数
    samples_per_frame = num_chirps * num_rx * num_samples * 2  # 乘以2是因为I/Q
    
    # 计算总帧数
    num_frames = len(raw_data) // samples_per_frame
    
    # 重塑数据
    data = raw_data[:num_frames * samples_per_frame]
    data = data.reshape(num_frames, num_chirps, num_rx, num_samples, 2)
    
    # 合并I/Q为复数
    complex_data = data[..., 0] + 1j * data[..., 1]
    
    return complex_data

# 使用示例
if __name__ == '__main__':
    # 假设配置:64个chirp,每chirp 256个采样点,4个接收通道
    data = parse_dca1000_bin('adc_data.bin', 64, 256, 4)
    print(f'数据维度: {data.shape}')
    print(f'数据类型: {data.dtype}')

这段代码我用了好几年,基本没出过问题。但要注意:如果你的bin文件有Header,需要先跳过前36个字节。怎么判断有没有Header?看文件大小是不是刚好等于理论值。如果多了36字节,那就是有Header。

4.6 常见问题与调试技巧

在实际采集过程中,你可能会遇到这些问题:

  1. 数据全是0——检查LVDS连接,或者DCA1000供电是否正常
  2. 数据有周期性跳变——可能是时钟抖动,检查时钟源
  3. 帧数不对——检查UDP丢包,可以用Wireshark抓包看看
  4. I/Q不平衡——这是硬件特性,需要在算法里做校正

我的调试流程:

  1. 先用mmWave Studio自带的工具采集,确认硬件没问题
  2. 用上面的Python脚本解析,看数据波形是否正常
  3. 做一次简单的FFT,看距离维有没有峰值
  4. 如果都正常,再接入自己的算法流程

你想想看,如果第一步就错了,后面再花哨的算法都是白费功夫。所以数据采集和解析这块,一定要稳扎稳打。

好了,这一章就到这里。下一章我们会聊数据预处理——怎么把原始ADC数据变成我们真正需要的距离-多普勒图。到时候我会分享一些我在项目中用到的滤波和校正技巧,保证实用。