Мне не удалось достичь необходимого динамического диапазона фильтра для следующих условий: ФВЧ2, Fc=2Гц, Fsmp=606 Гц, Uin=1.14, аккумулятор 32 бит, ассемблер. Для ц все в порядке...
Для анализа фильтра в Матлабе была создана модель, погоняв которую, я сделал следующие выводы.
1.Для входных значений >1000 все в порядке, если меньше - "уезжает" вверх частота среза, и для значений Uin<50 выход фильтра =0 (для контрольной частоты 3Гц д.быть 0.914 от 1.0).
2.Требуется повышение точности вычислений. 16 бит данных и 32 бита аккумулятора недостаточно. Повышение точности коэф.ничего не дает.
3.Возможно, поможет переход на direct-form II или отказ от стандартной формы вычислений (параллельная)?
Я решил перейти на арифметику 24данные*16коэф=40аккумулятор. Как это сделать правильно? Я просто масштабировал на 2^8 входные данные - получил 24 бита. В таком виде и храню промежуточные значения. Результат удовлетворительный. Для компенсации увеличения размера программы можно вычисления делать в каскадной форме, не обращая внимания на нормирующий коэффициент (только для этого фильтра).
Если не трудно - посмотрите свежим взглядом на модель, не ошибся ли где. А то, может, гоняю третий день ошибку и думаю, что все в порядке...
Пояснения к модели: 1.Вид подогнан к трансляции на ассемблер. 2.Для анализа использовал Фильтр Солюшн - там удобнее, имхо, чем в Матлабе, проверять коэффициенты и получать графики. 3.Если d=2^0 - 16*16=32, ecли d=2^8 - 24*16=40. 4.График 1: зеленым входной сигнал ампл.Asig, синим выходной. 5.График 2 показывает использование аккумулятора во время вычислений и нормирован к 2^39 (со знаком будет 2^40). Если больше 1.0 -переполнение. 6.График 3 показывает поток приведенных данных и нормирован к 2^23 (со знаком будет 2^24).
Вот м-файл.
------------------------------------------------------------------------------------- clear clc clf %Параметры сигнала =================================================== Nsmp=3000; %Кол-во выборок Fsmp=606; %Частота дискретизации Гц Asig=16383; %Амплитуда сигнала Fsig=3; %Частота сигнала m=2^14; %Масштабирование коэффициентов d=2^8; %Масштабирование данных 16->24 bit
%Входной сигнал 16bit ------------------------------------------------ k=1:Nsmp; x(k) = fix(Asig*sin((k*Fsig*2*pi)/(Fsmp)));
%Коэффициенты ========================================================
%-- HPF2 2Hz stand.--------------------------------------------------- a0=fix(0.9854440*m); a1=-fix(1.970888*m); a2=fix(0.9854440*m); b0=1*m; b1=-fix(1.970676*m); b2=fix(0.9710999*m); %-- HPF2 2Hz cascade ------------------------------------------------- %a0=1*m; a1=-2*m; a2=1*m; %b0=1*m; b1=-fix(1.970676*m); b2=fix(0.9710999*m);
%=== Узлы ============================================================ y0=0; y1=0; y2=0; x0=0; x1=0; x2=0;
%=== Фильтр DF I ===================================================== for k = 1:1:Nsmp; x2=x1; acc=x2*a2; ta1(k)=acc/(2^31*d); %r x1=x0; acc=acc+x1*a1; ta2(k)=acc/(2^31*d); %g x0=x(k)*d; acc=acc+x0*a0; ta3(k)=acc/(2^31*d); %b y2=y1; acc=acc-y2*b2; ta4(k)=acc/(2^31*d); %m y1=y0; acc=acc-y1*b1; y0=fix(acc/m); ty1(k)=y0/(2^15*d); y(k)=fix(y0/d); %Выход 16 бит end;
%Графики ============================================================= k = 500:1:Nsmp; %Диапазон вывода subplot(3,1,1); hold on; grid on; plot(k,x(k),'g'); %Входной сигнал plot(k,y(k),'b');
%Тестовые сигналы ---------------------------------------------------- subplot(3,1,2); hold on; grid on; %Контроль аккумулятора plot(k,ta1(k),'r'); plot(k,ta2(k),'g'); plot(k,ta3(k),'b'); plot(k,ta4(k),'m'); ylabel('ACC / 2^3^1 / 2^3^9');
subplot(3,1,3); hold on; grid on; plot(k,ty1(k),'b'); %Промежуточные значения Y ylabel('Y0 / 2^1^5 / 2^2^3');
|