29.3 Exemplu de proiectare: filtru audio FIR

După ce experimentați programele preîncrise pentru o perioadă de timp, veți dori să le modificați pentru a obține experiență în programare. Programele pot fi scrise în asamblare sau C; EZ-KIT Lite oferă instrumente software pentru a suporta ambele limbaje. Mai târziu, în acest capitol vom examina metode avansate de programare, cum ar fi simularea, depanarea și lucrul într-un mediu integrat de dezvoltare. Pentru moment, ne vom concentra pe cea mai ușoară cale de a obține un program de rulat. Pași mici pentru picioare mici.

Figura 29-2 Exemplu de filtru FIR.

În (a), este arătat răspunsul în frecvență al unui filtru înalt personalizat. Răspunsul la impuls corespunzător (nucleul filtrului) este arătat în (b). Acest filtru a fost proiectat în cap. 17 pentru a arăta că, practic, orice răspuns în frecvență poate fi realizat cu filtre digitale FIR.

Deoarece codul sursă este în ASCII, este necesar un editor de text standard pentru a face modificări fișierelor existente sau pentru a crea programe complet noi. Tabelul 29-2 prezintă un exemplu de program filtru FIR scris în asamblare. Deși acesta este singurul cod de care trebuie să vă faceți griji pentru moment, rețineți că există alte fișiere necesare pentru a face acest program complet. Acestea includ un "fișier de descriere a arhitecturii" (care definește configurația hardware și alocarea memoriei), configurarea tabelului vectorial de întrerupere și rutina de inițializare a codecului. În cele din urmă, va trebui să înțelegeți ce se întâmplă în aceste secțiuni, însă pentru moment le copiați pur și simplu din programele preîncrise.

După cum se arată în partea de sus a Tabelului 29-2, există trei variabile care trebuie definite înainte de a sări la secțiunea principală a codului. Acestea sunt numărul de puncte din kernelul filtru, NR_COEF; un buffer circular care păstrează probele anterioare din semnalul de intrare, dline[ ]; și un tampon circular care păstrează nucleul de filtrare, coef[ ]. De asemenea, trebuie să oferim programului două alte informații: rata de eșantionare a codecului și numele fișierului care conține nucleul de filtrare, astfel încât acesta să poată fi citit în coef[ ]. Toți acești pași sunt ușor; nimic mai mult decât o singură linie de cod fiecare. Nu le arătăm în acest exemplu deoarece sunt cuprinse în secțiunile de cod pe care le ignorăm pentru simplitate.

Figura 29-2 arată kernelul de filtrare cu care vom testa programul, același filtru personalizat pe care l-am proiectat în capitolul 17. După cum vă amintiți, acest filtru a fost ales să aibă un răspuns în frecvență foarte dezordonat, consolidând ideea că filtrele digitale FIR pot oferi practic orice răspuns în frecvență dorit. Figura (a) arată răspunsul în frecvență al filtrului nostru de test, în timp ce (b) arată răspunsul la impuls corespunzător (adică, kernelul filtrului). Acest kernel filtru de 301 puncte este stocat într-un fișier ASCII și este combinat cu alte secțiuni de cod în timpul conectării pentru a forma un singur program executabil.

Secțiunea principală a programului efectuează două funcții. În liniile 6 până la 13, generatoarele de adrese-date (DAG-uri) sunt configurate pentru a gestiona bufferele circulare: dline[ ] și coef[ ]. După cum este descris în ultimul capitol, sunt necesari trei parametri pentru fiecare buffer: locația de pornire a bufferului în memorie (b0 și b8), lungimea bufferului (l0 și l8) și mărimea pasului de date stocate în bufferul (m0 și m8). Acești parametri care controlează bufferele circulare sunt stocate în registrele hardware din DAG-uri, permițându-le să acceseze și să administreze datele foarte eficient.

A doua acțiune a programului principal este o buclă "thumb-twiddling", implementată în liniile 15-19. Aceasta nu face decât să aștepte o întrerupere care să indice că a fost achiziționat un eșantion de intrare. Toată prelucrare în acest program are loc pe baza unui eșantion-cu-eșantion. De fiecare dată când un eșantion este citit de la intrare, un eșantion din semnalul de ieșire este calculat și direcționat către codec. Majoritatea algoritmilor din domeniul timp, cum ar fi filtrele FIR și IIR, intră în această categorie. Alternativa este procesarea cadru-cu-cadru, care este necesară pentru tehnicile din domeniu frecvență. În metoda cadru-cu-cadru, un grup de eșantioane este citit de la intrare, sunt efectuate calcule și un grup de eșantioane este scris la ieșire.

Subrutina care asigură întreruperea eșantion-pregătit este împărțită în trei secțiuni. Prima secțiune (linii 27-33) preia eșantionul din codec ca număr în virgulă fixă și îl convertește în virgulă mobilă. În limbajul de asamblare SHARC, un registru de date care deține un număr în virgulă fixă este referit prin "r" (cum ar fi r0, r8, r15 etc.) și cu "f" dacă deține un număr în virgulă mobilă (adică f0, f8 sau f15). De exemplu, în linia 32, numărul în virgulă fixă din registrul de date 0 (adică, r0) este convertit într-un număr în virgulă mobilă și suprascrie registrul de date 0 (adică, f0). Această conversie se realizează conform unei scalări specificată de numărul în virgulă fixă în registrul de date 1 (adică r1). În a treia secțiune (liniile 47-53), au loc pașii opuși; numărul în virgulă mobilă pentru eșantionul de ieșire este convertit în virgulă fixă si trimis la codec.

Filtrul FIR care convertește eșantioanele de intrare în eșantioane de ieșire este conținut în liniile 35-45. Toate calculele se efectuează în virgulă mobilă, evitând necesitatea de a vă îngrijora de scalare și de depășire. După cum este descris în ultimul capitol, această secțiune de cod este optimizată pentru a profita de capacitatea SHARC DSP de a executa mai multe instrucțiuni pe fiecare ciclu de tact.

După ce am scris programul de asamblare și proiectat kernelul de filtrare, suntem gata să creăm un program care poate fi executat pe SHARC DSP. Acest lucru se face executând compilatorul, asamblatorul și apoi linkerul; trei programe furnizate cu EZ-KIT Lite. Compilatorul convertește un program C în limbajul de asamblare al SHARC-ului. Dacă scrieți direct programul în asamblare, cum ar fi în acest exemplu, săriți acest pas. Asamblatorul și linker-ul convertesc programul și fișierele externe (cum ar fi fișierul de arhitectură, rutinele de inițializare a codecului, kernelul de filtrare etc.) în fișierul executabil final. Toate acestea durează aproximativ 30 de secunde, rezultatul final fiind un program SHARC care se află pe harddiscul PC-ului. EZ-KIT Lite Host este apoi utilizată pentru a rula programul pe EZ-KIT Lite. Pur și simplu faceți clic pe pe fișierul pe care doriți să-l execute DSP, iar gazda EZ-KIT Lite se ocupă de restul, descărcând programul și pornind-l.

Tabelul 29-2 Program în Asamblare pentru filtru FIR.

Acest lucru ne aduce la două întrebări. În primul rând, cum să testați filtrul nostru audio pentru a vă asigura că funcționează așa cum l-am proiectat? și în al doilea rând, ce este în lume o companie numită Analog Devices ce face procesoare digitale de semnal?

Secțiunea următoare: Măsurători analogice pe un sistem DSP