FMCW 雷达中距离和速度信息的一维数组分配到二维矩阵
Assignment of 1d array into 2d matrix for range and speed information in FMCW radar
我正在使用 fmcw 雷达通过 stm32l476 微控制器查找移动物体的距离和速度信息。
首先,为了获取文具对象的范围,我使用“HAL_ADC_ConvCpltCallback”函数将ADC值存储到“fft_in”数组中。这里我初始化了“is_data_ready_for_fft = 1”如下:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1) {
is_data_ready_for_fft = 1;
}
并使用 fft 计算范围。现在我需要将这个 ADC 值的一维数组存储在二维数组中,以计算跨线性调频指数的多普勒频率。
下面是将 adc 值复制到 fft_in 数组和范围计算的代码:
while (1)
{
if (is_data_ready_for_fft == 1) {
for (size_t i = 0; i < ADC_BUF_LENGTH; i++) {
fft_in[i] = (float32_t) adcResultsDMA[i];
}
is_data_ready_for_fft = 0;
arm_rfft_fast_f32(&fft_handler, fft_in, fft_out, 0);
arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
fft_out2[0] = 0;
arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);
R = (300000000 * 0.004064* Index)/500000000;
}
}
以上代码将值复制到 fft_in 数组中。
这里 ADC_BUF_LENGTH = 512;
现在我的问题是如何将这个 fft_in 缓冲区添加到矩阵中,如下所示:
假设 fft_in 数组每秒变化一次:
所以这里 fft_in(0), fft_in(1), fft_in(2),......fft_in(20) 是 fft_in在那个特定时间具有 ADC_values 的数组。
[0,0]=fft_in(0)[0] [0,1]=fft_in(0)[1]..............[0,512]=fft_in(0)[512]
[1,0]=fft_in(1)[0] [1,1]=fft_in(1)[1]..............[1,512]=fft_in(1)[512]
[2,0]=fft_in(2)[0] [2,1]=fft_in(2)[1]..............[2,512]=fft_in(2)[512]
.
.
.
.
[19,0]=fft_in(19)[0] [19,1]=fft_in(19)[1].............[19,512]=fft_in(19)[512]
(我将 Chirp 指数设为 20,样本数设为 512。因此跨行的 fft 产生范围,跨列的 fft 产生速度)
我认为您正在寻找二维数组。你可以这样声明一个 float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];
。 NBR_SAMPLES_PER_CHIRP
是您放置在一个线性调频期间采样的值的列(在您的情况下为 512 个样本)。 NBR_CHIRPS_PER_FRAME
是一帧中的线性调频数的行,在您的情况下为 20。
要访问数组的一个元素,您需要两个嵌套的for-loops。这里有一个 code-snippet 用于此目的。
for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
{
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
/*acess the element*/
fftIn2D[chirpIdx][sampleIdx] = (float32_t) adcResultsDMA[i]
}
}
对于您的代码,可以这样锁定:
float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];
fftInDoppler[NBR_CHIRPS_PER_FRAME];
uint32_t chirpIdxGlobal = 0;
while (1)
{
if (is_data_ready_for_fft == 1) {
is_data_ready_for_fft = 0;
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
fftIn2D[chirpIdxGlobal][sampleIdx] = (float32_t) adcResultsDMA[i];
}
chirpIdxGlobal++;
if(chirpIdxGlobal == (NBR_CHIRPS_PER_FRAME - 1)){
is_data_ready_for_doppler_fft = 1;
}
arm_rfft_fast_f32(&fft_handler, &fftIn2D[sampleIdx][0], fft_out, 0);
arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
fft_out2[0] = 0;
arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);
R = (300000000 * 0.004064* Index)/500000000;
}
if (is_data_ready_for_doppler_fft){
chirpIdxGlobal = 0;
is_data_ready_for_doppler_fft = 0;
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
/* bring the data in the right order for the fft */
for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
{
fftInDoppler[chirpIdx] = fftIn2D[chirpIdx][sampleIdx];
}
arm_rfft_fast_f32(&fft_handler, &fftInDoppler[0], fft_out_doppler, 0);
arm_cmplx_mag_f32(fft_out_doppler, fft_out2_doppler, ADC_BUF_LENGTH);
fft_out2_doppler[0] = 0;
arm_max_f32(fft_out2_doppler, ADC_BUF_LENGTH/2, &Result, &Index);
}
}
}
这里是我的代码片段的注释,您还可以在 FFT(第一个 FFT)范围内检测到目标的样本上计算第二个 FFT,而不是在每个样本上。
请记住,fft 需要一些计算时间,也许您需要在计算之前对一帧的所有数据进行采样。
我正在使用 fmcw 雷达通过 stm32l476 微控制器查找移动物体的距离和速度信息。
首先,为了获取文具对象的范围,我使用“HAL_ADC_ConvCpltCallback”函数将ADC值存储到“fft_in”数组中。这里我初始化了“is_data_ready_for_fft = 1”如下:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc1) {
is_data_ready_for_fft = 1;
}
并使用 fft 计算范围。现在我需要将这个 ADC 值的一维数组存储在二维数组中,以计算跨线性调频指数的多普勒频率。
下面是将 adc 值复制到 fft_in 数组和范围计算的代码:
while (1)
{
if (is_data_ready_for_fft == 1) {
for (size_t i = 0; i < ADC_BUF_LENGTH; i++) {
fft_in[i] = (float32_t) adcResultsDMA[i];
}
is_data_ready_for_fft = 0;
arm_rfft_fast_f32(&fft_handler, fft_in, fft_out, 0);
arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
fft_out2[0] = 0;
arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);
R = (300000000 * 0.004064* Index)/500000000;
}
}
以上代码将值复制到 fft_in 数组中。 这里 ADC_BUF_LENGTH = 512; 现在我的问题是如何将这个 fft_in 缓冲区添加到矩阵中,如下所示: 假设 fft_in 数组每秒变化一次: 所以这里 fft_in(0), fft_in(1), fft_in(2),......fft_in(20) 是 fft_in在那个特定时间具有 ADC_values 的数组。
[0,0]=fft_in(0)[0] [0,1]=fft_in(0)[1]..............[0,512]=fft_in(0)[512]
[1,0]=fft_in(1)[0] [1,1]=fft_in(1)[1]..............[1,512]=fft_in(1)[512]
[2,0]=fft_in(2)[0] [2,1]=fft_in(2)[1]..............[2,512]=fft_in(2)[512]
.
.
.
.
[19,0]=fft_in(19)[0] [19,1]=fft_in(19)[1].............[19,512]=fft_in(19)[512]
(我将 Chirp 指数设为 20,样本数设为 512。因此跨行的 fft 产生范围,跨列的 fft 产生速度)
我认为您正在寻找二维数组。你可以这样声明一个 float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];
。 NBR_SAMPLES_PER_CHIRP
是您放置在一个线性调频期间采样的值的列(在您的情况下为 512 个样本)。 NBR_CHIRPS_PER_FRAME
是一帧中的线性调频数的行,在您的情况下为 20。
要访问数组的一个元素,您需要两个嵌套的for-loops。这里有一个 code-snippet 用于此目的。
for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
{
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
/*acess the element*/
fftIn2D[chirpIdx][sampleIdx] = (float32_t) adcResultsDMA[i]
}
}
对于您的代码,可以这样锁定:
float32_t fftIn2D[NBR_CHIRPS_PER_FRAME][NBR_SAMPLES_PER_CHIRP];
fftInDoppler[NBR_CHIRPS_PER_FRAME];
uint32_t chirpIdxGlobal = 0;
while (1)
{
if (is_data_ready_for_fft == 1) {
is_data_ready_for_fft = 0;
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
fftIn2D[chirpIdxGlobal][sampleIdx] = (float32_t) adcResultsDMA[i];
}
chirpIdxGlobal++;
if(chirpIdxGlobal == (NBR_CHIRPS_PER_FRAME - 1)){
is_data_ready_for_doppler_fft = 1;
}
arm_rfft_fast_f32(&fft_handler, &fftIn2D[sampleIdx][0], fft_out, 0);
arm_cmplx_mag_f32(fft_out, fft_out2, ADC_BUF_LENGTH);
fft_out2[0] = 0;
arm_max_f32(fft_out2, ADC_BUF_LENGTH/2, &Result, &Index);
R = (300000000 * 0.004064* Index)/500000000;
}
if (is_data_ready_for_doppler_fft){
chirpIdxGlobal = 0;
is_data_ready_for_doppler_fft = 0;
for (uint32_t sampleIdx = 0; sampleIdx < NBR_SAMPLES_PER_CHIRP; sampleIdx++)
{
/* bring the data in the right order for the fft */
for (uint32_t chirpIdx = 0; chirpIdx < NBR_CHIRPS_PER_FRAME; chirpIdx++)
{
fftInDoppler[chirpIdx] = fftIn2D[chirpIdx][sampleIdx];
}
arm_rfft_fast_f32(&fft_handler, &fftInDoppler[0], fft_out_doppler, 0);
arm_cmplx_mag_f32(fft_out_doppler, fft_out2_doppler, ADC_BUF_LENGTH);
fft_out2_doppler[0] = 0;
arm_max_f32(fft_out2_doppler, ADC_BUF_LENGTH/2, &Result, &Index);
}
}
}
这里是我的代码片段的注释,您还可以在 FFT(第一个 FFT)范围内检测到目标的样本上计算第二个 FFT,而不是在每个样本上。
请记住,fft 需要一些计算时间,也许您需要在计算之前对一帧的所有数据进行采样。