|
|
  |
FFT на STM32F4, На CMSIS либо ещё как-то |
|
|
|
Dec 12 2013, 19:01
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
В общем-то вопрос - кто-то делал? STM-овский пример очень скудный и малопонятный. Функций в DSP куча, какие именно использовать - непонятно. У меня получился один "как-то" работающий вариант на CMSIS, но там на выходе получаются какие-то жутко огромные числа, которые даже непонятно как масштабировать. И непонятно в каких крокодильчиках/попугайчиках выдаётся результат? Более-менее нормальные результаты выдавал только один вариант, найденный где-то на этом форуме. Но он на голом Си и жутко тормозит - 0.5-1 FPS  Да и некошерно как-то мой взляд использовать общие алгоритмы, когда под носом DSP ядро ... Короче, прошу помощи. Замахался уже  Если надо, выложу все свои эксперименты. Теорию FFT знаю хреново. В данный момент пишу на кокосе. Спасибо.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Dec 15 2013, 19:23
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
Уродовался-уродовался, родил вот такое: CODE // FFT.c
#include <stdint.h> #include <stdbool.h> #include <string.h>
#include "arm_math.h" #include "FftLib.h"
// выходной спектр FFT uint16_t SpectrumOut [ N_WAVE / 2 ];
static uint32_t ifftFlag = 0; static uint32_t doBitReverse = 1;
// q31_t == int32_t static q31_t input [ N_WAVE * 2 ]; static q31_t output [ N_WAVE ];
// Выполнение FFT // pInData - входные данные (выборка FFT) - N_WAVE void DoFFT ( uint16_t *pInData ) { int i, pos; uint32_t val;
// Очистка спектра memset ( SpectrumOut, 0, sizeof ( SpectrumOut ) );
// если инициализация не выполнена - ничего не делать // Initialize the CFFT/CIFFT module if ( arm_cfft_radix4_init_q31 ( &S, N_WAVE, ifftFlag, doBitReverse) != ARM_MATH_SUCCESS ) return;
// 1. Подготовка входных данных pos = 0; for ( i = 0; i < N_WAVE; i ++ ) {
val = pInData [ i ]; val <<= 16;
input [ pos ] = val; // Re input [ pos + 1 ] = 0; // Im pos += 2; } // for
arm_cfft_radix4_q31 ( &S, input ); arm_cmplx_mag_q31 ( input, output, N_WAVE / 2 );
for ( i = 0; i < N_WAVE / 2; i ++ ) { // SpectrumOut [ i ] = __USAT ( output [ i ] >> 21, 5 ); SpectrumOut [ i ] = __USAT ( output [ i ] >> 14, 7 ); } // for } // DoFFT
N_WAVE = 1024. Отрисовывается в окне 100x50 в масштабе 1:1. Если палка больше 100 по высоте, рисует 100 пикселей. Работает, палки дёргаются вроде в такт музыке, но как-то странно - вначале много палок, в конце мало. Пытался уменьшить размер выборки - N_WAVE = 512 - вообще ничего  Никак не вкурю, как работает DSP-шная команда usat. Гуглом ничего путного не нашёл.
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
Dec 16 2013, 02:38
|
Гуру
     
Группа: Свой
Сообщений: 2 223
Регистрация: 3-03-06
Из: Tomsk
Пользователь №: 14 925

|
Может быть поможет, их хэлпа Keil: Saturating instructions The saturating instructions are: QADD QDADD QDSUB QSUB SSAT USAT. Some of the parallel instructions are also saturating.
Saturating arithmetic These operations are saturating (SAT). This means that, for some value of 2^n that depends on the instruction: - for a signed saturating operation, if the full result would be less than -2^n, the result returned is -2^n - for an unsigned saturating operation, if the full result would be negative, the result returned is zero - if the full result would be greater than 2^n - 1, the result returned is 2^n - 1.
When any of these things occurs, it is called saturation. Some instructions set the Q flag when saturation occurs.
Note Saturating instructions do not clear the Q flag when saturation does not occur. To clear the Q flag, use an MSR instruction. The Q flag can also be set by two other instructions, but these instructions do not saturate.
|
|
|
|
|
Dec 18 2013, 19:44
|

Профессионал
    
Группа: Свой
Сообщений: 1 202
Регистрация: 26-08-05
Из: Донецк, ДНР
Пользователь №: 7 980

|
FFt видимо, нормальный. Вставил алгоритм с википедии - результат такой же. Оконные функции прикрутил. Теперь другой вопрос - какую часть палок выводить на дисплей? Штук 15-20, как винампе или как можно больше? У меня диспей 800х480, т.е. больше 800 палок я не выведу. При выборках в 2К FFT даёт 1024 палки  . И есть ли какой-то оптимальный размер выборки?
--------------------
Чтобы возить такого пассажира, необходим лимузин другого класса. (с) Мария Эдуарда
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|