реклама на сайте
подробности

 
 
> реализация IIR фильтра на целых числах
baralgin
сообщение May 20 2010, 08:37
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



 По мотивам топика 75610. Значит из матлаба получаем некоторые коэффициенты во второй форме. Для простоты возмём односекционный фильтр, матлаб выдаёт следующее:

CODE
const int NL[MWSPT_NSEC] = { 1,3,1 };
const int16_T NUM[MWSPT_NSEC][3] = {
{
303, 0, 0
},
{
16384, 0, -16384
},
{
16384, 0, 0
}
};
const int DL[MWSPT_NSEC] = { 1,3,1 };
const int16_T DEN[MWSPT_NSEC][3] = {
{
16384, 0, 0
},
{
16384, -32152, 15778
},
{
16384, 0, 0
}
};


Написал функцию(точнее класс, но не важно):

Код
class BiquadSection
{
public:
    BiquadSection(){ W1 = 0; W2 = 0; }
    int operator << (int x0)
    {
        x0 *= 303;
        int W = x0 - ( -32152 * W1 + 15778 * W2 );

        W /= 16384;
        int ret = W - W2;

        W2 = W1;
        W1 = W;
        return ret;
    }
protected:
    int W1, W2;
};


Фильтр работает, но результат получается немного "квадратным"(рисунок). Такой же фильтр но в первой форме(direct form I) работает отлично(без видимых искажений). Где у меня косяк в вычислениях?

На скриншоте верхня синусоида это исходный сигнал, а нижняя фильтрованный. Апмлитуда исходного 460 единиц. Фильтр убирает постоянную составляющую.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
baralgin
сообщение May 21 2010, 08:09
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 92
Регистрация: 23-12-08
Из: Кишинёв
Пользователь №: 42 680



Цитата(IWG @ May 21 2010, 06:34) *
Косяка на самом деле вроде как и нет. Просто отношение частоты дискретизации к сигналу внесло свою лепту. Выход - либо увеличить частоту дискретизации, либо увеличить разрядность.

Меня смущает что этот код работает:
Код
    int operator << (int x0)
    {
        int ret = ( x0 - x2 ) - ( ( -32152 * y1 + 15778 * y2 ) / 16384 );
        x2 = x1;
        x1 = x0;
        y2 = y1;
        y1 = ret;
        return (ret * 303) / 16384;
    }

Коэффициенты теже, сигнал тот же, а результат красивый(скриншот не привожу - там всё гладко). Хотя везде пишут что каноническая форма лучше...

Ладно, зада такая: частота сэмплирования 12.5кГц(меньше ну очень не хочется), 12bit, полезный сигнал 50Гц. Нужно убрать постоянную составляющую и немного пригладить высокочастотные шумы. В примерах выше полосный фильтр Баттерворта: Fcut1=25Гц, Fcut2=100Гц. Желательно, но не обязательно, иметь фазовый сдвиг поменьше в районе 50гц. Что можете посоветовать по такой задаче?
Go to the top of the page
 
+Quote Post
IWG
сообщение May 21 2010, 09:15
Сообщение #3





Группа: Участник
Сообщений: 11
Регистрация: 7-09-07
Из: Омск
Пользователь №: 30 350



То есть этот код не ваш? (Если да, то чем не устраивает)
Код
    int operator << (int x0)
    {
        int ret = ( x0 - x2 ) - ( ( -32152 * y1 + 15778 * y2 ) / 16384 );
        x2 = x1;
        x1 = x0;
        y2 = y1;
        y1 = ret;
        return (ret * 303) / 16384;
    }

А ваш тот, который в составе класса приведенного выше? Я правильно понимаю? Потому как проверив на отсчетах результат разный => функция, объявленная в классе, переписана с ошибкой.

Сообщение отредактировал IWG - May 21 2010, 09:26
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 15:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.02549 секунд с 7
ELECTRONIX ©2004-2016