Невозможно выполнить частотное преобразование CFFT с CMSIS на STM32? - PullRequest
1 голос
/ 02 июля 2019

В данный момент я пытаюсь реализовать программу для нахождения 3 частот (xs = 30,1 кГц, ys = 28,3 кГц и zs = 25,9 кГц) с помощью пакета CMSIS на плате STM32F411RE. Я не могу заставить комплексное БПФ (CFFT) и комплексную величину работать правильно.

В соответствии с частотными бинами, я генерирую массив, содержащий эти частоты, так что я могу вручную искать, какие индексы включают сигналы xs, ys и zs. Затем я использую этот индекс, чтобы посмотреть на результаты 3-х футов (Xfft, Yfft, Zfft), чтобы найти результаты для этих сигналов, но они не совпадают.

Я использую следующий порядок функций:

Буфер АЦП DMA: HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
Бункеры Freqeuncy в binfreqs
Изменить вход АЦП, чтобы плавать Xfft
CFFT_F32: 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 кГц, ни индекс 301 бина, ни индекс 602 бина не содержат соответствующий ожидаемый выходной сигнал?

301 индекс бункера

602 индекс корзины


EDIT:

С тех пор я пытался реализовать приведенный здесь пример arm_cfft_f32 . Этот последний пример полностью разбит, так как внешний набор данных 10 кГц больше не включается по умолчанию, и попытка включить его невозможна, поскольку программа ведет себя плохо и продолжает выдавать ошибки о возвращаемом типе данных, который даже не присутствует в первую очередь. Поэтому я не могу использовать приведенный для этого пример программы: она также устарела на 4 года, так что это неудивительно.

Функция arm_max_f32 () также оказалась бесполезной, поскольку она продолжает обнаруживать шум, генерируемый в ячейке 0, используя аналоговый сигнал. Вручную устанавливая этот интервал 0 равным 0, затем сбрасывает алгоритм, который начинает указывать на случайные значения, которые даже не являются самыми большими значениями, присутствующими в системе.

Даже при ручном просмотре данных и величины CFFT кажется, что они работают неправильно. Во всех частях спектра имеются случайные значения шума, в то время как осциллограф подтверждает, что большие результаты должны присутствовать только при частоте 0 Гц и выбранной частоте генератора сигналов (что соответствует частотному бину).

Использование CMSIS крайне разочаровывает меня из-за небольшого количества документации и доступных примеров, которые затем еще больше сокращаются из-за того, что большинство из них просто не работает (без серьезной модификации).

...