Sunteți pe pagina 1din 10

Beizadea Laurentiu-Cristian

Grupa 444C

Tema nr.2- PSC


Proiectarea unui filtru cu raspuns infinit la impuls

Datele initiale:

Tipul filtrului: FOB Chebashev II


Ordin: 4
Frecventele de taiere: 2400Hz, 4000Hz
Frecventa de esantionare: 12000Hz
Riplul maxim in banda de oprire: 40dB
Metoda de proiectare: Indirecta, transformare biliniara
Structura: forma paralel

I.
a) Au fost specificati toti parametrii necesari in enunt.

b) Coeficientii filtrului digital sunt:


b[2][2] = {(-0.0409), (-0.0991), (-0.0570), (0.1427)}
a[2][2] = {(1.6171), (0.6822), (-1.5212), (0.6193)}
Raspunsul in frecventa al filtrului digital proiectat se poate vizualiza in figura 1:

Fig.1 raspunsul in frecventa al filtrului digital


Pozitia polilor si a zerourilor a fost determinata cu ajutorul functiei zplane si se pot
observa in figura 2:

Fig.2, polii si zerourile functiei de transfer

c) Se observa existenta polilor complecsi si a reziduurilor. Vom folosi functia residuez din
Matlab. Coeficientii complecsi sunt urmatorii:

r = {-0.0204+ 0.1957i, -0.0204 - 0.1957i, -0.0285 - 0.2457i, -0.0285 + 0.2457i}


p = {-0.8085+0.1687i, -0.8085-0.1687i, 0.7606+0.2021i, 0.7606-0.2021i}
k = 0.1696

Observam coeficientii astfel obtinuti nu sunt reali, atunci ii vom grupa pe cei complex
conjugati si vom face o structura cu celule de ordin 2.
[b1,a1]=residuez (r(1:2),p(1:2),[]);
[b2,a2]=residuez (r(3:4),p(3:4),[]);

b1 = { -0.0409, -0.0991}
b2 = { -0.0570, 0.1427}
a1 = { 1.6171, 0.6822}
a2 = { -1.5212, 0.6193}
d)Pentru a nu exista depasiri de reprezentare am scalat semnalul x care a fost filtrat atat
in Matlab, cat si in CodeWarrior cu un factor de scala s.
s1 = sum(abs(impz(1,a1)));
s2 = sum(abs(impz(1,a2)));
s = max(s1,s2);
x = x/s;

e)
Structura obtinuta se poate vizualiza in figura 3. Deoarece am scalat coeficientii a
cu 2 pentru a nu exista depasiri in nodurile structurii, apoi am inmultit cu 2 pentru a corecta acest
lucru.

Fig. 3 Structura filtrului digital


Concluzii
In figurile 4 si 5 se pot observa semnalul filtrat atat in Matlab cat si in CodeWarrior iar in
figura 6 se poate observa eroarea relativa obtinuta intre cele doua metode.

Fig. 4, Semnalul filtrat in Matlab


Fig. 5, Semnalul filtrat in CodeWarrior

Fig. 6, Eroarea absoluta intre cele doua metode de filtrare


Codul in Matlab
clear all;
close all;
clc;

%FOB Chebashev II

Fs = 12000; %frecventa esantionare


Ft1 = 2400; %frecventa inferioara de taiere
Ft2 = 4000; %frecventa superioara de taiere

n = 4; %ordinul filtrului
we = 2*pi*Ft1/Fs;
wb = 2*pi*Ft2/Fs;
Oe = 2*Fs*tan(we/2);
Ob = 2*Fs*tan(wb/2);

Wt = [Oe Ob];
Rs = 40; %riplul in banda de oprire

[bs, as] = cheby2(n/2, Rs, Wt, 'stop', 's'); %extragerea coeficientilor


pentru filtrul analogic
figure(1), freqs(bs,as), title('Raspunsul in frecventa al filtrului
analogic'); %raspunsul in frecventa al filtrului analogic

[bd, ad] = bilinear(bs, as, Fs); %transformarea biliniara


figure(2), freqz(bd, ad), title('Raspunsul in frecventa al filtrului
digital'); %raspunsul in frecventa al filtrului digital
figure(3), zplane(bd, ad), title('Poli si zerouri'); %zerourile si polii

t = 0:1/Fs:1-1/Fs; %durata semnalului generat este o secunda


x = chirp(t, 0, 1, Fs/2); %semnalul sinusoidal de frecventa liniar > pe
intervalul [0,Fs/2] Hz
kx = fix(length(x)/160);
L = kx*160;
n = 0:L-1;

%forma paralel
[r,p,k] = residuez (bd,ad); % descompunerea functia de transfer
in fractii simple

[b1,a1] = residuez (r(1:2), p(1:2), []);


[b2,a2] = residuez (r(3:4), p(3:4), []);

%determinarea factorului de scala necesar pentru a nu depasi capacitatea de


%reprezentare a numerelor
s1 = sum(abs(impz(1,a1)));
s2 = sum(abs(impz(1,a2)));
s = max(s1,s2);
x = x/s;

%y_ref este semnalul obtinut la iesirea filtrului paralel


y_ref = filter(b1, a1, x) + filter(b2, a2, x) + x*k;
figure(4), plot(n, y_ref), title('Semnalul filtrat paralel')

%se scriu in fisierul x.dat esantioanele semnalului x ce vor fi aplicate la


%intrarea filtrului descris in CodeWarrior
fid = fopen('..\x.dat', 'w', 'b');
fwrite(fid, x.*2^15, 'int16');
fclose(fid);

%se va rula programul in CodeWarrior si se va apasa o tasta


display('Apasati o tasta');
pause

%se citesc valorile lui y din CodeWarrior ce sunt notate y_cw


fid = fopen('..\y.dat', 'r', 'b');
y_cw = fread(fid,L,'int16');
fclose(fid);

%se reprezinta numerele in format fractionar si se transpune matricea


%coloana intr-un vector
y_cw = y_cw'/(2^15);

%se afiseaza y_cw


figure(5), plot(n,y_cw), title('afisarea semnalului filtrat in CodeWarrior')

%se afiseaza eroarea absoluta intre valoarea de referinta calculata in


%matlab si valoarea obtinuta in CodeWarrior
figure(6), plot(n, y_ref-y_cw), title('Eroarea absoluta')
Codul in CodeWarrior

#include <prototype.h>
#include <stdio.h>
#define DataBlockSize 160 /* dimensiunea unui bloc de date */
#define BlockLength 75 /* numarul de blocuri de date */

Word16 x[DataBlockSize], y[DataBlockSize];


Word16 w[DataBlockSize], w1[DataBlockSize], w2[DataBlockSize];

/*valorile coeficientilor obtinuti in Matlab*/


Word16 b[2][2] = {WORD16(-0.0409), WORD16(-0.0991),
WORD16(-0.0570),WORD16(0.1427)};
Word16 a[2][2] = {WORD16(1.6171/2), WORD16(0.6822/2),
WORD16(-1.5212/2), WORD16(0.6193/2)};
Word16 k=WORD16(0.1696);

Word32 sum;

int main()
{
short n, i, p;

FILE *fpx, *fpy;

fpx = fopen("../x.dat","r+b");
if (!fpx)
printf("\nNu s-a deschis x");
fpy=fopen("../y.dat","w+b");
if (!fpy)
printf("\nNu s-a deschis y");
for (i = 0; i<BlockLength; i++)
{
fread(x, sizeof(Word16), DataBlockSize, fpx);

for (n = 0; n<DataBlockSize; n++)


{

y[n] = 0;
for (p = 0; p<2; p++)
{
sum = L_deposit_h(shr(x[n],1));
sum = L_msu(sum,a[p][0],w1[p]);
sum = L_msu(sum,a[p][1],w2[p]);
w[p] = shl(round(sum),1);
sum = L_mult(b[p][0],w[p]);
sum = L_mac(sum,b[p][1],w1[p]);
y[n] = add(round(sum),y[n]);
w2[p] = w1[p];
w1[p] = w[p];
}

sum = L_mult(x[n],k);
y[n] = add(round(sum),y[n]);

fwrite(y, sizeof(Word16), DataBlockSize, fpy);


}

fclose(fpx);
fclose(fpy);
printf("\nSimulare reusita");
return(0);
}

S-ar putea să vă placă și