0

我需要在STM32F446微控制器上对8192 个样本块执行FFT。为此,我想使用CMSIS DSP 库,因为它很容易获得并且针对 STM32F4 进行了优化。

我的 8192 个输入样本最终将是来自内部 12 位 ADC 的值(左对齐并通过翻转符号位转换为 q15)。但出于测试目的,我正在为 FFT 提供测试缓冲区。

使用 CMSIS 的 FFT 函数,只有 Q15 版本支持 8192 的长度。因此我使用arm_rfft_q15()

因为 CMSIS 库的 FFT 函数默认包含大约 32k 的 LUT——为了适应许多 FFT 长度,我已经“重写”它们以删除与我感兴趣的长度不同的所有表。我没有除了删除无用的代码之外,t 触及任何东西。

我的样本存储在我通过 DMA 访问的外部 SDRAM 上。

使用 FFT 时,我有几个问题:

  • 我的源缓冲区和目标缓冲区都被修改了;
  • 结果完全不像预期的那样

为了确保我得到错误的结果,我在 FFT 之后立即进行了 IFFT,但它只是确认代码不起作用。

这是我的代码:

status_codes FSM::fft_state(void)
{
  // Flush the SDRAM section
  si_ovf_buf_clr_u16((uint16_t *)0xC0000000, 8192);
  q15_t* buf = (q15_t*)(0xC0000000);
  for(int i = 0; i<50; i++)
    buf[i] = 0x0FFF; // Fill the buffer with test vector (50 sp gate)

  // initialise FFT
  // ---> Forward, 8192 samples, bitReversed
  arm_rfft_instance_q15 S;
  if(arm_rfft_init_q15(&S, 8192, 0, 1) != ARM_MATH_SUCCESS)
    return state_error;

  // perform FFT
  arm_rfft_q15(&S, (q15_t*)0xC0000000, (q15_t*)0xC0400000);

  // Post-shift by 12, in place (see doc)
  arm_shift_q15((q15_t*)0xC0400000, 12, (q15_t*)0xC0400000, 16384);

  // Init inverse FFT
  if(arm_rfft_init_q15(&S, 8192, 1, 1) != ARM_MATH_SUCCESS)
    return state_error;

  // Perform iFFT
  arm_rfft_q15(&S, (q15_t*)0xC0400000, (q15_t*)0xC0800000);

  // Post shift
  arm_shift_q15((q15_t*)0xC0800000, 12, (q15_t*)0xC0800000, 8192);

  return state_success;
}

这是结果(来自 GDB)

GDB 结果

PS:我正在使用ChibiOS - 不确定它是否相关。

4

0 回答 0