|
|
|
DSP на STM32F4 |
|
|
|
Aug 25 2016, 13:48
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Цитата(DASM @ Aug 25 2016, 16:35) Не знаю что и сказать, SystemVue позволяет считать и флоат и дабл и фиксед с любой точностью коэфф. и кол-ва бит. Матлаб, уверен, тоже. Да, я нашел где в матлабе посчитать коэффициенты с Single-precision floating-point Хорошо, теперь, если я буду подавать на вход фильтра с такими коэффициентами случайный 24-битный сигнал, у меня на выходе будет всегда получаться 24-битное число и никакие переполнения невозможны? Я просто никогда не работал с плавающей точкой, у целых чисел понятно когда появится переполнение, а тут - не очень.
|
|
|
|
|
Aug 26 2016, 06:04
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Цитата(sigmaN @ Aug 25 2016, 21:26) Что нужно знать про арифметику с плавающей запятой https://habrahabr.ru/post/112953/да, я читал эту статью Цитата(sigmaN @ Aug 25 2016, 21:26) Особо полезно прочесть вот эту часть 4. Подводные камни в арифметике с плавающей запятой а в чем польза? какой вывод можно сделать из этого пункта? не считать фильтры во float-ах?
|
|
|
|
|
Aug 26 2016, 06:18
|
Гуру
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702
|
Цитата(Atlantis- @ Aug 26 2016, 09:04) а в чем польза? какой вывод можно сделать из этого пункта? не считать фильтры во float-ах? Считать, но правильно. Зачастую фильтрация - это сложение с накоплением произведений пар чисел. Нужно все перемножить. Полученные значения расставить по возрастанию. Суммировать от меньшего к большему. Так ошибка будет минимальна.
|
|
|
|
|
Aug 26 2016, 09:37
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Цитата(adnega @ Aug 26 2016, 09:18) Считать, но правильно. Зачастую фильтрация - это сложение с накоплением произведений пар чисел. Нужно все перемножить. Полученные значения расставить по возрастанию. Суммировать от меньшего к большему. Так ошибка будет минимальна. Не понял, как суммировать от меньшего к большему? Коэффициенты фильтра у меня отличаются в два раза, а входной сигнал - рандомный. Знак тоже не угадаешь. Или что мне сначала сравнивать произведения между собой, а потом складывать?
|
|
|
|
|
Aug 26 2016, 11:41
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Цитата(khach @ Aug 26 2016, 11:06) Начинать писание своего фильтра надо с того что скачать CMSIS-DSP последней версии, выбрать подходящий фильтр и скомпилить его. В этой библиотеке реализован только решетчатый фильтр IIR, а мне надо обычный.
|
|
|
|
|
Aug 27 2016, 16:25
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Цитата(sigmaN @ Aug 26 2016, 19:41) https://www.keil.com/pack/doc/CMSIS/DSP/htm...scade_d_f1.html Можно реализовтаь фильтр любого порядка. Если нужен первый то делаете b2=0 and a2=0. Впрочем там всё хорошо описано по ссылке Спасибо, это я как то пропустил... Изучаю, не понял одно требование Цитата Pay careful attention to the sign of the feedback coefficients. Some design tools use the difference equation y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2] In this case the feedback coefficients a1 and a2 must be negated when used with the CMSIS DSP Library. Что то странное, у меня только а1 отрицательный, а2 - положительный. Или это правильно переводится как "а1 и а2 должны нейтрализовываться" и у меня все правильно?
Сообщение отредактировал Atlantis- - Aug 27 2016, 16:33
|
|
|
|
|
Aug 28 2016, 08:37
|
I WANT TO BELIEVE
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751
|
Читаем описание функци, реализует она следующее: Цитата Algorithm Each Biquad stage implements a second order filter using the difference equation: y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] + a1 * y[n-1] + a2 * y[n-2] Ниже заостряется внимание на том, что некоторые программы для моделирования фильтров подразумевают, что уравнение будет другим Цитата Some design tools use the difference equation y[n] = b0 * x[n] + b1 * x[n-1] + b2 * x[n-2] - a1 * y[n-1] - a2 * y[n-2] Видите разницу? в первом случае +a1 +a2 а во втором -a1 -a2 Соответственно вам подсказывают, что если вы пользуетесь как раз таким софтом, то коэффициенты a1 и a2 must be negated. Если по русски то перед применением коэффициенты a1 и a2 умножьте на -1, таким образом изменив их знак )
--------------------
The truth is out there...
|
|
|
|
|
Aug 29 2016, 11:56
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Аааа, вон оно как...понял, спасибо большое! Пока сам написал реализацию пары уравнений работающих с float, проверил анализатором спектра - похоже на правду. Смущает несколько моментов: 1) результат вычислений получается float, для вывода на ЦАП, естественно, преобразую его к int - теряется дробная часть, это нормально? 2) Отрицательные значения. Я подаю на вход фильтра белый шум, 24-битный. Соответственно, после фильтра у меня тоже должно получаться 24-битный результат. Но! Отрицательные значения в процессоре - это инвертированное положительное число + 1. А для ЦАП отрицательное значение получается простой инверсией положительного числа. Я отлавливаю в итоговом результате, если 23-й бит = 1, то я из всего числа вычитаю единицу. Это правильно? 3) Мне коэффициенты надо с компьютера передавать, а они у меня float теперь. Тут мне посоветовали, домножать, потом делить. Но как мне передать например число 0.99577337503433228 ? Чтобы целое получить, надо домножить на 10^17 и что потом с ним делать? Оно же даже в int не влезет.
|
|
|
|
|
Aug 29 2016, 14:24
|
Местный
Группа: Участник
Сообщений: 491
Регистрация: 18-05-11
Пользователь №: 65 102
|
Порылся в интернете, на последний вопрос вроде нашел ответ. Сделал так, результат сходится Код float float_value=0.6543278; char float_bytes[sizeof(float)]; float *ptr; float new_value;
//разбиение на байты float_bytes[0] = *((char *)&float_value + 0);//0x07 float_bytes[1] = *((char *)&float_value + 1);//0x82 float_bytes[2] = *((char *)&float_value + 2);//0x27 float_bytes[3] = *((char *)&float_value + 3);//0x3F //http://floatingpoint.ru/online/dec2float.php - проверка
//собрали из байт float ptr = (float*)float_bytes; new_value = *ptr;
|
|
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|