Rejestrator dźwięku z korektorem graficznym i analizatorem widma na bazie LPC55S28

Rejestrator dźwięku z korektorem graficznym i analizatorem widma na bazie LPC55S28

Rodzina procesorów LPC55 bardzo dobrze nadaje się do zastosowań audio. Układy te zawierają – oprócz wewnętrznego 16-bitowego przetwornika ADC, oferującego wiele udogodnień poprawiających jakość konwersji – także sprzętowe interfejsy umożliwiające podłączenie urządzeń dźwiękowych. Również rdzeń układów z tej serii jest przeznaczony do przetwarzania sygnałów: mimo niskiego szczebla zaawansowania (ARM Cortex-M33), zapewnia on bowiem sprzętowe wsparcie arytmetyki zmiennoprzecinkowej. Nawet płytka ewaluacyjna, demonstrująca działanie opisywanego mikrokontrolera, przeznaczona jest głównie do zastosowań audio: zawiera kodek połączony z procesorem za pomocą interfejsu I²S oraz gniazda (wejściowe i wyjściowe) typu mini Jack. Ponadto na płytce znalazł się slot kart SD.

Ogólny opis układu

Chociaż do działania samego rejestratora wystarczyłby sam moduł ewaluacyjny, to w ramach projektu został on rozbudowany o kartę SD (zewnętrzna pamięć znacznie powiększa pojemność rejestratora – czyli długość zapisywanych dźwięków) oraz kolorowy wyświetlacz. To drugie rozwiązanie uprościło obsługę urządzenia, co więcej: aby konstrukcja prezentowała się atrakcyjniej, projekt wzbogacono o wizualizację widma sygnału oraz korektor graficzny. W roli ekranu zastosowano wyświetlacz kolorowy 4” ze sterownikiem ILI9488, dostępny na rynku od niedawna. Jest on wyposażony w szeregowy interfejs SPI (co bardzo ułatwia konstrukcję), a do jego zalet należy również bardzo niska cena i łatwa dostępność na popularnych portalach handlowych. Do sterowania programem zastosowano enkoder 24-pozycyjny oraz dwa przełączniki monostabilne. Elementy te wpięto do złączy, na które wyprowadzone zostały sygnały procesora. Sposób podłączenia elementów zewnętrznych do płytki rozwojowej pokazany został na rysunkach 1 i 2.

Rysunek 1. Podłączenie enkodera (a) i przełączników (b) do płytki ewaluacyjnej
Rysunek 2. Podłączenie wyświetlacza do płytki ewaluacyjnej

Algorytm programu

Ogólny algorytm działania programu pokazuje rysunek 3. Jak widać, składa się on z części przetwarzania sygnału akustycznego (która odpowiada za odczyt dźwięku z kodeka, korekcję częstotliwościową dźwięku za pomocą equalizera, zapis na karcie SD oraz wyznaczanie amplitud używanych przez procedurę wizualizacji widma sygnału) oraz bloku obsługującego interfejs graficzny, tworzący na wyświetlaczu obiekty przeznaczone do regulacji parametrów programu, a także wyświetlania użytecznych danych. Interfejs jest sterowany za pomocą enkodera z przyciskiem oraz dwóch mikroprzełączników.

Rysunek 3. Ogólna koncepcja programu

Schemat blokowy korektora graficznego i układu analizatora widma pokazany został na rysunku 4.

Rysunek 4. Pomiar amplitudy sygnału akustycznego

Rejestracja sygnału polega na zapisywaniu danych na kartę SD, co odbywa się za pomocą interfejsu sprzętowego realizującego transmisję. Jak widać na schemacie, z filtrów cyfrowych korzystają zarówno algorytm korektora graficznego, jak i procedura pomiaru wartości sygnału w poszczególnych pasmach częstotliwości. W celu poprawy działania filtru, jego kod wykonywany jest 4 razy w czasie jednego cyklu taktowania. Tak więc rzeczywista częstotliwość pracy filtrów wynosi: 4×fP. Cała procedura przetwarzania sygnału została umieszczona w pamięci RAM, a z myślą o dalszym zwiększeniu prędkości jej wykonywania wyeliminowano stosowanie wywołań funkcji, zamiast których wprowadzone zostały makra. Na listingu 1 zaprezentowano fragmenty programu zawierające kod filtru pasmowego oraz detektora amplitudy.

#define PomiarAmplitudy(n,x)\
static float n##BA = 0;\
static float n##C1 = 0;\
n##C1 += (((x<0) ? -x :x)-n##C1)*T_PA;\
n##BA += (n##C1-n##BA)*T_PA;

#define Filtr(f,q,x)\
static float uc##f = 0;\
static float IL##f = 0;\
uc##f += IL##f * (float)((float)2 * STALA_PI / FP/(float)4) * (float)q * (float)f;\
IL##f += (x – uc##f – IL##f) * (float)((float)2 * STALA_PI / FP/(float)4) * (float)f / (float)q;\
uc##f += IL##f * (float)((float)2 * STALA_PI / FP/(float)4) * (float)q * (float)f;\
IL##f += (x – uc##f – IL##f) * (float)((float)2 * STALA_PI / FP/(float)4) * (float)f / (float)q;\
uc##f += IL##f * (float)((float)2 * STALA_PI / FP/(float)4) * (float)q * (float)f;\
IL##f += (x – uc##f – IL##f) * (float)((float)2 * STALA_PI / FP/(float)4) * (float)f / (float)q;\
uc##f += IL##f * (float)((float)2 * STALA_PI / FP/(float)4) * (float)q * (float)f;\
IL##f += (x – uc##f – IL##f) * (float)((float)2 * STALA_PI / FP/(float)4) * (float)f / (float)q;\

Listing 1. Makra odpowiedzialne za pomiar amplitudy oraz filtrację danych

Zasada działania bloku pomiaru amplitudy pokazana jest na rysunku 5. Jeśli Czytelnik chciałby zmodyfikować program, należy zwrócić szczególną uwagę na to, aby do przechowywania wartości sygnału i wykonywania na nim operacji matematycznych stosować zmienne typu float (pojedynczej precyzji), a stałe zamieniać (metodą konwersji jawnej) także na typ float, gdyż tylko on jest obsługiwany sprzętowo. Operacje na zmiennych typu double są o wiele bardziej czasochłonne i mogą spowodować nieprawidłowe działanie programu.

Rysunek 5. Schemat blokowy equalizera oraz analizatora widma

Rejestrowane dane zapisywane są na karcie SD podzielonej na 22 fragmenty. Na każdym z nich można zapisać około pół godziny dźwięku. Reprezentacja danych jednej ścieżki dźwiękowej pokazana została na rysunku 6.

Rysunek 6. Reprezentacja danych pojedynczej ścieżki dźwiękowej w pamięci karty SD

Do wykonania części interfejsu graficznego użytkownika zastosowano bibliotekę napisaną przez autora. Składa się ona z 5 obiektów oraz 5 procedur graficznych, które są stosowane przez interfejs, ale można także korzystać z nich niezależnie od tego ostatniego.

Do budowy interfejsu graficznego służą następujące obiekty:

  • Słupek – umożliwia ustawianie wartości,
  • Wybór – wywołuje procedurę zdarzenia po wciśnięciu przycisku enkodera,
  • Opcja – pozwala ustawić wartość pojedynczej flagi,
  • Lista – umożliwia wybranie jednej pozycji z listy napisów,
  • Statyczna – wyświetla tekst lub bitmapę.

Do zmiany obiektu na ekranie służą dwa przyciski.

Aby umieścić obiekt interaktywny na wyświetlaczu, należy odpowiednio wypełnić jego strukturę oraz wywołać funkcję: „GUI_Add” i jako parametr podać wspomnianą strukturę konfiguracyjną. Wszystkie deklaracje obiektów używanych przez interfejs użytkownika znajdują się w pliku nagłówkowym GUI. Strukturę interfejsu graficznego pokazuje rysunek 7.

Rysunek 7. Budowa biblioteki interfejsu graficznego

Oto wszystkie zaimplementowane funkcje GUI:

  • void InicjujPG(),
  • void GUI_Init() – inicjalizuje Framework,
  • void GUI_Add(E_Kontrol*) – wstawia kontrolkę i wyświetla ją na ekranie,
  • void GUI_New() – usuwa wszystkie obiekty,
  • void GUI_Hide() – zaciemnia ekran,
  • void GUI_Show() – usuwa zaciemnienie ekranu,
  • void GUI_Zatwierdz(E_Kontrol*) – rysuje ponownie obiekt,
  • void GUI_UstawKontrol(int id) – ustawia aktywny obiekt,
  • E_Kontrol* GUI_Podaj(int id) – zwraca strukturę obiektu na podstawie jego numeru identyfikacyjnego.

Do obsługi zdarzeń służy funkcja, którą należy przypisać odpowiedniemu polu obiektu graficznego:

void (*Handle)(T_Z, E_Kontrol *c) = NULL;

gdzie T_Z: typ wyliczeniowy pokazany na listingu 2.

enum T_Z
{
Z_INICJUJ, //inicjacja objektu
Z_EN_L, //ruch enkodera w lewo
Z_EN_P, //ruch enkodera w prawo
Z_EN_SW, //naciśnięcie przycisku enkodera
Z_SW1, //naciśnięty przycisk 1
Z_SW2, //naciśnięty przycisk 1
Z_TIMER, //skończenie odliczania przez TIMER
//(wywoływana jest funkcja wskazywana przez *TH)
Z_TICK // wewnętrzny
};

Listing 2. Definicja typu wyliczeniowego T_Z

Obsługa urządzenia

Ustawianie parametrów urządzenia odbywa się poprzez zastosowanie zwykłych kontrolek biblioteki, natomiast wyświetlanie pasków wizualizacji widma realizowane jest za pomocą procedury rysowania kształtu prostokątnego. Z powodu dość wolnej transmisji nie robi się tego jednak w sposób bezpośredni – wielkość słupka wskazującego wartość sygnału jest powiększana lub zmniejszana w zależności od zmiany amplitudy.

Interfejs składa się z trzech ekranów. Pierwszy z nich służy do wyboru numeru pozycji, pod którą zostanie zapisany lub odczytany dźwięk – fotografia 1.

Fotografia 1. Ekran służący do wyboru pozycji zapisu i sterowania odczytem oraz rejestracją

Drugi (fotografia 2) zawiera elementy do regulacji parametrów equalizera.

Fotografia 2. Ekran equalizera

Na ostatnim wyświetlane jest widmo sygnału (wartości napięcia dla różnych pasm częstotliwości) – fotografia 3.

Fotografia 3. Wyświetlanie widma sygnału

Do przełączania ekranów służy obiekt typu „Wybór”, leżący w prawym górnym rogu ekranu.

Do użycia dostępne są 22 pozycje pamięci. Obszar karty SD podzielony jest właśnie na tyle równych fragmentów, z których każdy umożliwia zapisanie około 30 min dźwięku. Całkowita wielkość zastosowanej karty wynosi 8 GB. Schemat przesyłania danych pomiędzy kartą a mikrokontrolerem pokazano na rysunku 8.

Rysunek 8. Komunikacja pomiędzy programem a kartą pamięci

Zapisanie i modyfikacja programu

Moduł ewaluacyjny LP55S28EV wyposażony jest we wbudowany programator MCU-Link. Aby jednak uruchomić program na mikrokontrolerze, należy go najpierw wpisać do pamięci Flash. Potrzebne do tego jest oprogramowanie działające na komputerze PC – MCUXpresso IDE. Dzięki wspomnianemu środowisku możemy zaprogramować nasz moduł oraz dowolny procesor firmy NXP, jak również przeglądać i modyfikować kod naszego programu. Aby skompilować program, musimy zainstalować pakiet SDK odpowiedni dla płytki ewaluacyjnej z procesorem LPC55S28. Najwygodniejszym sposobem instalacji pakietów jest wejście na stronę startową środowiska IDE i wybranie odpowiedniej opcji. Najprościej ekran powitalny uruchomić za pomocą sekwencji menu: HELP/WELCOME, a następnie na ekranie, który się wyświetli, wybrać polecenie „Install SDK” – rysunek 9.

Rysunek 9. Wybór pakietu SDK dla naszego projektu

Aby przenieść nasz projekt do procesora płytki rozwojowej, trzeba wykonać kilka kroków.

  • Dodać projekt do przestrzeni roboczej (rysunek 10).
Rysunek 10. Dodawanie projektu do przestrzeni roboczej
  • Z głównego menu wybrać ‘File’/’Open Project from File System’.
Rysunek 11. Kompilacja i uruchomianie programu
  • Teraz możemy już zaprogramować płytkę lub uruchomić Debugger, wybierając odpowiednie pozycje z paska narzędzi. Jeśli chcemy dokonać zmian w kodzie, należy go powtórnie skompilować – patrz rysunek 11.

Tomasz Krogulski

Artykuł ukazał się w
Elektronika Praktyczna
grudzień 2024
Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik grudzień 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio styczeń - luty 2025

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje listopad - grudzień 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna grudzień 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich styczeń 2025

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów