Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Библиотека DSP для STM32F1xx от STM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Halfback
Здравствуйте!
Пытаюсь понять как работает библиотека STM DSP (STM32F10xxx DSP library firmware), а конктретно FFT. ЧТо 64 что 256 - непонятен результат на выходе функции. Подробно в листинге:

Код
#define NPT 64
#define PI2  6.28318530717959
.....
long lBUFIN[NPT];         /* Complex input vector */
long lBUFOUT[NPT];        /* Complex output vector */
......
for(i=0;i<NPT;i++) lBUFIN[i] = 500+500*sin(PI2*i/NPT);
cr4_fft_64_stm32(lBUFOUT, lBUFIN, NPT);


по сути я нарисовал синус с амплитудой в диапазоне 0...1000 что по сути будет соответствовать оцифровке с 10-12 битного АЦП.
Далее само преобразование. Смотрел в отладчике - там в результате в массиве lBUFOUT какая-то белиберда. В pdf на библиотеку формата выходных данных не нашел. Про входные данные понял так: младшие 2 байта - действительная часть сигнала, старшие 2 - мнимые. В примерах посмотрел на функцию MygSin - почему-то они в отчеты синуса запихивают в старшие разряды. Непонятно. wacko.gif

В общем прошу помощи у тех кто в сове время разобрался - как правильно упаковывать в lBUFIN и как декодировать lBUFOUT.
Заранее спасибо!

Ссылки:
Описание библиотеки
Библиотека
Xenia
А у него точно long длиной в 32 бита? Может быть для уверенности лучше написать uint32_t, как в примере? А то по идее у него уже обычный int должен быть длиной в 32 бита.

А пример у вас в описании библиотеки приведен:

Код
#define N 64 /*Number of points*/
uint32_t x[N],y[N]; /* input and output arrays */
uint16_t real[N], imag[N]; /* real and imaginary arrays */
/* Fill the input array */
for(i=0; i<N; i++)
x[i] = (((uint16_t)(real[i])) | ((uint32_t)(imag[i]<<16)));
cr4_fft_64_stm32(y, x, N); /*computes the FFT of the x[N] samples*/

Это означает, что действительная часть хранится в младших 16-ти битах 32-битного числа, а мнимая - в его старших 16-битах.
И хотя там явно о том не сказано, но, по-видимому, и в результате преобразования тоже будет та же самая система.
Поэтому, на мой взгляд, было бы проще объявить входные и выходные данные не как массив из 32-битных целых, а как массив структур из 16-битных real и image полей:
Код
struct complex
{ uint16_t real;
  uint16_t imag;
} BUFOUT[NPT], BUFIN[NPT];

for(i=0;i<NPT;i++) { BUFIN[i].real=500+500*sin(PI2*i/NPT); BUFIN[i].imag=0; }
cr4_fft_64_stm32(BUFOUT, BUFIN, NPT);
// cos-амплитуды выбираем из BUFOUT[i].real, а sin-амплитуды из BUFOUT[i].imag

Тогда и упаковывать/распаковывать ничего не придется.
Halfback
Цитата
А у него точно long длиной в 32 бита?

у армовского кейла точно.

Цитата
Может быть для уверенности лучше написать uint32_t
.....
Поэтому, на мой взгляд, было бы проще объявить входные и выходные данные не как массив из 32-битных целых, а как массив структур из 16-битных real и image полей:

беззнаковые? sm.gif тут нужны знаковые массивы, т.к. в них же функция пишет коэффициенты синусов и косинусов после БПФ. но идея понятна.

кстати вычислил мощность спектра по функции powerMag из примера - похоже на правду. разве что не понятно - почему размер массива lBUFMAG у них NPT+NPT/2. Ну и запись в той же функции
Код
lX= (lBUFOUT[i]<<16)>>16; /* sine_cosine --> cos */
просто поставила в ступор. Интересный способ обнулить старшие 2 байта sm.gif В асм не раскладывал но подозреваю что запись
Код
lX= lBUFOUT[i] & 0xFFFF
будет выполняться быстрее.
Также вычислял время обработки: 64 точки БПФ считает ~600мкс, мощность 6мс. Одуреть. laugh.gif Надо будет подставить другую функцию извлечения квадратного корня.

в общем буду дальше разбираться.
Xenia
Цитата(Halfback @ Oct 11 2012, 18:21) *
у армовского кейла точно.

Вы, вероятно, полагаете, что у вас на лбу написано о том, что программируете на Кейле? Про это сразу положено указывать, если задаете вопросы по программированию. Тем более в данном случае, когда размерность long зависит не столько от МК, сколько от используемого компилятора.

Цитата(Halfback @ Oct 11 2012, 18:21) *
Интересный способ обнулить старшие 2 байта sm.gif В асм не раскладывал но подозреваю что запись
lX= lBUFOUT[i] & 0xFFFF
будет выполняться быстрее.

А зачем вам обнулять старшую часть??? Если записываете только real-значения в BUFIN, то старшая часть сама обнулится во время присваивания. А если речь идет о результате в BUFOUT, то из него нужны обе части для того, чтобы вычислить мощность.

Кстати, не пробовали, позволяет ли функция cr4_fft_64_stm32() делать FFT на том же самом месте, т.е. указывая в качестве входного и выходного массивов один и тот же массив?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.