- Łatwy montaż i uruchomienie.
- Nie wymaga strojenia.
- Wykorzystuje moduł z układem radiowym RDA5807.
- Wyjście stereofoniczne – dwa kanały o mocy 2 W każdy.
- Możliwość współpracy ze słuchawkami lub zestawem głośników.
- Odbiór stacji radiowych w zakresie 87,5…108 MHz.
- Odbiór i wyświetlanie informacji RDS.
- Pamięć 8 stacji radiowych.
- Zasilanie: 7…15 V DC/0,3 A.
- Niewielkie wymiary: 140 mm×38 mm×45 mm.
Rolę tunera radiowego pełni moduł z układem RDA5807. Jego płytka, pokazana na fotografii 1, ma wymiary 11 mm×11 mm×2 mm. Zawiera układ scalony radioodbiornika, rezonator kwarcowy oraz kilka komponentów biernych. Moduł jest bardzo łatwy w montażu, a jego cena pozytywnie zaskakuje.
Na rysunku 2 pokazano rozmieszczenie wyprowadzeń modułu. Oprócz doprowadzenia zasilania o napięciu ok. 3 V wymaga jeszcze tylko sygnału zegarowego i doprowadzenia anteny.
Na wyjściu jest dostępny stereofoniczny sygnał audio, a odczyt informacji RDS, statusu i oraz konfigurowanie układu odbywa się za pomocą interfejsu szeregowego.
Budowa
Schemat ideowy radioodbiornika pokazano na rysunku 3. Jego budowę można podzielić na kilka bloków: zasilania (IC1, IC2), radiowy (IC6, IC7), wzmacniacza mocy audio (IC3) oraz blok sterowania i interfejsu użytkownika (IC4, IC5, SW1, SW2).
Blok zasilania dostarcza dwóch napięć stabilizowanych: +5 V do zasilania wzmacniacza mocy audio i wyświetlacza oraz +3,3 V dla modułu radiowego i mikrokontrolera sterującego. Układ RDA5807 ma wbudowany wzmacniacz audio o małej mocy, który umożliwia bezpośrednie wysterowanie np. słuchawek. Aby nie obciążać wyjścia tak delikatnego układu oraz dla uzyskania większej mocy, w prezentowanym urządzeniu zastosowano dodatkowy wzmacniacz mocy audio. Jest to typowa aplikacja układu TDA2822, która pozwala na osiągnięcie mocy wyjściowej rzędu kilku watów. Wyjście sygnału jest dostępne na trzech złączach: CON4 (popularne gniazdo minijack pozwalające na dołączenie np. słuchawek), CON2 i CON3 (pozwalają na dołączenie do radioodbiornika głośniki). Dołączenie słuchawek odłącza sygnał od głośników.
Montaż
Schemat montażowy radioodbiornika pokazano na rysunku 4.
Montaż wykonujemy zgodnie z ogólnymi zasadami. Płytka drukowana ma miejsce do zamontowania gotowego modułu radiowego, ale także umożliwia montaż pojedynczych elementów składających się na moduł, czyli: układu RDA, rezonatora kwarcowego i dwóch kondensatorów. Dlatego na schemacie i płytce znajdują się elementy IC6 oraz IC7 – budując radioodbiornik należy wybrać jedną z opcji, wygodniejszą i dopasowaną do posiadanych komponentów. Wyświetlacz oraz impulsatory należy zamontować od strony lutowania. Pomocna przy montażu będzie fotografia 5 przedstawiająca zmontowaną płytkę radioodbiornika.
Po zmontowaniu radioodbiornik wymaga jedynie ustawienia kontrastu wyświetlacza za pomocą potencjometru R1. Po tej czynności jest gotowy do pracy.
Obsługa
Na wyświetlaczu są pokazywane podstawowe informacje. Słupek wyświetlany po lewej stronie ilustruje poziom mocy odbieranego sygnału radiowego. W centralnej części wyświetlacza znajduje się informacja o aktualnie ustawionej częstotliwości radiowej, a po prawej stronie – również w postaci słupka – jest pokazywany poziom sygnału audio (rysunek 6).
Po kilku sekundach bezczynności, jeśli jest możliwy odbiór danych RDS, wskazanie odbieranej częstotliwości zostaje „zasłonięte” podstawową informacją RDS, a w dolnej linii wyświetlacza jest pokazywana rozszerzona informacja RDS. Podstawowa informacja zawiera tylko 8 znaków. Zwykle zobaczymy tam nazwę stacji na zmianę z nazwą aktualnego programu lub wykonawcy. Informacja rozszerzona może zawierać do 64 znaków. Jej tekst jest przewijany w dolnej linii wyświetlacza, aby pokazać cały komunikat.
Do obsługi radioodbiornika służą dwa impulsatory. Ten po lewej stronie służy do ustawiania odbieranej częstotliwości, natomiast ten po prawej stronie pozwala na regulowanie głośności. Ponadto, przyciśnięcie lewego impulsatora pozwala na zapamiętanie aktualnej częstotliwości w jednej z 8 przeznaczonych do tego lokacji pamięci. Po wybraniu numeru programu należy potwierdzić działanie ponownie przyciskając impulsator (rysunek 7).
Dodatkowo, urządzenie zapamiętuje ostatnio zapisany program oraz ustawioną głośność i każdorazowo po włączeniu zasilania uruchamia ten program z taką głośnością. Przyciskanie prawego impulsatora powoduje przełączenie odbioru na następny zapisany program.
Działanie
Układ RDA5807 komunikuje się z mikrokontrolerem poprzez interfejs szeregowy I2C. Jego praca jest kontrolowana za pomocą 16 rejestrów 16-bitowych, ale nie wszystkie bity i rejestry są wykorzystywane.
Rejestry o adresach od 0x02 do 0x07 służą przede wszystkim jako rejestry do zapisu. Przy rozpoczęciu transmisji I2C z funkcją zapisu, automatycznie pierwszym zapisywanym rejestrem jest ten o adresie 0x02. Rejestry o adresach 0x0A do 0x0F zawierają informacje tylko do odczytu. Rozpoczęcie transmisji I2C z zamiarem odczytania statusu lub zawartości rejestrów RDS, automatycznie rozpoczyna odczyt od rejestru o adresie 0x0A.
Adres I2C układu RDA to według dokumentacji 0x20 (0x21 dla funkcji odczytu), jednak w przykładach programów dla tego modułu znaleziono funkcje zawierające adres 0x22. Okazało się, że przy użyciu tego adresu można zapisać jeden konkretny rejestr układu, a nie całą grupę, zaczynając od rejestru o adresie 0x02. Informacji tej zabrakło w dokumentacji.
//identyfikacja układu
#define RADIO_REG_CHIPID 0x00
#define RADIO_CHIP_ID 0x0058
#define RADIO_REG_CTRL 0x02
//adresy rejestrów kontrolnych funkcji
#define RADIO_REG_CTRL_OUTPUT 0x8000
#define RADIO_REG_CTRL_UNMUTE 0x4000
#define RADIO_REG_CTRL_MONO 0x2000
#define RADIO_REG_CTRL_BASS 0x1000
#define RADIO_REG_CTRL_SEEKUP 0x0200
#define RADIO_REG_CTRL_SEEK 0x0100
#define RADIO_REG_CTRL_RDS 0x0008
#define RADIO_REG_CTRL_NEW 0x0004
#define RADIO_REG_CTRL_RESET 0x0002
#define RADIO_REG_CTRL_ENABLE 0x0001
//adresy rejestrów sterujących zakresem
#define RADIO_REG_CHAN 0x03
#define RADIO_REG_CHAN_SPACE 0x0003
#define RADIO_REG_CHAN_SPACE_100 0x0000
#define RADIO_REG_CHAN_BAND 0x000C
#define RADIO_REG_CHAN_BAND_FM 0x0000
#define RADIO_REG_CHAN_BAND_FMWORLD 0x0008
#define RADIO_REG_CHAN_TUNE 0x0010
#define RADIO_REG_CHAN_TEST 0x0020
#define RADIO_REG_CHAN_NR 0x7FC0
//adresy rejestrów sterujących funkcjami specjalnymi
#define RADIO_REG_R4 0x04
#define RADIO_REG_R4_EM50 0x0800
#define RADIO_REG_R4_RES 0x0400
#define RADIO_REG_R4_SOFTMUTE 0x0200
#define RADIO_REG_R4_AFC 0x0100
//rejestry sterujące głośnością
#define RADIO_REG_VOL 0x05
#define RADIO_REG_VOL_DEFAULT 0x8880
#define RADIO_REG_VOL_VOL 0x000F
//rejestry funkcji RDS i dekodera stereofonicznego
#define RADIO_REG_RA 0x0A
#define RADIO_REG_RA_RDS 0x8000
#define RADIO_REG_RA_RDSBLOCK 0x0800
#define RADIO_REG_RA_STEREO 0x0400
#define RADIO_REG_RA_NR 0x03FF
//rejestr statusu oraz maski bitów statusu
#define RADIO_REG_RB 0x0B
#define RADIO_REG_RB_FMTRUE 0x0100
#define RADIO_REG_RB_FMREADY 0x0080
//rejestry RDS
#define RADIO_REG_RDSA 0x0C
#define RADIO_REG_RDSB 0x0D
#define RADIO_REG_RDSC 0x0E
#define RADIO_REG_RDSD 0x0F
Na kolejnych listingach pokazano ważniejsze fragmenty programu napisanego w języku C++. Listing 1 zawiera definicje istotnych rejestrów i bitów, ich dokładniejszy opis dostępny jest w dokumentacji układu.
radio.buff[RADIO_REG_CHIPID] = RADIO_CHIP_ID;
radio.buff[1] = 0x0000; //nieużywane
radio.buff[RADIO_REG_CTRL] = (RADIO_REG_CTRL_ENABLE | RADIO_REG_CTRL_OUTPUT |
RADIO_REG_CTRL_BASS | RADIO_REG_CTRL_RDS | RADIO_REG_CTRL_NEW);
radio.buff[RADIO_REG_CHAN] = (RADIO_REG_CHAN_BAND_FM | RADIO_REG_CHAN_SPACE_100);
radio.buff[RADIO_REG_R4] = (RADIO_REG_R4_EM50 | RADIO_REG_R4_SOFTMUTE);
radio.buff[RADIO_REG_VOL] = RADIO_REG_VOL_DEFAULT;
radio.buff[6] = 0x0000; //nieużywane
radio.buff[7] = 0x0000; //nieużywane
radio.buff[8] = 0x0000; //nieużywane
radio.buff[9] = 0x0000; //nieużywane
radio.mute = 1;
if (result == RADIO_STATUS_OK)
{
RadioWriteReg(RADIO_REG_CTRL, (RADIO_REG_CTRL_RESET | RADIO_REG_CTRL_ENABLE));
_delay_ms(10);
RadioWriteReg(RADIO_REG_CTRL, (RADIO_REG_CTRL_ENABLE));
_delay_ms(100);
radio.buff[RADIO_REG_CTRL] = (RADIO_REG_CTRL_ENABLE | RADIO_REG_CTRL_OUTPUT |
RADIO_REG_CTRL_BASS | RADIO_REG_CTRL_RDS | RADIO_REG_CTRL_NEW);
RadioWrite(); //przesłanie do układu
}
Na listingu 2 zamieszczono procedurę inicjującą układ scalony odbiornika radiowego RDA. Na listingu 3 przedstawiono procedurę ustawiającą układ radiowy na odbiór danej częstotliwości. Procedura wykorzystuje funkcje zapisu pojedynczego rejestru.
uint16_t RadioFreqSet(uint16_t freq) {
uint16_t reg_val;
if (freq > RADIO_FREQ_MAX) freq = RADIO_FREQ_MAX;
if (freq < RADIO_FREQ_MIN) freq = RADIO_FREQ_MIN;
freq -= RADIO_FREQ_MIN;
reg_val = (RADIO_REG_CHAN_BAND_FM | RADIO_REG_CHAN_SPACE_100 | RADIO_REG_CHAN_TUNE);
reg_val += (freq << 6);
RadioWriteReg(RADIO_REG_CHAN, reg_val);
return radio.buff[RADIO_REG_CHAN];
}
Odbiór danych RDS wymaga ciągłego odczytywania rejestrów układu RDA zawierających adekwatną informację. Program zawarty w pamięci mikrokontrolera wykonuje tę czynność co około 0,2 sekundy. Służy do tego funkcja RadioRead(). Struktury danych RDS były już opisywane na łamach EP np. przy okazji projektu AVT5401 (EP 6/2013), więc zachęcam osoby zainteresowane poszerzeniem swojej wiedzy do lektury wspomnianego artykułu, dostępnego za darmo w archiwum Elektroniki Praktycznej (http://ep.com.pl/archiwum.html). Na koniec tego opisu, warto poświęcić kilka zdań rozwiązaniom zastosowanym w prezentowanym radioodbiorniku.
Odebrane z modułu dane RDS są podzielone na 4 rejestry RDSA…RDSD (umieszczone w rejestrach o adresach od 0x0C do 0x0F). W rejestrze RDSB znajduje się informacja o grupie danych. Istotne grupy to 0x0A zawierająca podstawowy tekst RDS (8 znaków) oraz 0x2A zawierająca tekst rozszerzony (64 znaki). Oczywiście, tekst nie jest zawarty w jednej grupie tylko w wielu kolejnych grupach o tym samym numerze. Każda z nich zawiera informacje o pozycji danej części tekstu dzięki temu możliwe jest skompletowanie całego komunikatu.
Dużym problemem okazało się filtrowanie danych, aby skompletować prawidłowy komunikat bez „krzaczków”. W urządzeniu zastosowano rozwiązanie z podwójnym buforem komunikatów RDS. Odebrany fragment komunikatu jest porównywany z jego poprzednią wersją umieszczoną w pierwszym buforze – roboczym, na tej samej pozycji. Gdy wynik porównania wypadnie pozytywnie, to komunikat zostaje zapamiętany w drugim buforze – wynikowym. Metoda wymaga dużo pamięci, ale jest bardzo skuteczna.
KS
- R1: 20 kΩ (pot. nastawny)
- R2, R9, R10: 43 Ω
- R3, R4, R7, R8: 2,2 kΩ
- R5,R6: 100 kΩ
- C1, C3, C7: 220 μF/16 V (elektrolit.)
- C10…C13: 200 μF/16 V (elektrolit.)
- C2, C4, C5, C6, C8, C9, C14, C15: 100 nF
- D1: 1N4007
- SW1, SW2: impulsator z przyciskiem w osi
- IC1: 7805
- IC2: LM1117-3.3
- IC3: TDA2822
- IC4: ATmega168
- IC5: wyświetlacz LCD 2×16
- IC6: moduł z układem RDA5807
- CON1: GN DC 2.1/5.5 do druku
- CON2, CON3: DG381-3.5/2
- CON4: gniazdo minijack do druku