Działanie urządzenia polega na przetworzeniu sygnału analogowego na cyfrowy poprzez przetwornik A/D zawarty w kodeku WM8904, a następnie rozdzieleniu go w zespole pasmowych filtrów cyfrowych o różnych częstotliwościach. W każdym kanale częstotliwościowym można dokonać regulacji amplitudy sygnału. Następnie wartości ze wszystkich kanałów są sumowane i podawane na przetwornik D/A kodeka.
Opis programu komputerowego
Cały program składa się z dwóch części - procedur przetwarzania sygnału, w skład których wchodzi również komunikacja z kodekiem oraz z interfejsu użytkownika, który jest odpowiedzialny za ustawianie parametrów urządzenia i obsługuje przyciski sprzętowe, enkoder oraz steruje wyświetlaczem graficznym.
Sterowanie kodekiem
Sterowanie kodekiem WM8904 odbywa się poprzez dwa interfejsy: I²C oraz I²S. Magistrala I²C służy do konfiguracji układu. Proces ten polega na programowaniu wewnętrznych rejestrów procesora dźwięku. Można w ten sposób zaprogramować m.in.:
- wzmocnienie wewnętrznego wzmacniacza PGA,
- źródła sygnału wejściowego i wyjściowego,
- częstotliwość próbkowania, itp.
Interfejs I²S służy do przesyłania próbek dźwiękowych. W naszym programie zastosujemy gotową bibliotekę dźwiękową służącą do konfiguracji kodeka. Obsługa transmisji danych odbywa się poprzez dwa interfejsy I²S. Zastosowany mikrokontroler dostarcza system dziewięciu uniwersalnych bloków komunikacji szeregowej nazwanych FLEXCOM, każdy z nich można skonfigurować jako jeden z następujących interfejsów do transmisji danych:
- UART/USART
- SPI,
- I²C,
- I²S.
W naszym układzie użyjemy bloków FLEXCOM6 i FLEXCOM7, ponieważ są one elektrycznie podłączone do kodeka WM8904. Interfejs I²S zaimplementowany w module FLEXCOM6 jest używany jako wejście sygnału akustycznego, natomiast transmisja realizowana przez FLEXCOM7 wysyła dane do przetwornika DAC, czyli pełni funkcję wyjścia. Ponieważ sygnały sterujące transmisją (BCK i WS) są takie same dla obydwu interfejsów, należy dokonać ich połączenia. Służy do tego moduł SYSCTL.
Ponadto program ma funkcję regulacji sygnału wyjściowego oraz ustawienia typu wejścia: wejście mikrofonowe lub wejście liniowe. Rodzaj wejścia odbywa się poprzez zmianę wzmocnienia wewnętrznego wzmacniacza PGA (Programable Gain Amplifier). Obydwa te parametry można zmieniać poprzez ustawianie wartości w rejestrach kodeka.
Do działania układu WM8904 niezbędne jest dostarczenie sygnału taktującego na wejście MCLK. Sygnał ten wytwarzany jest przez mikrokontroler i wyprowadzony na odpowiednio skonfigurowane wyjście MCLK. Częstotliwość sygnału wynosi 24576000 Hz. Jest to zalecana wartość częstotliwości, która umożliwia wytworzenie wymaganych przebiegów sterującym przy pracy dla standardowych prędkości próbkowania. Na rysunku 1 pokazano strukturę wewnętrzną kodeka, natomiast rysunek 2 obrazuje transmisję pomiędzy kodekiem a mikrokontrolerem.
Opis algorytmu DSP
Cyfrowy strumień danych audio jest poddawany cyfrowej filtracji. Jako filtry zastosowałem cyfrowe imitacje szeregowych obwodów rezonansowych. Do ich zaprojektowania zastosowałem następujące zależności:
gdzie:
- UR - napięcie na rezystorze,
- UC - napięcie na kondensatorze,
- UL - napięcie na cewce.
Wartości L i C można wyliczyć na podstawie częstotliwości rezonansowej oraz wymaganej dobroci filtru, natomiast wartość rezystancji najwygodniej przyjąć równą jeden. Struktura tego filtru zamieszczona jest na rysunku 3.
Fragment kodu odpowiedzialny za przetwarzanie sygnału akustycznego został pokazany na listingu 1. Aby użyć maksymalnej częstotliwości procesora procedura DSP, została umieszczona w pamięci operacyjnej.
#define Filtr(f,q,x,y){\
static float uc = 0;\
static float IL = 0;\
uc += IL * (float)\
((float)2\
* STALA_PI / FP\
* (float)(q)\
* (float)(f));\
IL += (x - uc - IL)\
* (float)((float)2\
* STALA_PI / FP\
* (float)(f) / (float)(q));\
y = IL;}
void __attribute__((section("RamFunction")))\
PrzetwarzanieGlowne() {
volatile register float kl = 0,kp = 0,wy,wl,wp;
wl = (float)WartoscWE_L/(float)0x7FFF;
wp = (float)WartoscWE_P/(float)0x7FFF;
Filtr(21.5,1,wl,wy);
kl+=wy*Poz.A20L;
Filtr(21,1,wp,wy);
kp+=wy*Poz.A20P;
Filtr(46.4,1,wl,wy);
kl+=wy*Poz.A50L;
Filtr(46.4,1,wp,wy);
kp+=wy*Poz.A50P;
Filtr(100,1,wl,wy);
kl+=wy*Poz.A100L;
Filtr(100,1,wp,wy);
kp+=wy*Poz.A100P;
Filtr(215,1,wl,wy);
kl+=wy*Poz.A200L;
Filtr(215,1,wp,wy);
kp+=wy*Poz.A200P;
Filtr(464,1,wl,wy);
kl+=wy*Poz.A50L;
Filtr(464,1,wp,wy);
kp+=wy*Poz.A500P;
Filtr(1000,1,wl,wy);
kl+=wy*Poz.A1KL;
Filtr(1000,1,wp,wy);
kp+=wy*Poz.A1KP;
Filtr(2150,1,wl,wy);
kl+=wy*Poz.A2KL;
Filtr(2150,1,wp,wy);
kp+=wy*Poz.A2KP;
Filtr(4640,1,wl,wy);
kl+=wy*Poz.A5KL;
Filtr(4640,1,wp,wy);
kp+=wy*Poz.A5KP;
Filtr(10000,1.5,wl,wy);
kl+=wy*Poz.A10KL;
Filtr(10000,1.5,wp,wy);
kp+=wy*Poz.A10KP;
WartoscWY_L = (int16_t)(kl*(float)0x7FFF);
WartoscWY_P = (int16_t)(kp*(float)0x7FFF);
}
Na koniec wartości ze wszystkich filtrów są sumowane i podawane na przetwornik D/A kodeka, tak jak to pokazano na rysunku 4.
Interfejs GUI
Do opracowania interfejsu użytkownika zastosowano zaprojektowaną przez autora bibliotekę, która współpracuje z wyświetlaczem graficznym LCD o rozdzielczości 128×64 pikseli. Umożliwia ona utworzenie na ekranie 7 kontrolek:
- Check box - obiekt służy do wyboru dwóch stanów;
- Radio Button - ta kontrolka umożliwia wybór jednej z wielu opcji;
- Text - wyświetla tekst w ramce na ekranie i może być traktowana jako przycisk;
- Label - tylko wyświetla tekst;
- Bar - wyświetla słupek o zmieniającej się wysokości. Kontrolka ta używana jest do ustawiania wartości;
- Edit - ten obiekt umożliwia edycję napisu;
- Arrow - wyświetla strzałkę na ekranie.
Główną klasą do obsługi interfejsu użytkownika jest EGUI. Umożliwia ona wyświetlanie treści na ekranie oraz odczyt wartości z przycisków i enkodera. Również za pomocą jej funkcji składowych można do interfejsu dodawać okna kontrolne wywodzące się z klasy E KontrolkaBaza.
Na rysunku 5 pokazano hierarchię klas, natomiast na rysunku 6 widzimy strukturę interfejsu GUI naszego programu.
Interfejs GUI korzysta z jeszcze jednej biblioteki graficznej opracowanej przez autora, służącej do wyświetlania różnych kształtów na ekranie wyświetlacza. Koncepcję działania tej biblioteki obrazuje rysunek 7.
Opis układu elektrycznego
Układ zbudowany jest na bazie gotowego modułu z mikrokontrolerem firmy NXP, ale do jego działania potrzebnych jest kilka elementów dodatkowych - wyświetlacz graficzny o rozdzielczości 128×64 piksele oraz prosty układ sterowania. Można dołączyć dwa przyciski, chociaż nie jest to konieczne, jeśli zdecydujemy się na sterowanie urządzeniem za pomocą przycisków znajdujących się na płytce ewaluacyjnej.
Zastosowany w naszym układzie wyświetlacz graficzny może pracować w dwóch trybach. Może być sterowany za pomocą transmisji równoległej lub szeregowej, z zastosowaniem w transmisji SPI. W naszej aplikacji zastosujemy transmisję szeregową. Ponieważ wyświetlacz fabrycznie jest skonfigurowany do pracy przy transmisji równoległej, należy przełączyć zworę, która znajduje się na jego tylnej części (rysunek 8).
Dodatkowo, ponieważ układ logiczny wyświetlacza jest sterowany napięciami niezgodnymi z logiką standardu 3,3 V, czyli wartościami wyjściowymi mikrokontrolera (wysoki stan wejść wymaga napięcia wyższego niż 3,5 V), zastosowano bufor 74HCT541. Uproszczony schemat połączeń części elektrycznej pokazany jest na rysunku 9.
Elementy zastosowane w układzie
Do wizualizacji działania urządzenia zastosowano wyświetlacz monochromatyczny graficzny LCD o rozdzielczości 128×64 typu LCD-EG-128064H-FHW K/W-E6. Charakteryzuje się on niską ceną i jest dostępny w wielu sklepach internetowych m.in. Artronic czy Kamami. Jako bufor zastosowałem układ 74HCT541. Jest on szeroko dostępny, w niskiej cenie. Potencjometr do regulacji kontrastu może być dowolnym potencjometrem montażowym o rezystancji około 25 kΩ. Jako enkoder można zastosować dowolny 3-wyjściowy enkoder inkrementalny.
Tomasz Krogulski
krogul70@gmail.com