|
FFT stm32f407 лишние гармоники в выходном массиве |
|
|
|
Aug 19 2015, 10:48
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Доброго времени суток! Процессор stm32f407, библиотека DSP от Stm32CubeMx. Делаю выборку из 1024 отсчетов встроенного АЦП (12 бит) с частотой 1024 Гц. Когда набирается 1024 отсчета отправляю данные в функции быстрого преобразования Фурье из либы DSP. Код в более приятном виде можно посмотреть ЗДЕСЬ. CODE arm_cfft_radix2_instance_q15 fftInstance; static u32 curInputCursor=0; static u32 dataIsReady = 0; /**< Флаг для начала преобразования фурье */ static q15_t input [2048]; /**< входной массив данных */ static q15_t output [1024]; /**< выходной массив данных */
/** @brief прерывание по таймеру с частотой 1024 Гц */ extern "C" void timerInterrupt (void) { input[curInputCursor++]=uhADCxConvertedValue; /**< Набираю 1024 замера */ if (curInputCursor>=1024) { curInputCursor = 0; dataIsReady = 1; /**< Флаг, сигнализирующий, что выборка готова */ HAL_TIM_Base_DeInit(&htim1); /**< Как только набралось отключаю таймер, чтобы остановить забор замеров */ } invertLed(); /**< Инвертирую ногу, чтобы на осциллографе проверить действительно ли частота дискретизации 1024 Гц (да, именно так) */ }
/** @brief задача, которая занимается преобразованием фурье */ static void fftTask (void *p) { q15_t maxValue; /* Max FFT value is stored here */ uint32_t maxIndex; /* Index in Output array where max value is */
while(1) { if (dataIsReady) { dataIsReady = 0;
arm_cfft_radix2_init_q15 (&fftInstance, 1024, 0, 1); arm_cfft_radix2_q15(&fftInstance, input); arm_cmplx_mag_q15 (input, output, 1024); u32 index; saveFft(); timInit(); /**< Снова запускаю таймер для подготовки следующих 1024 замеров */ } vTaskDelay(5000); } } Если я все правильно понимаю то в массиве output[] должна получиться частотная характеристика с шагом 1 Гц. При этом output[0] - это постоянная составляющая, все остальное гармоники. Подаю синусоидальный сигнал 50 Гц с амплитудой 1 вольт, смещенный на 1 вольт. Ожидаю, что в output[0] будет значение постоянной составляющей, а в output[50] амплитуда 50-ой гармоники. Однако в результате output[0] всегда равен нулю, в output[1] некоторое значение очень похожее на постоянную составлющую, в output[3] тоже непонятно какое значение (181), а в output[50] как и ожидалось значение гармоники (оно смещается если изменить частоту синусоидального сигнала). Вдобавок нет нет да и появятся непонятные значения в разных гармониках (то output[200], то output[511] и т.п. совершенно случайным образом). Добавил RC-цепочку на вход - не помогло. Буду очень признателен, если кто растолкует, что я делаю неправильно. Вот здесь картинка с характеристикой (строю на графике массив output[])
|
|
|
|
|
 |
Ответов
|
Aug 24 2015, 04:56
|
Местный
  
Группа: Свой
Сообщений: 321
Регистрация: 23-12-11
Из: Уфа
Пользователь №: 69 041

|
Цитата(Krys @ Aug 24 2015, 09:00)  А какую частоту синусоиды взяли? Можете файл прикрепить с отсчётами? Фактически интересует, сколько сэмплов период повторения. Но файл лучше )
А в чём Ваша ошибка была? Вы вообще неправильно данные на вход подали? Да, для вещественного синуса комплексная часть равна нулю.
Почитайте на вики про бабочку в операциях БПФ, тогда все вопросы исчезнут. В 2х словах: формат 1.15 означает 16-битное представление, 1 бит под целую часть (он же знак, поэтому под целую часть нет ничего, и число должно быть меньше 1), а 15 битов - под дробную часть. Грубо говоря, в таком формате все числа пронормированы к 1. Бабочка выполняет умножение входного числа (отсчёта синуса) на поворачивающий множитель. Поворачивающий множитель по определению не превышает 1, поэтому его формат тоже выбран 1.15 (хотя, это чуть-чуть некорректно, и в своей реализации я выбрал честный формат). После умножения бабочка делает сложение. Отсюда разрядность должна увеличиться на 1 бит. Разрядная сетка у нас фиксирована 16 битами, поэтому приходится отбросить младший бит дробной части, чтобы не словить переполнение. Отсюда получается результирующий формат на выходе бабочки 2.14. Бабочка выполняется над массивом данных 1024 сэмпла 10 раз, поэтому в результате точка съезжает аж на 10 разрядов вправо, про это говорят "гейн БПФ".
Чтобы получить правильную амплитуду, нужно результат поделить на вышеупомянутый гейн. Можно и не делить физически, а "держать в уме" наличие усиленного результата. Так что делить или не делить - от этого качественно картинка меняться не должна, кривая спектра всё равно будет выглядеть одинаково внешне, и палки частот всё равно должны быть в нужных местах. Вы сначала добейтесь правильного положения палок, а затем уже думайте о правильном измерении абсолютного уровня амплитуды палки. Чуть позже смогу выложить файл с синусоидой. Ошибка была в том, что я ложил данные во входной массив "подряд", а нужно было писать ноль в ячейки с комплексными значениями. Я добился того, что "палки" находятся "на своих местах". Про бабочку почитаю подробно, пока только и знаю что весь принцип БПФ основан на бабочках (они могут быть по основанию 2,4,8, теоретически возможно и более, но практически слабо реализуемо). А что касается гейна БПФ - ведь я и сместил на 10 разрядов (или если хотите разделил на 2^10), но и после этого на выходе значения даже не близкие к реальным значениям амплитуд гармоник. Выход тоже пронормирован к 1 верно? Значит, чтобы получить амплитуды реальные амплитуды гармоник, то мне нужно сделать так: output[i]/2^15 * 2^12 (мой АЦП 12 бит)?
|
|
|
|
Сообщений в этой теме
yanvasiij FFT stm32f407 лишние гармоники в выходном массиве Aug 19 2015, 10:48 Krys Одной из причин может быть то, что подаваемая част... Aug 21 2015, 06:23 prig Цитата(yanvasiij @ Aug 19 2015, 13:48) ..... Aug 21 2015, 07:26 Krys Не умничайте )) Напишите, что конкретно Aug 21 2015, 09:53 Alex11 Конкретно - если не наложить окно на измеренный си... Aug 21 2015, 10:01 Lmx2315 Цитата(Alex11 @ Aug 21 2015, 14:01) Конкр... Aug 21 2015, 10:54  prig Цитата(Lmx2315 @ Aug 21 2015, 13:54) ..по... Aug 21 2015, 12:23 Krys Ну я что и предлагал - тесты на заранее подготовле... Aug 21 2015, 11:06 yanvasiij Цитата(Krys @ Aug 21 2015, 11:23) Одной и... Aug 21 2015, 11:43 Lmx2315 Цитата(yanvasiij @ Aug 21 2015, 15:43) Мн... Aug 21 2015, 11:57 Krys Цитата(yanvasiij @ Aug 21 2015, 18:43) Во... Aug 24 2015, 04:00 Alex11 Может быть мне следовало изъясняться тщательнЕе. Е... Aug 21 2015, 11:44 yanvasiij Цитата(Alex11 @ Aug 21 2015, 16:44) Может... Aug 21 2015, 11:52 yanvasiij Цитата(Lmx2315 @ Aug 21 2015, 16:57) ..10... Aug 21 2015, 12:04 Lmx2315 Цитата(yanvasiij @ Aug 21 2015, 16:04) Да... Aug 21 2015, 12:49  Krys Цитата(Lmx2315 @ Aug 21 2015, 19:49) Если... Aug 24 2015, 02:15 Alex11 Кроме всего изложенного выше, в спектре для опреде... Aug 21 2015, 16:03 yanvasiij Цитата(Lmx2315 @ Aug 21 2015, 17:49) ..ну... Aug 24 2015, 03:39 Krys Цитата(yanvasiij @ Aug 24 2015, 10:39) Пр... Aug 24 2015, 06:35 Krys Цитата(yanvasiij @ Aug 24 2015, 11:56) А ... Aug 24 2015, 07:41 yanvasiij Цитата(Krys @ Aug 24 2015, 11:35) Я уже с... Aug 24 2015, 07:17 yanvasiij Цитата(Krys @ Aug 24 2015, 12:41) Я не пр... Aug 24 2015, 08:36 Krys Спасибо, теперь всё гораздо понятнее.
А входной си... Aug 24 2015, 09:34 yanvasiij Цитата(Krys @ Aug 24 2015, 14:34) Спасибо... Aug 24 2015, 12:06 Krys Цитата(yanvasiij @ Aug 24 2015, 19:06) Фу... Aug 25 2015, 04:52  Krys Цитата(Krys @ Aug 25 2015, 11:52) А надо-... Aug 28 2015, 06:07   prig Цитата(Krys @ Aug 28 2015, 09:07) Я извин... Aug 28 2015, 09:10 yanvasiij Цитата(Krys @ Aug 25 2015, 09:52) Мы гово... Aug 25 2015, 06:42 Krys Цитата(yanvasiij @ Aug 25 2015, 13:42) По... Aug 25 2015, 07:28  prig Цитата(Krys @ Aug 25 2015, 10:28) ...
Теп... Aug 25 2015, 09:00   Krys Цитата(prig @ Aug 25 2015, 16:00) Звиздец... Aug 25 2015, 09:47    prig Цитата(Krys @ Aug 25 2015, 12:47) Осторож... Aug 25 2015, 11:22     Krys Цитата(prig @ Aug 25 2015, 18:22) Осторож... Aug 26 2015, 03:50 yanvasiij Цитата(Krys @ Aug 25 2015, 12:28) ...
По... Aug 25 2015, 08:25 Krys Пожалуйста!
А во входном массиве (т.е. на вых... Aug 25 2015, 08:49 Krys что-то ТС пропал... у Вас всё заработало? Aug 27 2015, 07:55 prig Цитата(Krys @ Aug 25 2015, 07:52) ...
Ну ... Aug 27 2015, 10:59 Krys Цитата(prig @ Aug 27 2015, 17:59) Цитата(... Aug 28 2015, 03:59 Krys куда делся ТС? Мы уже тут со скуки похоливарить ус... Aug 31 2015, 08:21 yanvasiij Цитата(Krys @ Aug 31 2015, 13:21) куда де... Sep 1 2015, 08:44 alex2103 Цитата(yanvasiij @ Sep 1 2015, 11:44) Я с... Feb 9 2016, 12:35 yanvasiij Цитата(alex2103 @ Feb 9 2016, 17:35) Расс... Feb 15 2016, 04:22 Apparatchik Цитата(yanvasiij @ Feb 15 2016, 06:22) Ес... Apr 21 2017, 06:39 yanvasiij Выложу в понедельник - пример у меня на работе Apr 23 2017, 06:34 Apparatchik Буду ждать Apr 23 2017, 15:19 yanvasiij Приношу извинения за задержку, не было времени нор... Apr 27 2017, 07:25
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|