1

目前,我正在尝试通过使用 STM32F411RE 板上的 CMSIS 包来实现一个程序来查找 3 个频率(xs = 30.1 kHz、ys = 28.3 kHz 和 zs = 25.9 kHz)。我无法让复数 FFT (CFFT) 和复数幅度正常工作。

根据频率箱,我生成一个包含这些频率的数组,以便我可以手动查找信号 xs、ys 和 zs 所在的索引箱。然后,我使用该索引查看 3 个 fft 结果(Xfft、Yfft、Zfft)以找到这些信号的结果,但它们不匹配。

我使用以下功能顺序:

DMA ADC 缓冲区: 将 ADC 输入更改为浮动 Xfft CFFT_F32: 复数幅度HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
中的频率箱 :binfreqs

arm_cfft_f32(&arm_cfft_sR_f32_len1024, Xfft, 0, 0);
arm_cmplx_mag_f32(Xfft, Xdsp, fftLen);

// ADC Stuff done via DMA, working correctly

int main(void)
{

    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_ADC1_Init();
    MX_USART2_UART_Init();
    HAL_ADC_Start_DMA(&hadc1, adc_buffer, bufferLen); // adc_buffer needs to be an uint32_t

   while (1)
    {

        /**
         * Generate the frequencies
         */
        for (int binfreqs = 0; binfreqs < fftLen; binfreqs++)   // Generates the frequency bins to relate the amplitude to an actual value, rather than a bin frequency value
        {
            fftFreq[binfreqs] = binfreqs * binSize;
        }

        /*
         * Find the amplitudes associated with the 3 emitter frequencies and store in an array for each axis. By default these arrays are generated with signal strength 0
         *  and with frequency index at 0: because of system limits these will indicate invalid values, as system range is from 10 - 60 kHz.
         */
        volatile int32_t X_mag[3][4] =  // x axis values: [index][frequency][signal_strength][phase]
        {
            {0, Xfreq, 0, 0},   // For x-freq index [0][0], frequency [0][1] associated with 1st biggest amplitude [0][2], phase [0][3]
            {0, Yfreq, 0, 0},   // Ditto for y-freq
            {0, Zfreq, 0, 0}    // Ditto for z-freq
        };


        /*
         * Finds the index in fftFreq corresponding to respectively X, Y and Z emitter frequencies
         */
        for(int binSearch = 0; binSearch < fftLen; binSearch++)
        {
            if(fftFreq[binSearch] == Xfreq) // Find index for X emitter frequency
            {
              X_mag[0][0] = binSearch;
            }

            if(fftFreq[binSearch] == Yfreq) // Find index for Y emitter frequency
            {
              X_mag[1][0] = binSearch;
            }

            if(fftFreq[binSearch] == Zfreq) // Find index for Z emitter frequency
            {
              X_mag[2][0] = binSearch;
            }
        }

信号处理


        /* Signal processing algorithms --------------------------------------------------
         *
         * Only to be run once with fresh data from the buffer, [do not run continuous] or position / orientation data will be repeated.
         * So only run once when conversionPaused
         */
        if(conversionPaused)
        {

            /*
             * Convert signal to voltage (12-bit, 4096)
             */
            for (int floatVals = 0; floatVals < fftLen; floatVals++)
            {
                Xfft[floatVals] = (float) Xin[floatVals]; * 3.6 / 4096
            }

            /*
             * Fourier transform
             */
            arm_cfft_f32(&arm_cfft_sR_f32_len1024, Xfft, 0, 0); // Calculate complex fourier transform of x time signal, processing occurs in place

            for (int fix_fft = 0 ; fix_fft < half_fftLen ; fix_fft++)
            {
                Xfft[fix_fft] = 2 * Xfft[fix_fft] / fftLen;
                Xfft[fix_fft + half_fftLen] = 0;
            }

           /*
            * Amplitude calculation
            */
            arm_cmplx_mag_f32(Xfft, Xdsp, fftLen);  // Calculate the magnitude of the fourier transform for x axis

            /*
             *  Finds all signal strengths for allocated frequency indexes
             */
            for(int strength_index = 0; strength_index < 3; strength_index++) // Loops through xyz frequencies for all 3 magnetometer axis
            {
                int x_temp_index = X_mag[strength_index][0]; // temp int necessary to store the strength, otherwise infinite loop?
                X_mag[strength_index][2] = Xfft[x_temp_index]; // = Xfft[2*x_temp_index];

            }
            conversionPaused = 0;
          }
      } // While() end
} // Main() end

我不知道如何计算 cfft 和复数幅度的这种组合的频率区间,因为我希望数组的偶数索引保存实际值,而数组的奇数索引保存虚相位值。我引用了一些1 2 3 个示例,但无法弄清楚我的代码做错了什么。

然而,根据图像,当应用 30.1 kHz 的输入信号时,301 bin 索引或 602 bin 索引都不会保持预期的相应输出?

301 bin 索引

602 bin 索引


编辑:

此后,我尝试实现此处给出的 arm_cfft_f32 示例。后一个示例完全被破坏了,因为默认情况下不再包含外部 10 kHz 数据集,并且尝试包含它是不可能的,因为程序的行为很差,并且一直在错误地返回甚至根本不存在的返回数据类型。因此我不能使用为此给出的示例程序:它似乎也已经过时了 4 年,所以这并不奇怪。

arm_max_f32() 函数也被证明没有成效,因为它通过使用模拟生成的信号不断追踪在 bin 0 处生成的噪声。手动将此 bin 0 设置为等于 0 会扰乱算法,该算法开始指向随机值,这些随机值甚至不是系统中存在的最大值。

即使手动查看 CFFT 数据和幅度,它们似乎也无法正常工作。整个频谱部分都有随机噪声值,而示波器确认大结果应该只出现在 0 Hz 和所选信号发生器频率(因此对应于频率仓)。

使用 CMSIS 对我来说非常令人沮丧,因为可用的文档和示例很少,然后由于其中大部分根本无法正常工作(没有重大修改)而进一步减少。

4

0 回答 0