„Diszkrét idejű szűrők” változatai közötti eltérés
(alapcikk+kategória) |
|||
(2 közbenső módosítás ugyanattól a szerkesztőtől nincs mutatva) | |||
53. sor: | 53. sor: | ||
A fenti rajzon látható logikát követve valósítható meg. A mostani bemenő minta és az előző eltárolt mintákból álló vektort szorozzuk össze a szorzók együtthatóinak vektorával, a részeredményeket pedig összegezzük. És FIR szűrő esetén már készen is van a kimenőjel. IIR szűrő esetén természetesen a kimenőjel előző állapotait tartalmazó vektorral szorozzuk össze a szorzók együtthatóinak vektorával és az eredményeit szintén összegezzük a kimenőjellel. | A fenti rajzon látható logikát követve valósítható meg. A mostani bemenő minta és az előző eltárolt mintákból álló vektort szorozzuk össze a szorzók együtthatóinak vektorával, a részeredményeket pedig összegezzük. És FIR szűrő esetén már készen is van a kimenőjel. IIR szűrő esetén természetesen a kimenőjel előző állapotait tartalmazó vektorral szorozzuk össze a szorzók együtthatóinak vektorával és az eredményeit szintén összegezzük a kimenőjellel. | ||
+ | |||
+ | <source lang="c"> | ||
+ | /* | ||
+ | FIR szűrő konvolúciót megvalósító részlete | ||
+ | Bemenetek: | ||
+ | m: <konvhossz> hosszú minta vektor | ||
+ | a: <konvhossz> hosszú együttható vektor | ||
+ | Kimenet: a konvolúció eredménye | ||
+ | */ | ||
+ | |||
+ | float konvolval_fir(const float *m, const float *a, int konvhossz) { | ||
+ | int i; | ||
+ | float er=0; | ||
+ | for (i=0; i<konvhossz; i++) er += m[i] * a[i]; | ||
+ | return er; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | És nézzünk egy példát az IIR implementációra, ahol mint a fenti blokkvázlaton látható, nem csak az új minták, hanem a régebbi eredmények is meghatározzák az új eredményt. | ||
+ | |||
+ | <source lang="c"> | ||
+ | /* | ||
+ | IIR szűrő konvolúciót megvalósító részlete | ||
+ | Bemenetek: | ||
+ | m: <konvhossz> hosszú minta vektor | ||
+ | a: <konvhossz> hosszú együttható vektor | ||
+ | eredm: <konvhossz> hosszú előző eredményekből álló vektor | ||
+ | b: <konvhossz> hosszú együttható vektor a visszacsatoláshoz | ||
+ | Kimenet: a konvolúció eredménye | ||
+ | A kimenetet ne felejtsük el a főprogramban az eredm vektorhoz hozzáilleszteni, | ||
+ | hiszen az alábbi szűrő esetén felhasználjuk a következő számításhoz. | ||
+ | */ | ||
+ | |||
+ | float konvolval_iir(float short *m, const float *a, const float *eredm, const float *b, int konvhossz) { | ||
+ | int i; | ||
+ | float er=0; | ||
+ | for (i=0; i<konvhossz; i++) er += m[i] * a[i] + eredm[i] * b[i]; | ||
+ | return er; | ||
+ | } | ||
+ | </source> | ||
+ | |||
+ | És hogy pontosan milyen feladatot lát el a szűrő, azt teljes mértékben az '''a''' illetve IIR elrendezés esetén az '''a''' és '''b''' vektorokban szereplő számértékek határozzák meg. Ezeknek az együtthatóknak a kiszámítására mi is vállalkozhatunk, azonban rengeteg program található az interneten, amely megadja nekünk a szükséges együtthatókat. | ||
+ | |||
+ | További érdekessége az implementációnak, hogy a törtszámok tárolására alkalmas float helyett gyakran olyan kisprocesszort alkalmazunk, amely sokkal gyorsabban képes egész (integer) értékekkel dolgozni. Ebben az esetben a fenti algoritmusokat célszerű úgy átdolgozni, hogy egész számokkal tudjon dolgozni. | ||
+ | |||
+ | A DSP-kben történő implementáláskor pedig számos, az adott architektúra által biztosított gyorsításra van lehetőségünk. Akár a hardveresen határolt ciklikus pufferek, akár a hosszabb eredmény tároló regiszterek (akkumulátorok), akár az egyidejűleg több szálon történő szorzást vagy szorzás+összegzés elemi műveletét nézzük. | ||
== Együtthatók meghatározása == | == Együtthatók meghatározása == | ||
* interneten található sok-sok szűrőtervező program valamelyikével | * interneten található sok-sok szűrőtervező program valamelyikével | ||
− | * | + | * A [[szabad szoftver]]eket tartalmazó [http://www.ubuntu.com Ubuntu] disztribúcióban található ''octave-signal'' csomag fir1(), fir2() és filter() függvényeivel. |
+ | |||
+ | Alábbi példán az alapvető FIR szűrők együtthatóinak jelleggörbéje van ábrázolva. Megfigyelhető, hogy a magas frekvenciát átengedő szűrők középső együtthatója ellentétes irányban „kiugrik”, míg a magas tartományt eltipró aluláteresztő és sáváteresztő szűrők esetén szép oszcilláció figyelhető meg a pontok között. | ||
+ | |||
+ | [[Fájl:FIR egyutthatok alulatereszto savatereszto.png|center]] | ||
+ | |||
+ | Megjegyzés: a fenti görbén a pontok számítanak, a pontok kizárólag azért lettek összekötve, hogy könnyebben tudjuk követni, melyik pont melyik pont után következik. | ||
+ | |||
+ | [[Fájl:FIR_egyutthatok_feluatereszto_savzaro.png|center]] | ||
+ | |||
+ | A gyakorlatban 128 együtthatós FIR szűrővel már szép eredmény érhető el, de gyakran még ennél több együtthatóval dolgozunk. | ||
+ | |||
[[Kategória:Digitális jelfeldolgozás]][[Kategória:Szűrők]] | [[Kategória:Digitális jelfeldolgozás]][[Kategória:Szűrők]] |
A lap jelenlegi, 2009. július 20., 09:31-kori változata
Tartalomjegyzék
Alapok
A diszkrét idejű rendszerek 3 alapelem kombinációjából épülnek fel.
- összeadó, amely a két bemenetére érkező értéket előjelesen összegzi. Azaz ki = be1 + be2
- erősítő vagy más néven szorzó, amely egy előre konfigurált konstanssal szorozza a jelet. Azaz ki = konstans * be
- késleltető, amely egyetlen ütemmel (nevezzük órajelnek) késleltetve helyezi a kimenetére (és tartja) a bemeneten levő jelet.
Ebből a hátom alapkomponensből épülnek fel fel a diszkrét idejű hálózatok.
Ezeknek a diszkrét idejű implementációknak számos előnyük van az analóg megoldásokhoz képest. Például:
- pontosság
- egyszerű, olcsó reprodukálhatóság - a szorzók konstansai könnyen reprodukálhatók.
- hőmérsékletfüggetlen működés
- nincs öregedési elhangolódásuk
FIR és IIR szűrő elrendezések
Nézzük meg a különbséget az alábbi ábrákon a FIR és az IIR szűrőelrendezés között. Első ránézésre látszik, hogy az IIR szűrőre a kimenetének késleltetett jele is vissza van vezetve, míg a FIR-nél csak a bemenőjel és annak késleltetésével operálunk.
- FIR (Finite Impulse Response = véges impulzusválaszú), hiszen a késleltető számával történő késleltetés után a bemenetre adott impulzus már tuti nem hat az áramkörre, hiszen ez az impulzus az utolsó késleltetőt (=élvezérelt tárolót) is elhagyta.
- IIR (Infinite Impulse Response = végtelen impulzusválaszú), hiszen a kimenet visszacsatoltja is beleszól a következő kimeneti állapotba.
És még néhány különbség:
Fázismenet: lineáris fázismenet mindig lehetséges | nehezen kézbentartható, nem léteznek rá pontos módszerek |
Stabilitás: mindig stabil, oszcillációmentes; tetszőleges mértékben bővíthető | instabillá (gerjedővé) tervezhető, oszcillátor is létrehozható. Szűrőként gyakorlatban csak véges fokszám implementálható. |
Ugyanolyan meredekséghez tartozó késleltetőszám: több | kevesebb a rekurzió miatt |
Története: nincs analóg megfelelője, sokfázisú (polyphase) analóg hálózatokkal közelíthető ez az elv. | Analóg szűrők működési elvéből származtatható a működési elve. |
Hogyan néz ki egy ilyen áramkör a gyakorlatban?
Alább két igen elterjedt és mint látható lesz, igen egyszerű megoldás lesz ismertetve. A bonyolultságát a tervezés során az erősítők együtthatóinak meghatározása jelenti. Ez dönti el ugyanis, hogy az adott X késleltetőt tartalmazó FIR vagy IIR szűrő valójában hogyan fog viselkedni.
Elöljáróban annyit megemlítve, hogy az áramkör leges leg elejére A/D átalakítót, a végére D/A átalakítót és aluláteresztő szűrőt téve, az egész rendszer bemenete analóg, a kimenete szintén analóg lesz.
Implementáció digitális logikai IC-kkel
Ahogy a fenti ábrán látható, az összeadó egy bináris összeadó, a szorzó egy bináris szorzó, a késleltető pedig például egy 74HC374-es digitális tároló IC. Mindezt ha egyetlen tokban szeretnénk implementálni, az FPGA, mint tetszőleges sorrendbe konfigurálható logikai kapukat tartalmazó ideális erre a célra.
Implementáció mikrovezérlővel illetve DSP-vel
A fenti rajzon látható logikát követve valósítható meg. A mostani bemenő minta és az előző eltárolt mintákból álló vektort szorozzuk össze a szorzók együtthatóinak vektorával, a részeredményeket pedig összegezzük. És FIR szűrő esetén már készen is van a kimenőjel. IIR szűrő esetén természetesen a kimenőjel előző állapotait tartalmazó vektorral szorozzuk össze a szorzók együtthatóinak vektorával és az eredményeit szintén összegezzük a kimenőjellel.
<source lang="c"> /*
FIR szűrő konvolúciót megvalósító részlete Bemenetek: m: <konvhossz> hosszú minta vektor a: <konvhossz> hosszú együttható vektor Kimenet: a konvolúció eredménye
- /
float konvolval_fir(const float *m, const float *a, int konvhossz) {
int i; float er=0; for (i=0; i<konvhossz; i++) er += m[i] * a[i]; return er;
} </source>
És nézzünk egy példát az IIR implementációra, ahol mint a fenti blokkvázlaton látható, nem csak az új minták, hanem a régebbi eredmények is meghatározzák az új eredményt.
<source lang="c"> /*
IIR szűrő konvolúciót megvalósító részlete Bemenetek: m: <konvhossz> hosszú minta vektor a: <konvhossz> hosszú együttható vektor eredm: <konvhossz> hosszú előző eredményekből álló vektor b: <konvhossz> hosszú együttható vektor a visszacsatoláshoz Kimenet: a konvolúció eredménye A kimenetet ne felejtsük el a főprogramban az eredm vektorhoz hozzáilleszteni, hiszen az alábbi szűrő esetén felhasználjuk a következő számításhoz.
- /
float konvolval_iir(float short *m, const float *a, const float *eredm, const float *b, int konvhossz) {
int i; float er=0; for (i=0; i<konvhossz; i++) er += m[i] * a[i] + eredm[i] * b[i]; return er;
} </source>
És hogy pontosan milyen feladatot lát el a szűrő, azt teljes mértékben az a illetve IIR elrendezés esetén az a és b vektorokban szereplő számértékek határozzák meg. Ezeknek az együtthatóknak a kiszámítására mi is vállalkozhatunk, azonban rengeteg program található az interneten, amely megadja nekünk a szükséges együtthatókat.
További érdekessége az implementációnak, hogy a törtszámok tárolására alkalmas float helyett gyakran olyan kisprocesszort alkalmazunk, amely sokkal gyorsabban képes egész (integer) értékekkel dolgozni. Ebben az esetben a fenti algoritmusokat célszerű úgy átdolgozni, hogy egész számokkal tudjon dolgozni.
A DSP-kben történő implementáláskor pedig számos, az adott architektúra által biztosított gyorsításra van lehetőségünk. Akár a hardveresen határolt ciklikus pufferek, akár a hosszabb eredmény tároló regiszterek (akkumulátorok), akár az egyidejűleg több szálon történő szorzást vagy szorzás+összegzés elemi műveletét nézzük.
Együtthatók meghatározása
- interneten található sok-sok szűrőtervező program valamelyikével
- A szabad szoftvereket tartalmazó Ubuntu disztribúcióban található octave-signal csomag fir1(), fir2() és filter() függvényeivel.
Alábbi példán az alapvető FIR szűrők együtthatóinak jelleggörbéje van ábrázolva. Megfigyelhető, hogy a magas frekvenciát átengedő szűrők középső együtthatója ellentétes irányban „kiugrik”, míg a magas tartományt eltipró aluláteresztő és sáváteresztő szűrők esetén szép oszcilláció figyelhető meg a pontok között.
Megjegyzés: a fenti görbén a pontok számítanak, a pontok kizárólag azért lettek összekötve, hogy könnyebben tudjuk követni, melyik pont melyik pont után következik.
A gyakorlatban 128 együtthatós FIR szűrővel már szép eredmény érhető el, de gyakran még ennél több együtthatóval dolgozunk.