Regulator barwy dźwięku na bazie płytki ewaluacyjnej LPCxpresso55S28

Regulator barwy dźwięku na bazie płytki ewaluacyjnej LPCxpresso55S28

W artykule zaprezentuję ciekawe zastosowanie popularnego modułu wykonanego na bazie mikrokontrolera firmy NXP z rodziny LPC55Sxx - korektor barwy tonu. Zastosowana płytka ewaluacyjna - LPCxpresso55S28 - jest gotowym do pracy zestawem ze zintegrowanym programatorem i debuggerem oraz pełnym torem audio na bazie kodeka WM8904 firmy Cirrus Electronic. Sam mikrokontroler LPC55S28 jest wyposażony w interfejsy I²C oraz I²S przeznaczone do komunikacji z kodekiem oraz do przesyłania cyfrowego strumienia audio. Do artykułu dołączony jest pełny projekt programu.

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.

Rysunek 1. Schemat blokowy kodeka WM8904
Rysunek 2. Realizacja transmisji pomiędzy MPU a kodekiem

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.

Rysunek 3. Struktura filtra pasmowego realizowanego w programie

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.

Listing 1. Fragment kodu odpowiedzialny za przetwarzanie sygnału akustycznego

#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.

Rysunek 4. Sposób tworzenia sygnału wyjściowego

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:

  1. Check box - obiekt służy do wyboru dwóch stanów;
  2. Radio Button - ta kontrolka umożliwia wybór jednej z wielu opcji;
  3. Text - wyświetla tekst w ramce na ekranie i może być traktowana jako przycisk;
  4. Label - tylko wyświetla tekst;
  5. Bar - wyświetla słupek o zmieniającej się wysokości. Kontrolka ta używana jest do ustawiania wartości;
  6. Edit - ten obiekt umożliwia edycję napisu;
  7. 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.

Rysunek 5. Hierarchia klas interfejsu GUI

Na rysunku 5 pokazano hierarchię klas, natomiast na rysunku 6 widzimy strukturę interfejsu GUI naszego programu.

Rysunek 6. Schemat poglądowy struktury naszego interfejsu

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.

Rysunek 7. Koncepcja działania interfejsu graficznego obsługującego wyświetlacz LCD

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).

Rysunek 8. Schemat podłączenia wyświetlacza oraz sposób konfiguracji

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.

Rysunek 9. Schemat połączeń części elektrycznej

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

Artykuł ukazał się w
Elektronika Praktyczna
listopad 2023

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik maj 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio maj - czerwiec 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje maj 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna maj 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich czerwiec 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów