Fourierova transformácia na mikrokontroléri. Spektrálna analýza signálov. Rýchla Fourierova transformácia

Existuje mnoho špecializovaných procesorov na digitálne spracovanie signálu (DSP), ako napríklad DSP od Texas Instruments série TMS320, ktorý zahŕňa jednoduché celočíselné jadrá a také monštrá, ako je podrodina rodiny C6000, ktorá spracováva dáta s pohyblivou rádovou čiarkou. Existuje celý rad ADSP od Analog Devices (ktorý zahŕňa viac-menej univerzálny BlackFin), existujú aj jednoduchšie riešenia od MicroChip - dsPIC.

Špecializovaný DSP je však dobrý, ale je vždy taký potrebný? Áno, pri obrovskom toku informácií je jednoducho nenahraditeľná, no existujú aj jednoduchšie úlohy spracovania. Konkrétne ma zaujala úloha dvojitej konverzie - audio signál je konvolvovaný, čím sa získa spektrum, potom je možné na spektre vykonávať ľubovoľné operácie a vykonávať inverznú konverziu, čím sa získa spracovaný signál. To všetko je potrebné urobiť v reálnom čase a získať kvalitu nie nižšiu ako kvalita telefónu.

Nepíše sa rok 2000, existujú jednočipové riešenia založené na vysokovýkonných jadrách ARM7/Cortex-M3, ktoré výrazne klesli na cene, sú 32-bitové, majú hardvérovú implementáciu 32-bitovej operácie násobenia (navyše , takmer operácia násobenia a akumulácie DSP a 64 bitový výsledok) a Cortex-M3 zahŕňa aj hardvérovú divíziu.

Chcem vás hneď upozorniť, že spracovanie signálov nie je mojou špecializáciou, takmer všetky znalosti (alebo skôr pochopenie princípov) sa zachovali z inštitútu, ale teraz som to chcel len otestovať a implementovať. Mám na mysli, že môžu existovať nepresnosti v popise, zámene pojmov atď. V skutočnosti ma akademická presnosť veľmi neznepokojovala.

Pre takmer každý DSP je vyššie uvedená úloha jednoduchá a priamočiara. Ako sa však na ňom bude správať jadro RISC na všeobecné použitie? Ak vezmeme do úvahy AVR alebo PIC, je nepravdepodobné, že budú stačiť. Vplyv má 8-bitová a nízka taktovacia frekvencia. Hoci Elm-Chan má návrhy, v ktorých vykonáva FFT na AVR a kreslí spektrum signálu. V tomto prípade sa však v reálnom čase vykonáva jednoduchá vizualizácia (s minimálnou presnosťou spracovania) a nie úplné spracovanie signálu s prijateľnou kvalitou zvuku.

Ako experimentálny čip bol vybraný LPC2146, založený na jadre ARM7TDMI-S s maximálnou taktovacou frekvenciou 60 MHz (v praxi nepracuje na 72 a dokonca ani na 84 MHz). prečo? Jednak mám na to ladiacu dosku a jednak je na doske ADC a DAC, t.j. minimálna potrebná vonkajšia úprava.

Trochu teórie

V prvom rade bolo zaujímavé zhodnotiť výkon FFT (Fast Fourier Transform) na mikrokontroléroch ARM. Na základe tohto hodnotenia môžeme usudzovať, či má dostatočnú rýchlosť na spracovanie toku zvukových dát a signál s akou vzorkovacou frekvenciou a koľko kanálov je možné spracovať na takomto mikrokontroléri.

Na základe Fourierovej transformácie môžete zostaviť chytré filtre (s veľmi atraktívnymi vlastnosťami). Zaujímala ma predovšetkým problematika zmeny tónu signálu (zvyšovanie a znižovanie spektra) a „odrážanie“ spektra. Ten je potrebný v rádiách SDR na počúvanie rádiového vysielania LSB v dolnom postrannom pásme.

Nebudem vás zaťažovať teóriou a vysvetľovať, čo je Fourierova transformácia, na túto tému je pomerne veľa materiálov, z toho, čo som použil: wiki a kapitola z veľmi dobrej a poučnej knihy.

Softvérová implementácia

Existuje veľa softvérových implementácií FFT, ja som však napísal svoju vlastnú. Hlavným cieľom, ktorý som sledoval, bola optimalizácia kódu pre konkrétnu architektúru. Po prvé som sa hneď zameral na 32-bit, po druhé boli potrebné len celočíselné výpočty a bolo žiaduce vyhnúť sa operácii delenia. Nájsť niečo hotové, čo by tieto požiadavky spĺňalo, je už problematické.

Všetky konštanty, ktoré bolo možné vypočítať vopred, boli vypočítané a umiestnené do tabuliek (väčšinou hodnoty goniometrických funkcií). Toto je hlavná optimalizácia algoritmu, inak takmer úplne opakuje opísaný algoritmus.

Najdôležitejšia je požiadavka na celočíselné výpočty. Počas procesu implementácie dokonca došlo k chybe, ktorá spôsobila pretečenie v jednej z 32-bitových premenných slučky. Navyše sa neobjavil na všetkých testovacích údajoch, takže spôsoboval dosť bolesti hlavy, kým sa nenašiel.

Všetky pramenné texty som zhromaždil v jednom archíve. Implementácia nie je konečná, existujú duplicitné výpočty (neberie sa do úvahy spektrálna a fázová symetria) a je potrebná optimalizácia použitia vyrovnávacích pamätí, keďže v súčasnosti sa na výpočty používa príliš veľa RAM (takmer 12k na prepočet 1024 bodov ).

Prvé testy

Drum roll: Testujem rýchlosť prevodu na vzorke 1024 bodov, frekvencia jadra procesora je 60 MHz. Testovanie bolo vykonané v emulátore, takže si netvrdí, že je 100% presné, ale tento výsledok sa dá použiť ako indikátor (podľa mojich predchádzajúcich skúseností, hoci emulátor klamal, nebolo to veľa). Test prvej verzie kódu, kompilátor RealView MDK, možnosť optimalizácie O3, režim generovania kódu ARM.

Čo teda vidíme:

6 ms pre každú konverziu, celkovo niečo cez 12 ms pre spiatočnú konverziu. Ukazuje sa, že pri vzorkovacej frekvencii 44100 Hz (štandard pre zvuk) a vzorkách s rozlíšením až 16 bitov budú čisté výpočty trvať ~44*12ms = 528ms. A to je na prechodnej verzii firmvéru, keď niektoré optimalizácie kódu ešte neboli dokončené (podľa odhadov môže byť algoritmus zrýchlený takmer dvakrát)! Podľa mňa je to len výborný ukazovateľ.

Celkovo sa očakáva zaťaženie jadra okolo 50 %, ďalších 50 % zostáva na konverzie cez spektrum a režijné náklady pri práci s ADC, DAC a inými dátovými prenosmi. Ak znížite vzorkovaciu frekvenciu na „telefónnu“ úroveň (asi 4800-9600Hz), zaťaženie jadra bude ešte nižšie (asi 15-30%).

Takže matematická časť je viac-menej jasná. Môžete pristúpiť ku konkrétnej realizácii.

Železo

Pre testovaciu platformu sme použili vývojovú dosku Keil MCB2140 s reproduktorom. Kábel Mini-Jack je prispájkovaný na pripojenie k lineárnemu výstupu zariadenia a je zostavený jednoduchý vstupný reťazec. Ako už bolo spomenuté, na doske je už pripojený reproduktor na analógový výstup mikrokontroléra a nechýbajú ovládacie prvky (tlačidlo a potenciometer).

Tu je náčrt vstupného obvodu:


Ladenie softvéru prebiehalo v etapách:

  1. Odladenie všetkých potrebných periférií: ADC, DAC, časovače, LED indikácia.
  2. Test s digitalizáciou signálu: Dáta zdigitalizujem požadovanou rýchlosťou a vložím do vyrovnávacej pamäte, potom údaje z vyrovnávacej pamäte vytiahnem a prehrám signál. Tie. jednoduchý posun signálu v čase, bez akýchkoľvek transformácií. V tejto fáze sa testuje mechanizmus práce s 2 nárazníkmi, potrebnými pre ďalšiu prácu.
  3. Dopredná a inverzná Fourierova transformácia sú pridané k predchádzajúcej verzii. Tento test nakoniec overí správne fungovanie kódu FFT, ako aj skontroluje, či kód zapadá do dostupného výkonu.
  4. Potom je hlavná kostra aplikácie hotová, môžete prejsť k praktickým aplikáciám.

Problém nastal po pridaní FFT do kódu: v signáli sa objavil cudzí šum a píšťalky. Vo všeobecnosti sa mi toto správanie zdalo dosť zvláštne, pretože... Bez konverzie zostal signál prechádzajúci digitálnou cestou celkom čistý. Prvý dôvod: po analógovom obvode nebola amplitúda signálu na ADC plná (0-3,3V), ale iba v rozmedzí 0,5-2V pri maximálnej hlasitosti prehrávača, druhý: dosť silný šum spôsobený celým číslom výpočty (+-1 jednotka, čo sa ukázalo ako dostatočné na to, aby spôsobilo počuteľné rušenie).

Na boj proti prvému problému bolo rozhodnuté začať s úpravou analógovej časti. A na vyriešenie problému so šumom skúste použiť dolnopriepustný filter.

Aplikácia 1: zmena tónu signálu

Doska má potenciometer (variabilný odpor), ktorý je možné použiť na ovládanie. V tomto prípade nastaví posun spektra signálu nahor a nadol, čo je dosť na „transformáciu“ vašich obľúbených skladieb.

Čo sa deje vo frekvenčnej doméne:


V tomto prípade je výsledok konverzie obsiahnutý v 2 bufferoch. Jeden nárazník je skutočná časť a druhý je imaginárna časť. Fyzický význam čísel získaných v nich: skutočná časť obsahuje hodnoty harmonických, imaginárna časť obsahuje fázový posun pre tieto harmonické. Navyše, ako vidíte, počiatočný signál je opísaný N-hodnotami a po konverzii sa získajú 2N-hodnoty. Množstvo informácií sa nemení a k 2-násobnému zvýšeniu množstva informácií dochádza v dôsledku toho, že dáta vyrovnávacej pamäte majú redundanciu vo forme duplicitných hodnôt.

Ako zobrazovacie zariadenie sa používa dvojriadkový znakový LCD indikátor. Hlavným bodom pri realizácii tohto projektu nie je hardvér, ale softvér, presnejšie implementácia diskrétnej Fourierovej transformácie (DFT) na 8-bitovom mikrokontroléri. Hneď je potrebné poznamenať, že autor nie je odborníkom v tejto oblasti a preto začal základmi - jednoduchou diskrétnou Fourierovou transformáciou. Algoritmus rýchlej Fourierovej transformácie je nielen rýchly, ale aj pomerne zložitý.

Diskrétna Fourierova transformácia (v anglickej literatúre DFT, Discrete Fourier Transform) je jednou z Fourierových transformácií široko používaných v algoritmoch digitálneho spracovania signálu (jej modifikácie sa používajú pri kompresii zvuku v MP3, kompresii obrazu v JPEG atď.), ako aj v iné oblasti súvisiace s analýzou frekvencií v diskrétnom (napríklad digitalizovanom analógovom) signáli. Diskrétna Fourierova transformácia vyžaduje ako vstup diskrétnu funkciu. Takéto funkcie sa často vytvárajú vzorkovaním (vzorkovanie hodnôt zo spojitých funkcií).

Schéma zapojenia spektrálneho analyzátora audio signálu je veľmi jednoduchá a možno ju rozdeliť na digitálnu a analógovú časť.

Digitálnu časť tvorí mikrokontrolér a k nemu pripojený LCD indikátor. Mikrokontrolér je taktovaný z kremenného rezonátora 16 MHz; napájacie napätie +5 V sa používa ako referenčné napätie pre ADC mikrokontroléra.
Dátová zbernica LCD indikátora je pripojená na port C mikrokontroléra (vstupné/výstupné linky PC0-PC3), riadiaca zbernica je pripojená na port D (PD5, PD6) mikrokontroléra. Indikátor pracuje v 4-bitovom režime. Na nastavenie kontrastu sa používa variabilný odpor s nominálnou hodnotou 4,7 kOhm. Pre prácu s indikátorom boli vytvorené vlastné symboly na zobrazenie 8 horizontálnych stĺpcov analyzátora; tieto vlastné symboly zaberajú všetkých 64 bajtov RAM indikátora LCD.

Mikrokontrolér pracuje z externého 16 MHz kremenného rezonátora.

Analógová časť zariadenia je najdôležitejšou časťou a je predzosilňovačom signálu elektretového mikrofónu, ktorého výstup je pripojený na kanál ADC0 ADC zabudovaného v mikrokontroléri. Nulovú úroveň na vstupe ADC potrebujeme nastaviť presne na polovicu referenčného napätia, t.j. 2,5 V. V tomto prípade môžeme použiť kladnú a zápornú polvlnu signálu, ale jej amplitúda by nemala prekročiť stanovenú hranicu, t.j. Zisk musí byť jemne nastavený, aby sa zabránilo preťaženiu. Všetky vyššie uvedené podmienky spĺňa bežný mikroobvod operačného zosilňovača s nízkym výkonom.

Algoritmus DFT je o niečo pomalší v porovnaní s rýchlou Fourierovou transformáciou. Náš spektrálny analyzátor však nevyžaduje vysokú rýchlosť a ak dokáže poskytnúť rýchlosť aktualizácie približne 30 snímok za sekundu, bude to viac než dosť na vizualizáciu spektra zvukového signálu. V každom prípade je v našej verzii možné dosiahnuť rýchlosť 100 snímok za sekundu, ale to je už príliš vysoká hodnota parametra pre dvojriadkový znakový LCD indikátor a neodporúča sa. Vzorkovacia frekvencia je 20 kHz pre 32 bodovú diskrétnu Fourierovu transformáciu a keďže výsledok transformácie je symetrický, stačí nám použiť len prvú polovicu, t.j. prvých 16 výsledkov. Preto môžeme zobraziť frekvenčné spektrum až do 10 kHz a rozlíšenie analyzátora je 10 kHz/16 = 625 Hz.

Autor návrhu sa pokúsil zvýšiť rýchlosť výpočtov DFT. Ak má táto transformácia N bodov, musíme nájsť hodnoty N2/2 sínusu a kosínusu. Pre našu 32-bodovú transformáciu potrebujeme nájsť 512 sínusových a kosínusových hodnôt. Pred ich nájdením však musíme vypočítať uhol (stupne), ktorý zaberie určitý čas procesora, takže bolo rozhodnuté použiť na tieto výpočty tabuľky hodnôt. Pri výpočte v programe mikrokontroléra sa nepoužívajú čísla s pohyblivou rádovou čiarkou a čísla s dvojnásobnou presnosťou, pretože ich spracovanie na 8-bitovom mikrokontroléri bude trvať dlhšie. Namiesto toho hodnoty vo vyhľadávacích tabuľkách používajú 16-bitové celočíselné údaje vynásobené 10 000. Potom sa po vykonaní konverzie výsledky vydelia číslom 10 000. S týmto prístupom je možné vykonať 120 32-bodových konverzií za sekundu , čo je pre naše zariadenia viac než dosť.

Ukážka činnosti spektrálneho analyzátora na mikrokontroléri ATmega32

K stiahnutiu

Zdrojový kód (program mikrokontroléra, tabuľky sínusových, kosínusových a uhlových údajov) -

  • Je jasné, že na AVR je ťažké zájsť ďalej ako svetlo a hudba, parametre nie sú v poriadku. Ale 120 32-bodových konverzií za sekundu môže stačiť na väčšinu úloh. A môžete si samozrejme vziať ďalšiu vzorku 625 Hz, alebo skôr stratiť obnovovaciu frekvenciu. Stojí za zmienku, že MK sa bude cítiť zle, pokiaľ ide o výkon, nie je na ňom možné nič iné. Ale tu môžete usporiadať výstup výsledku pomocou hardvérových metód prenosu údajov. Potom to bude pomocný mikrokontrolér a ten hlavný bude z neho iba prijímať dáta a spracovávať ich kompatibilne s inými procesmi. Vo všeobecnosti to stále závisí od frekvencie procesora. Kedysi bolo možné pretaktovať mega nad 20 MHz, no na tieto úlohy sa zrejme dočkáme len glitchov na vysokých frekvenciách. Myšlienka je dobrá, len keby bolo napísaných viac matematických častí... je to jej implementácia na MK
  • Urobil som aj zaujímavejšie analyzátory: You Tube alebo verzia na farebnom LCD: You Tube je založená na slávnej Chen knižnici :)
  • „Musíme vypočítať uhol (stupne)“ Môže nám niekto povedať podrobnejšie, ako sa vypočítavajú hodnoty pre tieto tabuľky?
  • S tabuľkou sínusov a kosínusov je všetko jasné. Nie je jasné, ako sa vypočítavajú hodnoty v tabuľke degree_lookup?

Úvod

Knihy a publikácie o digitálnom spracovaní signálov píšu autori, ktorí často nemajú ani poňatia a ani nerozumejú výzvam, ktorým vývojári čelia. To platí najmä pre systémy pracujúce v reálnom čase. Títo autori si prisudzujú skromnú úlohu boha, ktorý existuje mimo čas a priestor, čo vyvoláva u čitateľov takejto literatúry určité zmätok. Cieľom tejto publikácie je rozptýliť zmätok, ktorý vzniká medzi väčšinou vývojárov, a pomôcť im prekonať „prah vstupu“; na tieto účely text zámerne používa analógie a terminológiu z oblasti programovania.

Tento opus nepredstiera, že je úplný a koherentný.

Pridané po prečítaní komentárov.
Existuje nespočetné množstvo publikácií o tom, ako vytvoriť FFT, ale zjavne nie je dostatok publikácií o tom, ako vytvoriť FFT, konvertovať spektrum a znovu zostaviť signál, a to dokonca v reálnom čase. Autor sa snaží túto medzeru vyplniť.

Prvá časť, prehľad

Existujú dva hlavné spôsoby konštrukcie diskrétnych lineárnych dynamických systémov. V literatúre sa takéto systémy zvyčajne nazývajú digitálne filtre, ktoré sa delia na dva hlavné typy: filtre s konečnou impulzovou odozvou (FIR) a filtre s nekonečnou impulznou odozvou (IIR).

Algoritmickou podstatou FIR filtra je diskrétny výpočet konvolučného integrálu:

Kde x(t) je vstupný signál
y(t) – výstupný signál
h(t) – impulzná odozva filtra alebo odozva filtra na funkciu delta. Impulzná odozva je inverzná Fourierova transformácia komplexnej frekvenčnej odozvy filtra K(f).

Aby si čitateľ vytvoril jasný obraz, uvedieme príklad diskrétneho výpočtu konvolučného integrálu v jazyku C v reálnom čase.

#define L (4) //dĺžka filtra int FIR(int a) ( static int i=0; //aktuálna pozícia static int reg[L]; //pole vstupných hodnôt ​​static const int h[L]= (1, 1,1,1);//impulzná odozva int b=0;//výstupná hodnota reg[i]=a; //skopírujte vstupnú hodnotu do poľa vstupných hodnôt pre (int j=0 j

Volaním tejto funkcie v určitých časových intervaloch T a odovzdaním vstupného signálu ako argumentu dostaneme na výstupe výstupný signál zodpovedajúci odozve filtra s impulznou odozvou v tvare:

H(t) = 1 pri 0 h(t)=0 v ostatných prípadoch.

Pre všetkých prítomných je filter s takouto impulznou odozvou lepšie známy ako „filter s pohyblivým priemerom“, a preto je oveľa jednoduchší na implementáciu. V tomto prípade sa ako príklad používa takáto impulzná odozva.

Veľa literatúry sa venuje syntéze impulzných odoziev FIR filtrov, existujú aj hotové softvérové ​​produkty na získanie filtrov so špecifikovanými vlastnosťami. Autor preferuje zabugovaný nástroj Filter Design z balíka Matlab, ale to je vec vkusu.

Pomocou filtra s konečnou impulznou odozvou je možné vzniesť sa trochu nad bežnú realitu, keďže v prírode neexistujú dynamické systémy, ktoré by mali konečnú impulznú odozvu. FIR filter je pokusom vstúpiť do časovo-frekvenčnej domény z druhého konca, nie ako to chodí v prírode, takže frekvenčné charakteristiky týchto filtrov majú často neočakávané vlastnosti.

Oveľa bližšie k prírode sú filtre s nekonečnou impulznou odozvou. Algoritmická podstata filtrov s nekonečnou impulznou odozvou spočíva v rekurentnom (nemýliť si s rekurzívnym!) riešením diferenciálnej rovnice popisujúcej filter. To znamená, že každá nasledujúca hodnota výstupného signálu filtra sa vypočíta na základe predchádzajúcej hodnoty. Presne takto fungujú procesy v reálnom svete. Kameň padajúci z mrakodrapu každú sekundu zvýši svoju rýchlosť o 9,8 m/s Rýchlosť=Rýchlosť+9,8 a prejdená vzdialenosť sa zväčší každú sekundu. Vzdialenosť=Vzdialenosť+rýchlosť. Kto hovorí, že to nie je rekurentný algoritmus, nech je prvý, kto do mňa hodí kameňom. Iba v našom Matrixčasový interval pre volanie funkcie, ktorá vracia polohu kameňa, je oveľa menší ako deliaca cena meracích prístrojov, ktoré máme k dispozícii.

Samostatne by som chcel definovať pojem „poradie filtra“. Toto je počet premenných, ktoré sú predmetom opakujúcich sa operácií. Vo vyššie uvedenom príklade je funkcia, ktorá vracia rýchlosť kameňa, prvého rádu, funkcia, ktorá vracia prejdenú vzdialenosť, je druhého rádu.

Aby sme čitateľa konečne osvietili, uvedieme v jazyku C príklad najjednoduchšieho dolnopriepustného filtra, všeobecne známeho ako filter „exponenciálny vyhladzovací filter“.

#define alfa (2) //parameter vyhladenia int filter(int a) ( static int out_alfa=0; out_alfa=out_alfa - (out_alfa >>alfa) + a; return (out_alfa >> alfa); )

Volaním tejto funkcie s frekvenciou F a jej odovzdaním vstupného signálu ako argumentu dostaneme výstupný signál zodpovedajúci odozve dolnopriepustného filtra prvého rádu s medznou frekvenciou:

Uvedený príklad zdrojového kódu je z hľadiska pochopenia podstaty algoritmu úplne nezrozumiteľný. Z hľadiska rekurentnej podstaty (pozri „pád kameňa“) algoritmu je správnejšie y=y+((x-y)>>alfa);, ale v tomto prípade dochádza k významnej strate alfa číslic. Výraz opakujúceho sa filtra z príkladu kódu je skonštruovaný tak, aby sa zabránilo strate významných bitov. Práve konečná presnosť výpočtov môže pokaziť krásu digitálneho filtra s nekonečnou impulznou odozvou. Toto je obzvlášť viditeľné na filtroch vyššej kategórie s vysokým faktorom kvality. V skutočných dynamických systémoch tento problém nevzniká, náš Matrix robí pre nás výpočty s neuveriteľnou presnosťou.

Syntéze takýchto filtrov sa venuje veľa literatúry a existujú aj hotové softvérové ​​produkty (pozri vyššie).

Druhá časť. Fourierov filter

Z univerzitných kurzov (pre vás to bol kurz OTEC) si mnohí z prítomných pamätajú dva hlavné prístupy k analýze lineárnych dynamických systémov: analýzu v časovej oblasti a analýzu vo frekvenčnej oblasti. Analýza v časovej oblasti je riešením diferenciálnych rovníc, konvolúcie a Duhamelových integrálov. Tieto analytické metódy sú diskrétne začlenené do digitálnych IIR a FIR filtrov.

Existuje však frekvenčný prístup k analýze lineárnych dynamických systémov. Niekedy sa nazýva operátor. Ako operátory sa používajú Fourierova transformácia, Laplaceova transformácia atď. Ďalej budeme hovoriť len o Fourierovej transformácii.

Táto metóda analýzy nie je široko používaná pri konštrukcii digitálnych filtrov. Autor nebol schopný nájsť rozumné praktické odporúčania na konštrukciu takýchto filtrov v ruštine. Jediná krátka zmienka o takomto filtri v praktickej literatúre je [Rabiner L., Gould B., Theory and Application of Digital Signal Processing 1978], ale v tejto knihe je úvaha o takomto filtri veľmi povrchná. V tejto knihe sa táto schéma konštrukcie filtra nazýva: „konvolúcia v reálnom čase pomocou metódy FFT“, čo podľa môjho skromného názoru vôbec neodráža podstatu, názov by mal byť krátky, inak nezostane čas na oddych.

Odozvou lineárneho dynamického systému je inverzná Fourierova transformácia súčinu Fourierovho obrazu vstupného signálu x(t) a komplexného koeficientu prenosu K(f):

V praxi tento analytický výraz predpokladá nasledujúci postup: vezmeme Fourierovu transformáciu vstupného signálu, vynásobíme výsledok komplexným koeficientom prenosu, vykonáme inverznú Fourierovu transformáciu, ktorej výsledkom je výstupný signál. V reálnom diskrétnom čase sa tento postup nedá vykonať. Ako zobrať integrál v čase od mínus do plus nekonečna?! Dá sa užívať len mimo času...

V diskrétnom svete existuje nástroj na vykonávanie Fourierovej transformácie - algoritmus rýchlej Fourierovej transformácie (FFT). To je to, čo použijeme pri implementácii nášho Fourierovho filtra. Argumentom funkcie FFT je pole časových vzoriek 2^n prvkov, výsledkom sú dve polia s dĺžkou 2^n prvkov zodpovedajúce reálnej a imaginárnej časti Fourierovej transformácie. Samostatnou vlastnosťou algoritmu FFT je, že vstupný signál sa považuje za periodický s intervalom 2^n. To kladie určité obmedzenia na algoritmus Fourierovho filtra. Ak zoberiete sekvenciu vzoriek vstupného signálu, vykonajte na nich FFT, vynásobte výsledok FFT komplexným ziskom filtra a vykonajte inverznú transformáciu... nič nevyjde! Výstupný signál bude mať obrovské nelineárne skreslenia v blízkosti prechodov vzoriek.

Na vyriešenie tohto problému musíte použiť dve techniky:

  • 1. Vzorky musia byť spracované Fourierovou transformáciou s presahom. To znamená, že každá nasledujúca vzorka musí obsahovať časť predchádzajúcej vzorky. V ideálnom prípade by sa vzorky mali prekrývať s (2^n-1) vzorkami, čo si však vyžaduje enormné výpočtové úsilie. V praxi postačuje viac ako trojštvrťové (2^n-2^(n-2)), polovičné (2^(n-1)) a dokonca štvrtinové prekrytie (2^(n-2)).
  • 2. Výsledky inverznej Fourierovej transformácie, aby sa získal výstupný signál, sa musia pred vzájomným prekrytím vynásobiť váhovou funkciou (polom váhových koeficientov). Funkcia váženia musí spĺňať tieto podmienky:
  • 2.1 Rovná sa nule všade okrem intervalu 2^n.
  • 2.2 Na okrajoch intervalu má tendenciu k nule.
  • 2.3 A čo je najdôležitejšie, súčet váhových funkcií Fv(t) posunutých o interval prekrytia k musí byť konštantný:

Takéto funkcie sú široko používané v technológii digitálneho spracovania signálu a zvyčajne sa nazývajú okná. Podľa skromného názoru autora je z praktického hľadiska najlepšie okno pomenované po Khanovi:

Na obrázku sú znázornené grafy znázorňujúce vlastnosti Hahnovho okna s dĺžkou 2^n=256. Inštancie okien sú zostavené s polovičným prekrytím k=128. Ako vidíte, všetky vyššie uvedené vlastnosti sú k dispozícii.

Na želanie pracovníkov je na nasledujúcom obrázku znázornená schéma výpočtov Fourierovho filtra, s dĺžkou vzorky 2^n=8, počet vzoriek je 3. Na takýchto obrázkoch je veľmi ťažké zobraziť proces výpočtu. , je obzvlášť ťažké ukázať jeho cyklickosť, preto sme obmedzili počet vzoriek na tri .

Vstupný signál sa rozdelí na bloky dĺžky 2^n=8 s prekrytím 50 %, z každého bloku sa odoberie FFT, výsledky FFT prejdú potrebnou transformáciou, zoberie sa inverzná FFT, výsledok inverznej FFT sa skalárne vynásobené oknom, po vynásobení sa bloky sčítavajú s presahom.

Pri vykonávaní transformácií spektra nezabudnite na hlavnú vlastnosť poľa FFT reálnych signálov, prvá polovica poľa FFT je komplexne konjugovaná s druhou polovicou, t.j. Re[i]=Re[(1<

Teraz vieme všetko, čo potrebujeme na napísanie algoritmu Fourierovho filtra. Poďme si popísať algoritmus v jazyku C.

#include #define FSempl (8000) //vzorkovacia frekvencia Hz #define BufL (64) //dĺžka vyrovnávacej pamäte spracovania #define Perk (2) //prekrytie snímok 2-1/2, 4-3/4 //obmedzenie spektra, pásmový filter #define FsrLow (300)//nízka frekvencia filtra Hz #define FsrHi (3100)//vysoká frekvencia filtra Hz #define FsrLowN ((BufL*FsrLow+(FSempl/2))/FSempl)//nízka frekvencia v harmonických #define FsrHiN ((BufL*FsrHi +(FSempl/2))/FSempl)//vysoká frekvencia v harmonických //Posun spektra #define SdvigSp (0)//posun spektra v harmonických +(nadol) -(nahor) 0 (bez posunu) //Filter časového spektra, echo #define FilterSpekrtaT_EN (1)//použitie spektrálneho filtra 1/0 #define FiltSpektrFsr (0,100025f) //medzná frekvencia spektrálneho filtra volatilná unsigned short ShBuf;//vstupné počítadlo buffer signed short BufIn;/ / vstupný buffer podpísaný krátky BufOut;//výstupný buffer podpísaný krátky BufInOut;//bufer na prepísanie float FurRe;//Fourierova reálna časť float FurIm;//Fourierova imaginárna časť #if (FilterSpekrtaT_EN!=0) float FStektr;//amplitúda filtra spektrum #endif //Sínusová kosínusová tabuľka #if BufL==64 const float SinCosF= ( 0,000000000 , 0,098017140 , 0,195090322 , 0,290284677 , 0,375257685 7,03752756834 0233, 0,634393284, 0,707106781, 0,773010453, 0,831469612, 0,881921264, 0,9203879533, 0,9569409336, 0,9569409336 0,995184727, 1,000000000, 0,995184727, 0,980785280, 0,956940336, 0,923879533, 0,881921264, 0,881921264, 0,0777 0,077 106781 , 0,634393284 , 0,555570233 , 0,471396737 , 0,382683432 , 0,290284677 , 0,195090322 0,04 0,04 0,04 98017140, -0,195090322, -0,290284677, -0,382683432, - 0,471396737, -0,555570233, -0,634393284, -0,707106781, -0,773010453, -0,831469612, -0,881921264, -0,881921264, -95,938, -99384, -093,03 785280, -0,99 5184727, -1,000000000, -0,995184727, -0,980785280, -0,956940336, -0,923879533, -0,841921 , - 0,831469612, -0,773010453, -0,707106781, -0,634393284, -0,555570233, -0,471396737, -0,3826832932, -80,2192, -0,04,04,21922, -0,00,04 980 17140, 0,000000000, 0,098017140, 0,195090322, 0,290284677, 0,382683432, 0,4713966737, 0,723557, 0,723557, 317,71 81 , 0,773010453, 0,831469612, 0,881921264, 0,923879533, 0,956940336, 0,980785280, 0,995184727); #endif //FFT triediaca tabuľka #if BufL==64 const unsigned short sortFFT= ( 0x0000,0x0020,0x0010,0x0030,0x0008,0x0028,0x0018,0x0038, 0x0024,1x0,0,0,00 002C, 0x001C, 0x003C , 0x0002,0x0022,0x0012,0x0032,0x000A,0x002A,0x001A,0x003A, 0x0006,0x0026,0x0016,0x0016,0x0016,0x0,00000001E0000 0x0001, 0x0021,0x0011,0x0031,0x0009,0x0029,0x0019,0x0039, 0x0005 ,0x0025,0x0015,0x0035,0x000D,0x002D,0x001D,0x003D, 0x0003,0x0023,0x0013,0x0033,0x002B,0x01B,0x01B,0x0,0x0 x0027,0 x0017,0x0037,0x000F,0x002F,0x001F,0x003F ); #endif //Tabuľka okna Han #if BufL==64 const float WinHanF= ( 0. 0, 0,002407637, 0,00960736, 0,021529832, 0,038060234, 0,059039368, 0,084265194, 0,1134947473, 0,1134947473, 8460,02 22214883, 0,264301632, 0,308658284, 0,354857661, 0,402454839, 0,45099143, 0,5, 0,54900857, 954 000857, 514 00831 1716, 0,735698368, 0,777785117, 0,817196642, 0,853553391; 0,886505227, 0,915734806 9903 9264, 0,978470168, 0,961939766, 0,940960632, 0,915734806, 0,886505227, 0,853553391, 6,517719, 0,5171719, 0,5171719 68, 0,691341716, 0,645142339, 0,597545161, 0,54900857, 0,5, 0,45099143, 0,402454839, 0,354857661, 0,308658284, 0,264301632, 0,222214883, 0,1828031758, 0,1828031758, 0,1828031758, 0,34,09460,308658284 084265194, 0,059039368, 0,038060234, 0,021529832, 0,00960736, 0,002407637); #koniec Ak //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //Výpočet priamej rýchlej Fourierovej transformácie //argumenty //ukazovateľ na pole v skutočnosti ReFT a imaginárna časť ImFT //Po vykonaní polia obsahujú koeficient. skutočné a imaginárne časti void FFTnoInv(float* ReFT,float* ImFT) ( //kopírovanie a preusporiadanie pre (int i=0;i >1; dlhý arg=0; // argument jadra, fáza pre (int j=0;j >1; long arg=0;////argument jadra, fáza pre (int j=0;j 0 //posun spektra nadol, Karabas-Barabas for(int i=1;i<(BufL/2);i++) { if(i>=(BufL/2-SdvigSp)) ( FurRe[i]=FurIm[i]=0; FurRe=FurIm=0; pokračovať; ) FurRe[i]=FurRe; FurIm[i]=FurIm; FurRe=FurRe[i]; FurIm=-FurIm[i]; ) #endif #if SdvigSp<0 //сдвиг спектра вверх, Буратино for(int i=(BufL/2-1);i>0;i--) (ak(i<=(-SdvigSp)) { FurRe[i]=FurIm[i]=0; FurRe=FurIm=0; continue; } FurRe[i]=FurRe; FurIm[i]=FurIm; FurRe=FurRe[i]; FurIm=-FurIm[i]; } #endif //обрезание спектра, полосовой фильтр FurRe=0.0F;FurIm=0.0F; //постоянная составляющая FurRe[(BufL/2)]=0.0F;FurIm[(BufL/2)]=0.0F;//последняя гармоника float ZnStektr;//амплитудный спектр кадра for(int i=1;i<(BufL/2);i++) { if((i < FsrLowN)//нижняя частота || (i >FsrHiN)//vysokofrekvenčný) (//medzenie spektra, harmonické mimo pásma sú vynulované FurRe[i]=0,0F;FurIm[i]=0,0F;//priame harmonické FurRe=0,0F;FurIm=0,0F ;//konjugujte harmonické ) else //vypočítajte amplitúdové spektrum nerozrezanej časti ( ZnStektr[i]=sqrtf(FurRe[i]*FurRe[i])+(FurIm[i]*FurIm[i]);// amplitúdové spektrum ) ) // filter amplitúdového spektra v čase, echo for(int i= FsrLowN;//nižšia frekvencia i<=FsrHiN ;//верхняя частота i++) { #if FilterSpekrtaT_EN!=0 //фильтр спектра во времени, эхо FStektr[i]=FStektr[i]+ FiltSpektrFsr*(ZnStektr[i]-FStektr[i]); #endif //переходим от модуля к комплексному числу FurRe[i]=FurRe=(FStektr[i]*FurRe[i])/ZnStektr[i]; FurIm[i]=(FStektr[i]*FurIm[i])/ZnStektr[i]; FurIm=-FurIm[i]; } //выполняем обратное БПФ FFTInv(FurRe,FurIm); //копирование буферов for(int i=0;i<(BufL);i++) { BufInOut[i]=((signed short)(FurRe[i]+0.5f)); } } //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ //Фурье фильтр signed short FureFilter(signed short t1) { //записываем во входной буфер BufIn=t1; //выходное значение signed short out=BufOut; //инкремент указателя буфера ShBuf=(ShBuf+1)&((BufL*2)-1); //если в буфере часть кадра обработки if((ShBuf&((BufL/Perk)-1))==0) { //переписываем буфер обработки в выходной буфер int ShTmpOut=ShBuf; int ShTmpIn=(ShBuf-BufL)&((BufL*2)-1); for(int i=0;i<(BufL);i++) { if(i<(BufL-(BufL/Perk))) { //переписываем первую часть буфера обработки в выходной буфер BufOut=BufOut+BufInOut[i]; } else { //переписываем вторую часть буфера обработки в выходной буфер BufOut=BufInOut[i]; } //инкремент указателя выходного буфера ShTmpOut=(ShTmpOut+1)&((BufL*2)-1); //переписываем входной буфер в буфер обработки BufInOut[i]=BufIn; //инкремент указателя входного буфера ShTmpIn=(ShTmpIn+1)&((BufL*2)-1); } }//конец if((ShBuf&((BufL/Perk)-1))==0) //вызов функции обработки //в на реальном процессоре распараллелить! if((ShBuf&((BufL/Perk)-1))==0)ObrBuf(); return out; }

Zavolaním funkcie FureFilter() s frekvenciou FSempl a odovzdaním vstupného signálu ako argumentu bude výsledkom výstupný signál. V tomto príklade je vstupný signál spracovaný nasledovne: signál prechádza cez pásmový filter s medznými frekvenciami FsrLow, FsrHi, všetky spektrálne zložky nad a pod uvedenými frekvenciami sú potlačené, spektrum signálu je posunuté (pre audio signály je to vnímaný ako efekt Buratino-Karabas), amplitúdové spektrum signálu je vyhladené dolnopriepustným filtrom (pre zvuk je to efekt dunivej miestnosti). Tieto akcie so signálom sa vykonávajú ako príklad s cieľom ukázať technické techniky na spracovanie signálu vo frekvenčnej oblasti, ako napríklad: udržiavanie komplexnej konjugácie koeficientov, obnovenie komplexného spektra z amplitúdy, bez použitia goniometrických funkcií atď.

Záver

Stojí za zmienku, že táto funkcia Fourierovho filtra s najväčšou pravdepodobnosťou nebude v praxi fungovať. Pri volaní tejto funkcie sa aj pri nízkej frekvencii 8000 Hz nestihne vykonať do nasledujúceho volania, výkon nebude stačiť. Tento kód Fourierovho filtra sa poskytuje ako popis algoritmu bez odkazu na špecifické hardvérové ​​zdroje a má čisto vzdelávacie účely (pozri Úvod).

V praktickej implementácii je potrebné paralelizovať vykonávanie funkcie vypĺňania a vyprázdňovania vyrovnávacej pamäte BufInOut (najlepšie DMA atď.) a funkcie spracovania vyrovnávacej pamäte ObrBuf(), ale to je úplne iný príbeh.

Fourierova veta hovorí, že každý signál môže byť rozšírený do série v ortonormálnom súbore periodických funkcií (napríklad sínus a kosínus) s frekvenciami, ktoré sú násobkami frekvencie periodického signálu. Spektrálna analýza signálu je teda založená na hľadaní váhových koeficientov (vo všeobecnom prípade komplexných), ktorých modul zodpovedá zlomku oscilačného výkonu zodpovedajúcej harmonickej zavedenej do všeobecnej superpozície všetkých harmonických. .

Rýchla Fourierova transformácia

Rýchla Fourierova transformácia je výpočtový algoritmus, ktorý úspešne využíva vlastnosti periodicity goniometrických funkcií, aby sa zabránilo zbytočným výpočtom v diskrétnej Fourierovej transformácii (DFT), čím sa urýchli nájdenie koeficientov vo Fourierovej expanzii. Hlavný rozdiel od diskrétnej konverzie je len v spôsobe výpočtu číselných hodnôt (algoritmus), a nie v samotnom spracovaní signálu. V prípade FFT aj v prípade DFT je výsledok výpočtov rovnaký. Jedinou požiadavkou pre algoritmus FFT je veľkosť vzorky, ktorá je násobkom N = 2L, kde L je akékoľvek kladné celé číslo. Najbežnejšie základné 2 FFT algoritmy sú: časovo zdecimované a frekvenčne zdecimované.

V tejto práci je implementovaný radix-2 FFT algoritmus s časovým stenčovaním (Cooley-Tukeyov algoritmus). Je ľahké ho získať štúdiom niektorých zákonov DFT. Zavedieme takzvaný rotačný koeficient:

V tomto prípade sú v DFT Fourierove koeficienty pre množstvo hodnôt signálu (f0,f1,…,fN-1) vyjadrené vzťahom:

Uvažujme sériu signálov so 4 hodnotami: (f0,f1,f2,f3). Uveďme Fourierovu transformáciu v maticovom tvare (normalizačný koeficient 1/N je zahrnutý v stĺpcovom vektore Cij na pravej strane výrazu):

Po zapísaní rotačných koeficientov pomocou Eulerovho vzorca a určení ich hodnôt pre k = 0, 1, 2,.. 9 môžete zostaviť diagram (obr. 2), z ktorého je možné vidieť vzor opakujúcich sa koeficientov.

Obrázok 2. Mocninný rad w pre N=4

Nahradením číselných hodnôt do (4) dostaneme:

To znamená, že hodnoty w začínajúce od w4 sa rovnajú zodpovedajúcej hodnote od w0 do w3. Ďalej prepíšeme maticovú rovnicu (4) do neštandardnej formy (pre prehľadnosť ďalších operácií sú zavedené podobné zápisy):

Vymeňme stĺpce matice a rozdeľme ju do dvoch skupín: podľa párnych indexov f0, f2 a nepárnych f1, f3:

Zoberme si, že wk+1 = wkw1, potom výraz (6) bude prepísaný ako:

Použitie pomerov:

Požadované koeficienty expanzie získame vo forme stĺpcového vektora s hodnotami buniek:

Grafické znázornenie algoritmu (obr. 3) vyzerá ako motýľ s otvorenými krídlami, preto sa tento spôsob výpočtu nazýva „motýľ“.

Obrázok 3. Motýľový graf pre sériu 4 výrazov

Takže v prvom kroku algoritmu sú členovia niekoľkých hodnôt signálu rozdelené na párne a nepárne indexy. Potom sa vykoná „motýľový“ graf, ktorý pozostáva z dvoch etáp, ich počet sa rovná mocnine dvoch veľkosti vzorky (N = 4 = 22). V každej fáze sa vykonávajú dva „motýle“ a ich celkový počet zostáva nezmenený. Každá operácia motýľa zodpovedá jednej operácii násobenia. Pre porovnanie: pri DFT so vzorkovaním (f0,f1,f2,f3) by bolo potrebné operáciu násobenia vykonať 4×4 = 16-krát a v prípade FFT len 4-krát.

teória

Najprv trocha teórie. Ako každý vie, takéto analyzátory používajú rýchlu Fourierovu transformáciu a často sa hovorí, že DFT nemožno použiť v takýchto návrhoch, iba FFT a dokonca aj v assembleri. Namiesto toho som použil diskrétnu Fourierovu transformáciu (DFT) a Walshovu transformáciu. A v tomto článku dokážem, že môžete dokonca použiť nielen FFT, ale aj DFT napísaný v C. Najprv však, ako získať jednoduchú funkciu DFT z DFT a podľa Walsha. DFT klasicky vyzerá takto:

Keďže μ má málo zdrojov, nahrádzajú cos a sin poliami s rozmerom N. Okrem toho je μ 8-bitové a je vhodnejšie ukladať polia vo forme 8-bitových hodnôt. Keďže cos a sin sa líšia od -1 do 1, je najlepšie tento rozsah zväčšiť 127-krát, pretože 8-bitová premenná so znamienkom môže ukladať hodnoty od -127 do 127. Teda, berúc do úvahy transformácie vzorca , bude to:

kde m sa mení z 0 na N-1 s krokom rovným k, keď sa m stane väčším ako N, m sa zníži o N-1. Celkovo sa používa 12 kanálov, takže výkon DFT je obmedzený na taký malý počet kanálov.

Napríklad máme 512 vzoriek ADC; musíme vypočítať imaginárne a skutočné časti pre 150 Hz pri vzorkovacej frekvencii 19200 Hz:

Skutočné a vymyslené časti sa teda získavajú oveľa rýchlejšie ako tradičným spôsobom, no 127-krát väčšie. Aby ste získali ich skutočné hodnoty, potrebujete deliť 127, ale MK žiadne delenie nemá, oveľa racionálnejšie by bolo báseň nedeliť, ale posúvať! Jeden posun je ekvivalentný deleniu 2. To znamená, že ak posuniete číslo 7-krát, v podstate ho vydelíte 128! Keďže straty v presnosti už boli nevyhnutné, delenie číslom 128 nezmení obraz.

Diskrétna Fourierova transformácia pre 150 Hz pri vzorkovacej frekvencii 19200 Hz potom vyzerá takto:

Pre Walsha nahrádzame sínusové a kosínusové vlny strednými hodnotami zodpovedajúcich periód. To znamená, že pre hriech od 0 do 180 stupňov to bude 1 a od >180 do 360 to bude -1. V súlade s tým je pre sínus od 0 do 90 1, od 90 do 270 je -1 a od 270 do 360 je 1. Všetky výpočty imaginárnej a reálnej časti budú teda jednoduchou akumuláciou súčtov a rozdielov hodnotu ADC. To znamená, že keď sa napríklad sínus rovná 1, potom sa hodnota ADC pripočíta a keď sa -1 odpočíta. Nevýhodou tohto riešenia je opäť chyba, ktorá sa nevyhnutne zvyšuje a dosahuje 20 %. Ale keďže môj návrh má len 8 hodnôt, opäť si málokto všimne výrazný rozdiel.

Príklad implementácie výpočtu imaginárnej a reálnej časti pre 150 Hz pri vzorkovacej frekvencii 19200 a 512 vzoriek:

Takto získame imaginárne a reálne časti pomerne rýchlo bez procedúr násobenia.

A tak po získaní imaginárnych a skutočných častí je potrebné nájsť amplitúdu spektra. Aby ste to dosiahli, musíte nájsť koreň súčtu druhých mocnín imaginárnej a reálnej časti. Ak ale použijete funkciu z matematickej knižnice, extrakcia bude trvať dlho a funkcia zožerie aj dosť veľký kus ROM. Po nejakom hrabaní na internete som našiel elegantnú funkciu, ktorú som potom ešte trochu zjednodušil, keďže pracuje na malých hodnotách. Toto je funkcia:

Po porovnaní tejto funkcie a funkcie z matematickej knižnice som dospel k záveru, že jej presnosť je úplne dostatočná na to, aby bol výsledok rovnaký. Samotná funkcia váži 2% oproti 12% MK ROM. Navyše počíta oveľa rýchlejšie.

Ale ako sa to stalo, že MK dokáže vypočítať 12 kanálov a dokonca aj v DFT. Okrem všetkých trikov s posunom namiesto delenia a funkciou rýchleho štvorca je tu ešte jeden trik. O ktorom vám teraz poviem. Faktom je, že čím vyššia je frekvencia výberu, tým užšie je priepustné pásmo filtra, pretože prechod cos a sin sa zrýchľuje a počet periód sa zvyšuje. A čím viac takýchto prechodov cos a sin, tým užšia je šírka pásma. Napríklad pri frekvencii 150 Hz sa cos a sin opakujú 4-krát a pri 1,2 kHz sa cos a sin opakujú 32-krát. Z toho je vidieť, že aby bolo priepustné pásmo jednotné na všetkých rozsahoch a pokrylo všetky frekvenčné rozsahy, musí sa počet vzoriek znižovať so zvyšujúcou sa frekvenciou filtrovania. Napríklad pre 150 Hz je vyvŕtaných všetkých 512 vzoriek, pre 600 Hz 256 vzoriek a pre 2,4 kHz 32 vzoriek atď. Nie je ťažké nahradiť, že znížením počtu vzoriek so zvyšujúcou sa frekvenciou sa rýchlosť DFT prudko zvýši, pretože je potrebné vykonať oveľa menej násobení a súčtov.

Praktická realizácia

A tak je teoretická časť pripravená, môžeme začať popisovať dizajn. Celá konštrukcia pozostáva z jedného mikrokontroléra, 4 tranzistorov, niekoľkých kondenzátorov a mnohých rezistorov. Je lepšie inštalovať veľa odporov, aj keď sa môžete obmedziť iba na odpory horizontálne, t.j. jeden pre každý pin portu. Schéma je klasická, až na jedinú vec, že ​​som použil 3 porty na 1 prechod dynamického skenovania namiesto 1, ako všade inde. To umožnilo znížiť frekvenciu rozmietania a znížiť počet tranzistorov na 4. Výsledkom bola vlastne mierka 24x4.

Spektrálny analyzátor pracuje pri vzorkovacej frekvencii 19,2 kHz z kryštálu 16 MHz.

Spektrálny analyzátor vypočítava spektrálne amplitúdy nasledujúcich frekvencií:

9,6 kHz, 4,8 kHz, 2,4 kHz, 1,6 kHz, 1,2 kHz, 800 Hz, 600 Hz, 500 Hz, 400 Hz, 300 Hz, 150 Hz, 75 Hz. Program bol testovaný pre 33 Hz a DFT uspel napriek skutočnosti, že rozmery cos a sin sa rovnali 512, ale rozhodli sa obmedziť na 75 Hz.

Sú tu frekvencie, ktoré nie sú násobkom 2 ku n-tej mocnine, ale napriek tomu sú vypočítané. Napríklad 400 Hz, keď vydelíme číslom 19200, dostaneme 48, čo nie je násobok 2 mocniny n. Vybral som si východisko zo situácie tak, že som číslo blízke číslu 2 umocnil n. Najbližšie je 240, blíži sa 256. To znamená, že z 512 sme odobrali len 240 vzoriek. Okrem toho nemôžete vziať len niečo blízko. Mohli by sme napríklad vziať 480, čo je blízko 512, ale napriek tomu sme vzali takmer 256. Vysvetlenie je, že pri rôznych frekvenciách počet vzoriek ovplyvňuje šírku pásma. Čím väčší je počet vzoriek, tým užšia je šírka pásma. Je to spôsobené tým, že pri vysokej frekvencii prechádza kosínus periódou oveľa rýchlejšie ako pri nízkej a amplitúda je vypočítaná tak presne, že susedné frekvencie sú jednoducho vyhodené a medzi frekvenciami sa vytvárajú slepé frekvenčné zóny, ktoré nie sú vnímané. analyzátorom. Aby analyzátor vnímal všetky frekvencie a pokryl celé spektrum, je potrebné pásmo pri vysokých frekvenciách zväčšiť odberom menšieho počtu vzoriek a pri nízkych frekvenciách ho čo najviac zúžiť odberom zodpovedajúceho väčšieho počtu vzoriek. Praktickým výberom počtu čítaní som teda vybral nasledovné:

9,6 kHz 16 impulzov, 4,8 kHz 32 impulzov, 2,4 kHz 32 impulzov, 1,6 kHz 60 impulzov, 1,2 kHz 64 impulzov, 800 Hz 240 impulzov, 600 Hz 256 impulzov, 500 Hz, 250 Hz 402 impulzov , 150 Hz 512 impulzov, 75 Hz 512 impulzov.

Táto voľba počtu vzoriek umožnila, aby pásmo bolo jednotné v celom frekvenčnom rozsahu.

Ďalšie úskalie nastalo pri frekvencii 9,6 kHz. Keďže neexistuje žiadna imaginárna časť (toto sa dá ľahko skontrolovať dosadením čísla spektra 256 do vyššie uvedeného vzorca s 512 vzorkami a sínus bude vždy rovný 0), skutočná časť sa môže dosť výrazne zmeniť v dôsledku skutočnosti, že hodnota kosínusu bude vypočítaná každý druhýkrát v protifáze k hlavnému signálu . To znamená, že sa to vypočíta raz. Aby ste tomu zabránili, je potrebné vypočítať aspoň 2 hodnoty reálnej časti posunuté o 90 stupňov a vybrať maximum z týchto dvoch hodnôt.

Algoritmus programu akumuluje 512 vzoriek v intervale, prepne mikrokontrolér do režimu spánku a prebudí sa, keď je pripravená ďalšia vzorka. Okrem toho sú LED diódy snímané pri 150 Hz – to je 128-násobok vzorkovacej frekvencie 19200. To znamená, že predtým, než ADC zoberie všetky vzorky, stihne dokončiť jedno úplné zametanie. Akonáhle sú všetky vzorky pripravené, vypočítajú sa všetky amplitúdy spektra v hlavnom cykle programu. V tomto čase zametanie pokračuje, ale MK nezaspí, ale počíta amplitúdy. Hneď ako sa vypočítajú amplitúdy, mikrokontrolér prejde do režimu spánku a program sa znova zopakuje. Amplitúdy sú vypočítané na základe rozsahu 20 dB, to znamená, že sú logaritmické.

Na základe času na prijatie všetkých meraní a času na výpočet všetkých amplitúd je frekvencia aktualizácie v rozsahu 10-15 Hz.


Svet bezplatných programov a užitočných tipov
2024 whatsappss.ru