Generator DDS na zakres 1 Hz…40 MHz z wobulatorem (2)

Generator DDS na zakres 1 Hz…40 MHz z wobulatorem (2)
Pobierz PDF Download icon

W poprzednim artykule opisano warstwę sprzętową generatora DDS oraz zasadę jego działania. W bieżącym podano uwagi odnośnie do sposobu jego montażu oraz uruchomienia. Omówiono również oprogramowanie sterujące.

Podstawowe parametry:
  • Zakres częstotliwości generowanego sygnału: 1 Hz…40 MHz (krok 1 Hz).
  • Zakres prędkości wobulacji: 5…40 Hz (krok 1 Hz).
  • Wyjście analogowe (sygnał sinusoidalny, regulowana amplituda) i cyfrowe (sygnał prostokątny, CMOS 0/5 V).
  • Wyjście sygnału przestrajającego wobulator, które można podać na wejście „X” oscyloskopu.
  • Standardowe wejścia/wyjścia o impedancji 50 Ω.
  • Złożony z dwóch płytek: sterującej (na panelu czołowym) i głównej.
  • Gniazda dla dwóch rodzajów popularnych modułów z AD9850.
  • Zasilanie 12…15 V DC/0,25 A.

Układ generatora należy zmontować na dwóch płytkach drukowanych, których schematy montażowe pokazano na rysunkach 11 i 12. Na płytce głównej znajduje się m.in. zasilacz generatora, na panelu jego sterowanie. Na fotografiach 13…15 pokazano szczegóły montażu obu płytek, a na fotografii tytułowej i na fotografii 16 organizację panelu przedniego i tylnego, dla których projekty zastosowanych maskownic opisów przedstawiono na rysunku 17.

Rysunek 11. Schemat montażowy płyty głównej
Rysunek 12. Schemat montażowy panelu sterującego

Montaż elementów rozpoczynamy od elementów najniższych (rezystory, dławiki i diody) i kolejno montujemy elementy coraz wyższe (podstawki pod układy scalone, kondensatory, potencjometry, tranzystory i wszelkie elementy łącznikowe). Rozsądne wydaje się zmontowanie i uruchomienie najpierw płytki głównej (poziomej) i przetestowanie poprawności pracy bloku zasilającego ze stabilizatorami liniowymi U1 i U2, dostarczającego napięcia +5 V i +9 V dla całego przyrządu. Stabilizatory U1 i U2 warto wyposażyć w niewielkie radiatory. Układ należy zasilić napięciem 11…14 V ze źródła o wydajności prądowej około 500 mA. Po sprawdzeniu poprawności zasilania należy skontrolować stałoprądowe punkty pracy wzmacniacza sygnału sinusoidalnego z tranzystorami Q1…Q3.

Fotografia 13. Gotowy generator – widok zamontowanego panelu sterującego od tyłu

Napięcia na wyprowadzeniach tych tranzystorów powinny być następujące:

  • Q1: Baza – 2,1 V, Kolektor – 6,65 V, Emiter – 1,4 V.
  • Q2: Emiter – 7,37 V, Kolektor – 2,5 V.
  • Q3: Kolektor – 5,47 V, Emiter – 1,74 V.

Pewną trudnością może okazać się przygotowanie wsuwek dla modułów DDS, które wykonujemy z przyciętych na odpowiednią długość odcinków żeńskich listew „goldpin”. Dla modułu U5 wystarczą listwy jednorzędowe, a dla modułu U6 jedną z wsuwek wykonujemy z listwy dwurzędowej lub sklejamy ją na wymiar z dwóch listew jednorzędowych. Jeśli jesteśmy zdecydowani na zastosowanie jednego, konkretnego typu modułu DDS (U5 albo U6), to nie ma potrzeby przygotowywania i montażu wsuwek pod oba typy modułów.

Fotografia 14. Widok zmontowanego generatora od przodu

Po zmontowaniu i wstępnym uruchomieniu (na razie bez zainstalowanego modułu DDS) głównej płytki urządzenia należy przystąpić do montażu płytki sterowania, montowanej do przedniego panelu urządzenia. 16-pinową złączkę-gniazdo dla ekranu LCD (U11) należy przyciąć z odpowiedniego odcinka żeńskiej listwy „goldpin”. Z kolei wyprowadzenia do montażu potencjometru regulacyjnego poziomu sygnału sinusoidalnego PR3 wykonujemy z pięciu segmentów odcinka męskiej listwy „goldpin”, po usunięciu zbędnych pinów (2 i 4). Warto zadbać także o solidne zamontowanie enkodera obrotowego z przyciskiem (SW1), który powinien mieć przylutowane nie tylko wyprowadzenia elektryczne, ale także dwa metalowe mocowania obudowy. Na fotografii 13 pokazano montaż potencjometru PR2 do regulacji kontrastu LCD. Zamontowano go na tylnej stronie PCB po to, by ułatwić dostęp. Na zdjęciu widać także zamontowane na roboczo (w fazie uruchomienia projektu) elementy R22, R23, C42 oraz C43, które zapewniają dodatkową filtrację drgań styków enkodera. W dostępnym w sprzedaży kicie AVT5580 te elementy są zamontowane na płytce drukowanej. Na uwagę zasługuje także montaż rezystora R21, ograniczającego prąd podświetlenia LCD. W modelowym wykonaniu miał on rezystancję 22 Ω, jednak należy dobrać wartość do posiadanego wyświetlacza. Dla ułatwienia doboru R21 w jego miejsce na płytce drukowanej wlutowano odcinek listwy „goldpin”.

Fotografia 15. Widok zmontowanego generatora od tyłu

Po zmontowaniu obu płytek należy przystąpić do wykonania połączeń. Najlepiej do tego celu nadają się odcinki kątowych męskich listew „goldpin”, za których pomocą łączymy ze sobą porty: P5 i P11, P6 i P10 oraz P7 i P9. Najpierw przycinamy kątowe łączówki na odpowiednią liczbę segmentów, a następnie przesuwamy elementy plastikowe, łączące metalowe kołki, do samego ich zagięcia, co pozwoli zamontować tak przygotowane listwy jak najbliżej głównej (poziomej) płytki drukowanej. Po wprowadzeniu listew do głównej PCB zalutowujemy je od spodu, pilnując, by montaż został wykonany starannie pod kątem prostym do płytki.

Fotografia 16. Przykładowe wykonanie i opis tylnego panelu generatora

Projekty obu płytek drukowanych zostały dopasowane do obudowy typu KM-60 i przed dolutowaniem płytki sterowania (panelowej) do płytki głównej należy wstępnie przypasować odległość montażu do usytuowania całości urządzenia w obudowie. Po ustaleniu odległości montażowych lutujemy starannie płytkę przednią do „goldpinów” wyprowadzonych z płytki głównej i możemy przystąpić do wstępnego uruchomienia urządzenia – przed zamontowaniem w obudowie.

Rysunek 17. Wzór maskownic-opisów na panele obudowy

Jeśli nie korzystamy z zaprogramowanego mikrokontrolera, to układ ten należy zaprogramować w zewnętrznym gnieździe DIP-28 programatora. W pierwszym kroku trzeba ustawić bity konfiguracyjne mikrokontrolera zgodnie z rysunkiem 18 (low fusebit: 3F, high fusebit: D7), a następnie wgrać do niego kod z pliku HEX. Po zainstalowaniu mikrokontrolera montujemy wyświetlacz LCD U11 i włączamy główne zasilanie +12 V.

Rysunek 18. Ustawienia fusebitów mikrokontrolera ATmega8

Na LCD powinniśmy ujrzeć ekran powitalny, pokazany na fotografii 19. Potencjometrem PR2 regulujemy kontrast LCD. Po wyłączeniu zasilania montujemy wybrany moduł generatora DDS. Obrysy modułów, namalowane na górnej stronie głównej płytki drukowanej, pomogą w prawidłowym umiejscowieniu modułu w przygotowanym w tym celu gnieździe. Po ponownym włączeniu zasilania powinna zaświecić się także dioda LED, umieszczona na module DDS. Dalszą regulację i konfigurację urządzenia opisano w części artykułu poświęconej obsłudze przyrządu.

Fotografia 19. Wygląd ekranu powitalnego

W tym miejscu należy poświęcić kilka słów montażowi przyrządu w obudowie. Idealnym rozwiązaniem byłoby zastosowanie obudowy metalowej, która po uziemieniu zapewniałaby ekranowanie. Jakkolwiek, najtańsze i najdogodniejsze w obróbce mechanicznej są fabryczne obudowy, wykonane z tworzyw sztucznych. Projekt opisywanego tutaj urządzenia od samego początku powstawał z zamiarem użycia obudowy typu KM-60. Po wstępnym przymierzeniu zmontowanego urządzenia do obudowy przykręcamy do niej płytkę główną dwoma wkrętami M3. Następnie wykonujemy w tylnym panelu trzy otwory dla gniazd BNC (fot. 16) oraz otwory dla gniazda zasilania 12 V i włącznika.

Ostatnim elementem konstrukcji mechanicznej urządzenia jest usztywnienie przedniej (pionowej) płytki drukowanej. Jest ono niezbędne z uwagi na naprężenia, które będą występowały na łączeniu obu płytek drukowanych pod wpływem nacisku na enkoder SW1. W egzemplarzu modelowym wzmocnienie wykonano, łącząc dwoma śrubami M2,5 płytkę drukowaną sterowania z przednim panelem.

Trwale zamocowane w obudowie urządzenie należy połączyć elektrycznie z wyprowadzeniami sygnałów na gniazdach BNC oraz włącznikiem i gniazdem zasilania +12 V. Z uwagi na brak zagrożenia zwarć wewnątrz zamkniętej obudowy, opisane połączenia można wykonać np. za pomocą srebrzanki o średnicy 0,5 mm.

Oprogramowanie

Program sterujący generatorem napisano w języku Bascom AVR. Kod programu sterującego pracą układu podzielono na cztery listingi 1…4 (ze względu na obszerność, są one dostępne w materiałach dodatkowych), odpowiadające podziałowi na zasadnicze części programu.

Listing 1 obejmuje definicje i deklaracje wstępne wraz z kodem inicjującym urządzenie i pozwalającym wybrać jego zasadniczą funkcję (generator lub wobulator). Pierwsze linijki służą do konfiguracji pracy mikrokontrolera U10 (ATmega8A-PU). Zdefiniowano w nim typ i częstotliwość taktowania U10 zewnętrznym rezonatorem kwarcowym 16 MHz, a także rozmiary stosów i ramki programu. Dalej ustalono konfigurację sterowania wyświetlacza alfanumerycznego LCD 16×2 (U11) oraz zdefiniowano osiem specjalnych znaków semigraficznych. Są to jednoznakowe symbole: jednostki herca [Hz], skrótu indeksu „peak-to-peak”, jednostki napięcia [Vp-p], strzałki w górę i w dół oraz cztery pogrubione symbole literowe modyfikowanych parametrów: częstotliwości F, napięcia U, kroku regulacji częstotliwości D oraz szybkości wobulacji S.

Listing 1.
'Dwumodułowy generator DDS (AD9850) z wobulatorem
'Autor: Adam Sobczyk SQ5RWQ @ 05-11'2016
'Ver. 1.00

'************************** KOD PODSTAWOWY/WSPÓLNY *****************************
'KONFIGURACJA PROCESORA I SYSTEMU
$regfile = "m8def.dat"
$crystal = 16000000 ' Dla celu szybszej wobulacji zdecydowanie wskazane jest użycie rezonatora na 16 MHz
$hwstack = 40
$swstack = 16
$framesize = 32

'KONFIGURACJA WYŚWIETLACZA LCD 16x2 ZNAKI
Config Lcdpin = Pin , Db4 = Portd.6 , Db5 = Portd.7 , Db6 = Portb.0 , Db7 = Portb.1 , E = Portd.5 , Rs = Portd.4
Config Lcd = 16 * 2
Cls

'DEFINICJE ZNAKÓW WŁASNYCH
Deflcdchar 0 , 20 , 20 , 28 , 23 , 21 , 2 , 4 , 7 ' "Hz" - Chr(0)
Deflcdchar 1 , 28 , 21 , 28 , 16 , 7 , 21 , 7 , 4 ' "p-p" - Chr(1)
Deflcdchar 2 , 4 , 14 , 31 , 14 , 14 , 14 , 14 , 32 ' strzałka w górę - Chr(2)
Deflcdchar 3 , 14 , 14 , 14 , 14 , 31 , 14 , 4 , 32 ' strzałka w dół - Chr(3)
Deflcdchar 4 , 31 , 24 , 24 , 30 , 24 , 24 , 24 , 32 ' "F" bold - Chr(4)
Deflcdchar 5 , 25 , 25 , 25 , 25 , 25 , 25 , 14 , 32 ' "U" bold - Chr(5)
Deflcdchar 6 , 28 , 26 , 25 , 25 , 25 , 26 , 28 , 32 ' "D" bold - Chr(6)
Deflcdchar 7 , 14 , 25 , 24 , 14 , 3 , 19 , 14 , 32 ' "S" bold - Chr(7)

'RESET LCD I POWITANIE
Cls
Cursor Off
Upperline : Lcd "Gen. DDS AVT5580"
Lowerline : Lcd "SQ5RWQ (R) 2016"
Wait 5
Cls

Dim Sa As String * 16 ' ciąg tekstowy do formatowania F (z miejscem na spację na końcu)

'KONFIGURACJA PORTÓW STEROWANIA DDS
Config Portc.5 = Output ' DDS - ZEGAR
Config Portc.4 = Output ' DDS - FLAGA ZMIANY CZĘSTOTLIWOŚCI
Config Portc.3 = Output ' DDS - LINIA DANYCH SZEREGOWYCH
Config Portc.2 = Output ' DDS - RESET UKŁADU

'PORTY STERUJĄCE DDS - aliasy
Dds_w_clk Alias Portc.5
Dds_fq_ud Alias Portc.4
Dds_data Alias Portc.3
Dds_reset Alias Portc.2

'ZMIENNE PODSTAWOWE DLA OBSŁUGI DDS
Dim Init As Byte
Init = &H00
Dim Freq As Long
Dim Freq_d As Single
Const Df = 34.359738368 ' 2^32 / 125e6 = [2^(32-6)] / [125*(5^6)] = (2^26) / (5^9) = 67108864 / 1953125

'OBSŁUGA ENKODERA MECHANICZNEGO
Config Portb.3 = Input ' PIN-A, użyto zewnętrzny rezystor podciągający linię
Config Portb.4 = Input ' PIN-B, użyto zewnętrzny rezystor podciągający linię
Config Portd.2 = Input ' WBUDOWANY PRZYCISK, użyto zewnętrzny rezystor podciągający linię

Dim Encportbyte As Byte ' bajt przechowujący bity stanu z enkodera
Encportbyte = 255 ' inicjacja

'OBSŁUGA CZASOWA ENKODERA - Z ZASTOSOWANIEM PRZERWAŃ O CZĘSTOTLIWOŚCI ok. 2 kHz (rozsądne minimum przy odległościach zboczy rzędu 1ms przy szybkim obracaniu)
'I WYSTAWIANIEM FLAG BITOWYCH, INFORMUJĄCYCH O STANIE WYJŚĆ I KIERUNKU OBRACANIA
Config Timer2 = Timer , Prescale = 64 , Clear_timer = 1 'Valid values are 1 , 8, 64, 256 or 1024
Ocr2 = 125 ' ca. 2 kHz @ autoreload mode active (Clear_timer = 1)
On Compare2 Testenc Nosave
Enable Interrupts
Enable Compare2


' ********** OPCJONALNA (WSTĘPNA) PREKONFIGURACJA FUNKCJI URZĄDZENIA ***********
Dim State As Byte ' Bitowe zmienne stanu trybu pracy urządzenia b0: 0=GEN, 1=VOB, b1: 0=DIGI_OFF, 1=DIGI_ON
Readeeprom State , 10 ' adres zmiennej stanu 'State' w pamięci EEPROM

If Pind.2 = 0 Then ' przycisk wciśnięty w momencie startu urządzenia
' * WYBÓR I ZAPAMIĘTANIE STANU DLA WYJŚCIA SYGNAŁU CYFROWEGO "DIGI"
Cls
Upperline
Lcd "DIGI OUT:"
Wait 1
Do
Lowerline
If State.1 = 1 Then
Lcd " ON "
Else
Lcd " OFF "
End If
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
State.1 = 1
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
State.1 = 0
End If
Loop Until Pind.2 = 0

' * WYBÓR I ZAPAMIĘTANIE TRYBU PRACY URZĄDZENIA (GEN/WOB)
Cls
Upperline
Lcd "MODE:"
Wait 1
Do
Lowerline
If State.0 = 1 Then
Lcd " WOB "
Else
Lcd " GEN "
End If
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
State.0 = 1
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
State.0 = 0
End If
Loop Until Pind.2 = 0

Writeeeprom State , 10 ' adres tymczasowy zmiennej stanu 'State' !!! - do korekty na koniec alokacji wszystkich zmiennych w EEPROM !!!

End If

' ************ USTAWIENIE WYJŚCIA CYFROWEGO "DIGI" I START GŁÓWNEGO PROGRAMU ************
'USTAWIENIE TRYBU PRACY URZĄDZENIA "STATE" W OPARCIU O USTAWIENIA NOWE LUB ZAPISANE W PAMIĘCI EEPROM
'b1: 0=DIGI_OFF, 1=DIGI_ON
Cls
Upperline
Config Portc.1 = Output ' DIGI ON/OFF
If State.1 = 1 Then
Portc.1 = 1 ' DIGI ON
Lcd "DIGI out ON"
Else
Portc.1 = 0 ' DIGI OFF
Lcd "DIGI out OFF"
End If

' URUCHOMIENIE GENERATORA DDS (CHIP'U AD9850) - PRZED PRZEJŚCIEM DO WYBRANEGO TRYBU PRACY
Set Dds_reset : Reset Dds_reset ' Reset
Set Dds_w_clk : Reset Dds_w_clk ' W_CLK
Set Dds_fq_ud : Reset Dds_fq_ud ' FQ_UD

'b0: 0=GEN, 1=VOB
Lowerline
If State.0 = 0 Then
Lcd "Generator Mode"
Wait 2
'Goto Generator ' skok zbędny - ta część programu jest po prostu kolejna
Else
Lcd "Wobulator Mode"
Wait 2
Goto Wobulator
End If

Po zdefiniowaniu znaków semigraficznych i niezbędnym w tym momencie restarcie sterownika wyświetlacza LCD jest wyświetlany komunikat powitalny, po którym następuje definicja: roboczego ciągu tekstowego „Sa”, wykorzystywanego dalej do czytelnego formatowania częstotliwości generatora „F”, portów sterujących pracą modułu DDS (sygnały: W_CLK, FQ_UD, DATA, oraz RESET, zamapowane na piny PORTC.2…5), a także podstawowych zmiennych wykorzystywanych do sterowania modułem AD9850: Init (ciąg startowy), Freq i Freq_d (programowana częstotliwość w dwóch formatach) oraz stałej Df. Wartość tej stałej, równa „34.359738368”, wynika z przeliczenia formuły: 2^32/125*10^6 (liczba możliwych kombinacji rejestru akumulatora DDS-a, podzielona przez częstotliwość taktowania generatora Fs) i jest wykorzystywana do przeliczenia pożądanej częstotliwości generowanej Fc na krok (przyrost) fazy syntezera DDS.

W dalszej części kodu zdefiniowano porty wejściowe, przeznaczone do obsługi enkodera mechanicznego (piny PORTB.3…4) oraz PORTD.2 dla jego przycisku. Określono też i zainicjowano zmienną Encportbyte oraz przerwanie czasowe wywołujące podprogram (procedurę) Testenc modyfikującą tę zmienną. Treść i sposób działania tej procedury zostanie omówiona dalej, ale już w tym miejscu należy zaznaczyć, że jej zadaniem jest skanowanie (próbkowanie) styków enkodera ze stałą częstotliwością około 2 kHz, pozwalającą na prawidłowe wykrywanie stanu i kierunku obracania (ta informacja jest przekazywana do głównego kodu właśnie przez zmienną Encportbyte).

Kolejny krok to ustalenie konfiguracji pracy urządzenia: jako generator („GEN”) lub jako wobulator („WOB”), z włączonym („ON”) lub z zablokowanym („OFF”) wyjściem cyfrowym „DIGI”. Informacje te są przechowywane w pamięci EEPROM pod adresem 10 na dwóch najmłodszych bitach zmiennej State. Jeśli jednak w momencie przejścia do tej części programu (praktycznie chwilę po zakończeniu wyświetlania ekranu powitalnego) będzie wciśnięty przycisk mikrokontrolera (PIND.2=0), to program przejdzie do dwóch bloków decyzyjnych, zorganizowanych w postaci zamkniętych pętli, powtarzanych aż do kolejnych naciśnięć przycisku enkodera. Wewnątrz tych pętli, na podstawie bitów b0 i b1 zmiennej State, wyświetlana jest wybrana konfiguracja pracy urządzenia a także istnieje możliwość jej zmiany w oparciu o analizę obecności i kierunku obrotu enkodera SW1, odzwierciedlonej na czterech najmłodszych bitach zmiennej Encportbyte. Odbywa się to wewnątrz instrukcji warunkowych If-Then-Elseif-Then-EndIf, które interpretują wartości zmiennej Encportbyte, równe 2, 4, 11 lub 13 jako obracanie w prawo, a wartości 1, 7, 8 lub 14 jako obracanie w lewo (wynika to z mechanicznej konstrukcji wewnętrznej styków enkodera).

Po dokonaniu wyboru trybu pracy przyrządu, zapamiętanego w zmiennej State, zapisanej następnie w pamięci EEPROM, następuje fizyczne włączenie (PORTC.1=1) lub wyłączenie (PORTC.1=0) portu „DIGI”. Ostatnie dwa działania w tym bloku programowym to: aktywacja (uruchomienie) generatora DDS (chipu AD9850) poprzez wygenerowanie krótkich impulsów (poniżej 1 µs) kolejno na jego portach: RESET, W_CLK i FQ_UD oraz przejście do podprogramu realizującego tryb Generatora lub tryb Wobulatora. Wybrany tryb pracy jest zapowiadany dużym napisem, a w przypadku trybu Wobulatora wykonywany jest odpowiedni skok bezwarunkowy do procedury obsługującej tę opcję (podprogram dla Generatora znajduje się w następującej bezpośrednio dalej części programu i nie wymaga realizacji skoku).

Listing 2 zawiera opis procedur obsługujących funkcję generatora. W pierwszej kolejności skonfigurowano jako wejściowy PORTC.0, który pełni funkcję wejścia przetwornika A/C w mikrokontrolerze U10. Przetwornik skonfigurowano do pracy pojedynczej, z automatycznym preskalerem zegara oraz napięciem referencyjnym Uref=+5 V, pobieranym ze stabilizatora scalonego U2 (LM7805). Po uruchomieniu przetwornika A/C zdefiniowano i zainicjowano zmienne Uold i Unew, które służą do przechowywania bieżącej i poprzedniej próbki zmierzonego napięcia. Takie podejście służy unikaniu zbyt częstego formatowania i odświeżania wyświetlanej na LCD wartości napięcia wyjściowego, gdy nie ulegało ono zmianie. Kolejna zainicjowana zmienna to Uvolt, która po przeskalowaniu i sformatowaniu służy do bezpośredniej prezentacji na wyświetlaczu LCD.

Listing 2.
' ************************ FUNKCJA GENERATORA ************************
Generator:
' KONFIGURACJA I START PRZETWORNIKA ADC
Config Portc.0 = Input ' ADC IN
Config Adc = Single , Prescaler = Auto , Reference = Avcc 'The single mode must be used with the GETADC() function
Start Adc 'Now give power to the chip; With STOP ADC, you can remove the power from the chip 'Stop Adc
Dim Uold As Word , Unew As Word ' do sprawdzania, czy zmierzona wartosc ulegla zmianie
Uold = 0 : Unew = 0
Dim Uvolt As Single ' do wyswietlania na LCD
Uvolt = 0

' PODSTAWOWE PARAMETRY PRACY GENERATORA - USTAWIENIE POCZĄTKOWE
Dim F As Long , Fold As Long ' [Hz]
F = 1000000
Fold = F
Dim Fstep As Long '[Hz]
Fstep = 1000

' PIERWSZY SETUP GENERATORA
Freq_d = Df * F : Freq = Freq_d
Gosub Dds_setup

' INICJACJA WYŚWIETLANIA NA LCD
Gosub F_disp
Gosub Df_disp
Gosub U_disp
Locate 1 , 16 : Lcd "G"

Do
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
Gosub F_up
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
Gosub F_down
End If

'Zmiana kroku strojenia generatora
If Pind.2 = 0 Then
Gosub F_step_chng ' praca "w kółko" z powrotem na początek (1, 10, ..., 1000000, 1, 10 ... itd.)
End If
If F <> Fold Then
Fold = F
Freq_d = Df * F
Freq = Freq_d
Gosub Dds_setup
Gosub F_disp
End If
Unew = Getadc(0) ' pomiar napięcia wyjściowego sinusoidalnego; test, czy zaszła zmiana?
If Unew <> Uold Then
Unew = Unew + Uold
Shift Unew , Right , 1 ' uśrednianie
Uold = Unew ' zapamiętanie do późniejszego porównania
Gosub U_disp
End If
Loop

W kolejnych krokach zostały zdefiniowane i zainicjowane zmienne: F, Fold i Fstep. Zmienne F i Fold przechowują bieżącą i poprzednią wartości zadawanej częstotliwości generatora. Ich porównywanie pozwala na uniknięcie częstej rekonfiguracji parametrów pracy generatora DDS wtedy, gdy obie one są równe (brak oczekiwanych zmian).

Natomiast zmienna Fstep przechowuje bieżący krok modyfikacji częstotliwości F, wykorzystywany przy jej modyfikacji za pomocą enkodera obrotowego SW1. W programie przyjęto wartości początkowe F=1 MHz oraz Fstep=1 kHz.

Kolejny blok programu realizuje pierwszą nastawę generatora DDS. Najpierw żądana częstotliwość F jest przeliczana na zwiększenie wartości akumulatora Freq_d, odpowiadające przyrostowi fazy sygnału generowanego, a następnie wyliczona wartość zmiennej Freq_d jest rzutowana na zmienną Freq 32-bitowego typu całkowitego, odpowiedniego dla rejestru sterującego AD9850. Za przesłanie tej zmiennej do syntezera jest odpowiedzialna procedura Dds_setup. W następnym etapie następuje zainicjowanie wyświetlania parametrów pracy generatora: częstotliwości F, kroku strojenia Df, napięcia wyjściowego U oraz trybu pracy G, realizowane przez procedury: F_disp, Df_disp, U_disp i funkcję Lcd.

Wewnątrz nieskończonej pętli Do…Loop cyklicznie powtarzane są te same czynności:

  • Interpretacja stanu enkodera obrotowego SW1 i w razie konieczności zmiana nastawy częstotliwości F o wartość kroku Fstep za pomocą procedury F_up lub F_down.
  • Sprawdzenie stanu przycisku enkodera SW1 i jeśli odpowiadające mu wejście PIND.2=0, rotacyjna zmiana parametru Fstep z zastosowaniem procedury F_step_chng.
  • W bloku instrukcji warunkowej If-Then-EndIf następuje porównanie ostatnio ustawionej częstotliwości generowanej F z częstotliwością poprzednią Fold i w razie wykrycia takiego stanu ponowne zaprogramowanie AD9850 oraz wyświetlenie generowanej częstotliwości F na ekranie LCD.
  • Pomiar i wizualizacja na ekranie LCD sinusoidalnego napięcia wyjściowego. Wykrycie zmiany wartości (Unew<>Uold) wyzwala proces uśrednienia porównywanych wartości, zapamiętania tak wyliczonej wartości jako poprzedniej a następnie wyświetlenie jej na ekranie LCD za pomocą procedury U_disp.

Na listingu 3 umieszczono procedury realizujące funkcję wobulatora. Na początku PORTB.2 jest definiowany jako wyjściowy, a następnie TIMER1 jest konfigurowany jako 8-bitowy przetwornik C/A pracujący w trybie PWM. Wyjście kanału PWM1A tego przetwornika jest wyprowadzone na wcześniej skonfigurowany PORTB.2 i służy do wytworzenia piłokształtnego sygnału odchylania poziomego, przeznaczonego do sterowania kanałem X oscyloskopu. Dalej definiowane są zmienne Fmin i Fmax będące granicami przedziału częstotliwości wobulacj), Deltaf – elementarny krok-postęp częstotliwości wobulacji, Fvobstep – krok regulacji krańców przedziału wobulacji Fmin i Fmax. Początkowy przedział wobulacji ustalono na zakres pasma akustycznego 20 Hz…20 kHz, a krok jego regulacji na 100 Hz. Po tych definicjach następuje pierwsze (inicjujące) wywołanie procedury Deltafcalc, której zadaniem jest wyznaczenie elementarnego kroku wobulacji Deltaf. Dalej wprowadzane są definicje zmiennych: Pwmval (poziom sygnału na wyjściu przetwornika DAC/PWM1A oraz iterator głównej pętli wobulatora), Fvob (rzeczywista częstotliwość wobulacji w zakresie 1…40 Hz), Tvobwaitus (czas determinujący szybkość wobulacji 1000000/(Fvob*256) minus ok. 91 [us]), Tvobwaitusword (wersja całkowitoliczbowa zmiennej Tvobwaitus). Początkową wartość częstotliwości wobulacji Fvob ustalono na 20 Hz. Następnie jest wywoływana procedura Fvob_chng, wyznaczająca opóźnienie w elementarnym kroku wobulacji – w funkcji przyjętej częstotliwości przemiatania Fvob. Dalej następuje pierwsze w procedurze wobulacji wyświetlenie na ekranie LCD regulowanych parametrów pracy: Fmin, Fmax, Fvob oraz Fvobstep.

Listing 3.
' ***************************** FUNKCJA WOBULATORA *****************************
Wobulator:
'KONFIGURACJA I START LICZNIKA TIMER1 JAKO PWM_N
Config Portb.2 = Output ' PWM10 DLA WOBULATORA - KANAŁ WYJŚCIOWY "X"
Config Timer1 = Pwm , Pwm = 8 , Compare_b_pwm = Clear_up , Prescale = 1
Start Timer1
Pwm1a = 0 ' USTAWIENIE PREWENCYJNIE - NIE UŻYWAMY KANAŁU PWM1A
Pwm1b = 0 ' USTAWIENIE WSTĘPNE / SPOCZYNKOWE

' Uwaga na typy zmiennych (long/single???), sposób dzielenia i błędy wynikające z zaokrąglenia kroku - do doprecyzowania/korekty później!!!
Dim Fmin As Long , Fmax As Long , Deltaf As Long , Fvobstep As Long
Fmin = 20 : Fmax = 20000 ' audio sweep

Gosub Deltafcalc '* UPDATE PARAMETRÓW WYNIKAJĄCYCH Z Fmin i Fmax

Fvobstep = 100 ' ustawienie kroku modyfikacji Fmin i Fmax w menu

Dim Pwmval As Word
Dim Fvob As Byte ' Częstotliwość wobulacji 1..40 Hz
Dim Tvobwaitus As Single ' Czas determinujący częstotliwość (szybkość) wobulacji: Tvobwaitus = 1000000 /(fvob * 256) minus ok. 91 [us]
Dim Tvobwaitusword As Word 'Wersja WORD zmiennej - specjalnie dla komendy 'waitus'

Fvob = 20 ' default; dopuszczalny zakres od 1 do 40 Hz

Gosub Fvob_chng
' Elementarny krok wobulacji (nie pełny okres) - bez dodatkowego wypełnienia czasowego na czas martwy, to ok.:
' 23.28 ms / 256 = 90.938 us @ PWM8 (Fvobmax = 43.0528 Hz)
' 46.56 ms / 512 = 90.938 us @ PWM9 (Fvobmax = 21,5264 Hz)
' 93.12 ms / 1024 = 90.938 us @ PWM10 (Fvobmax = 10.7632 Hz)

'Wyświetlanie parametrów na LCD - po raz pierwszy
Cls
Locate 1 , 16 : Lcd "W"
Upperline : Lcd Chr(2) ; Fmax ; Chr(0) ; " "
Lowerline : Lcd Chr(3) ; Fmin ; Chr(0) ; " "

Locate 1 , 12 : Lcd Chr(7) ; Fvob ; " " ' "S"
Locate 2 , 12 : Lcd Chr(6) ; Fvobstep ; " " ' "D"

Do
'* ZMIANA PARAMETRÓW WOBULACJI
If Pind.2 = 0 Then ' przycisk wciśnięty w momencie wejścia w nieskończoną pętlę - zmiana parametrów
'* ZMIANA Fvobstep - krok regulacji wartości Fmin i Fmax
Waitms 400
Do
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
If Fvobstep < 1000000 Then
Fvobstep = 10 * Fvobstep
End If
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
If Fvobstep > 1 Then
Fvobstep = Fvobstep \ 10
End If
End If
Locate 2 , 12 : Lcd "*"
Select Case Fvobstep
Case 1 To 100 : Lcd Fvobstep ; Chr(0) ; " "
Case 1000 To 100000 : Fvobstep = Fvobstep \ 1000 : Lcd Fvobstep ; "k" ; Chr(0) ; " " : Fvobstep = Fvobstep * 1000
Case 1000000 : Lcd "1M" ; Chr(0) ; " "
End Select
Loop Until Pind.2 = 0
Locate 2 , 12 : Lcd Chr(6) ' "D"

'* ZMIANA Fmin
Waitms 400
Do
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
Fmin = Fmin + Fvobstep
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
Fmin = Fmin - Fvobstep
End If
If Fmin < 1 Then
Fmin = 1
Elseif Fmin > Fmax Then
Fmin = Fmax
End If
Lowerline : Lcd "*" ; Fmin ; Chr(0) ; " "
Loop Until Pind.2 = 0
Lowerline : Lcd Chr(3)

'* ZMIANA Fmax
Waitms 400
Do
'Odczyt stanu enkodera
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
Fmax = Fmax + Fvobstep
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
Fmax = Fmax - Fvobstep
End If
If Fmax > 40000000 Then
Fmax = 40000000
Elseif Fmax < Fmin Then
Fmax = Fmin
End If
Upperline : Lcd "*" ; Fmax ; Chr(0) ; " "
Loop Until Pind.2 = 0
Upperline : Lcd Chr(2)

'* UPDATE PARAMETRÓW WYNIKAJĄCYCH Z Fmin i Fmax
Gosub Deltafcalc

'* ZMIANA Fvob - częstotliwość wobulacji
Waitms 400
Do
If Encportbyte = 2 Or Encportbyte = 4 Or Encportbyte = 11 Or Encportbyte = 13 Then ' PRAWO: Encportbyte = 2, 4, 11, 13; [11] - stan stabilny
If Fvob < 40 Then ' do doprecyzowania granica, która powinna być też skoordynowana z Fmin!!!
Incr Fvob
Gosub Fvob_chng
End If
Elseif Encportbyte = 1 Or Encportbyte = 7 Or Encportbyte = 8 Or Encportbyte = 14 Then ' LEWO: Encportbyte = 1, 7, 8, 14; [7] - stan stabilny
If Fvob > 1 Then ' do doprecyzowania granica, która powinna być też skoordynowana z Fmin!!!
Decr Fvob
Gosub Fvob_chng
End If
End If
Locate 1 , 12 : Lcd "*" ; Fvob ; Chr(0) ; " "
Loop Until Pind.2 = 0
Locate 1 , 12 : Lcd Chr(7) ' "S"
Waitms 600
End If

'* REGULARNA PRACA WOBULATORA
For Pwmval = 0 To 255
' Cykliczne wyliczenie częstotliwości generatora
F = Deltaf * Pwmval
F = F + Fmin
Freq_d = Df * F
Freq = Freq_d
' Zmiana wartości napięcia odchylania dla osi "X" oscyloskopu - przed zmianą F w DDS-ie, by ustaliła się wcześniej odpowiedź FDP
Pwm1b = Pwmval
' Zmiana częstotliwości generatora
Gosub Dds_setup
Waitus Tvobwaitusword
Next Pwmval
Loop

Nieskończoną pętlę Do…Loop podprogramu wobulatora podzielono na dwa bloki: modyfikacji parametrów procesu oraz jego realizacji. Blok realizacji podzielono na 4 cztery części, służące zmianie każdego z ustawialnych parametrów. Wejście do bloku modyfikacji parametrów procesu następuje po naciśnięciu przycisku enkodera SW1 (PIND.2=0) i odczekaniu 400 ms. Wtedy następuje wejście do podprogramu modyfikacji parametru Fvobstep, czyli kroku regulacji parametrów Fmin i Fmax. W kolejnej podpętli, przerywanej naciśnięciem przycisku enkodera, jest odczytywany kierunek obrotu enkodera, a następnie krok regulacji częstotliwości jest odpowiednio zmniejszany lub zwiększany 10-krotnie, przy czym odbywa się to wyłącznie w granicach 1 Hz…1 MHz. Zmodyfikowana wartość parametru Fvobstep jest formatowana i wyświetlana na LCD, przy czym przy modyfikowanym aktualnie parametrze cały czas w miejsce symbolizującej go ikony jest wyświetlana gwiazdka „*”. Opuszczenie pętli modyfikacji parametru Fvobstep następuje po naciśnięciu przycisku enkodera, a gwiazdka „*”, symbolizująca proces modyfikacji parametru, jest zamieniana na podstawowy symbol, czyli pogrubione „D”.

Modyfikacje kolejnych trzech parametrów wobulacji odbywają się w bardzo podobny sposób, każdorazowo po odczekaniu 400 ms od potwierdzającego naciśnięcia przycisku enkodera, z różnicami charakterystycznymi dla danego parametru. W przypadku parametru Fmin zmiana wartości następuje o (być może zmodyfikowaną w poprzednim kroku) wartość parametru Fvobstep, przy czym zakres możliwych wartości jest ograniczony od dołu do 1 Hz a od góry do bieżącej wartości Fmax. Znacznikiem parametru Fmin jest gruba strzałka, skierowana w dół. Analogicznie, w wypadku parametru Fmax zmiana wartości następuje o wartość parametru Fvobstep, przy czym zakres możliwych wartości jest ograniczony od góry do 40 MHz a od dołu do bieżącej wartości Fmin. Znacznikiem parametru Fmax jest gruba strzałka, skierowana w górę. Po modyfikacji Fmin i Fmax wywołana zostaje procedura Deltafcalc, która ponownie przelicza elementarny krok wobulacji Deltaf.

Ostatni, czwarty krok modyfikacji dotyczy parametru Fvob, utrzymując go w zakresie 1…40 Hz. Po zmianie wartości zmiennej Fvob jest wywoływana procedura Fvob_chng, wyznaczająca opóźnienie w elementarnym kroku wobulacji. Znacznikiem parametru Fvob jest pogrubiona litera S.

W drugiej części pętli Do…Loop jest realizowane przemiatanie ustalonego zakresu częstotliwości, połączone z wysterowaniem osi X oscyloskopu. Obszerny blok modyfikacji parametrów przy normalnej pracy wobulatora nie opóźnia jego działania, ponieważ program wchodzi do tego bloku wyłącznie w trybie konfiguracji urządzenia.

Podstawowa pętla wobulatora For…Next iteruje parametr Pwmval w zakresie 0…255, który jest właściwy do ustawienia jako wyjście przetwornika DAC/PWM i równocześnie stanowi iterator do wyliczenia narastającej częstotliwości wyjściowej F, liczonej jako iloczyn tego iteratora oraz wyliczonego wcześniej współczynnika skalującego Deltaf, powiększony o wartość Fmin. Tak wyznaczona wartość F jest następnie przeliczana na wartość parametru Freq_d do zaprogramowania AD9850 przez procedurę Dds_setup. Procedura ta jest poprzedzana modyfikacją wyjścia przetwornika PWM/DAC, aby przyśpieszyć propagację sygnału PWM przez filtry dolnoprzepustowe z układami U4A/U4B. Ostatnim działaniem, wykonywanym wewnątrz podstawowej pętli wobulacyjnej, jest wprowadzenie opóźnienia o wartość Tvobwaitusword mikrosekund, odpowiedniego do przyjętej szybkości wobulacji Fvob, wyliczonego przez wywołanie procedury Fvob_chng.

Listing 4 zawiera podprogramy pomocnicze wywoływane komendą skoku Gosub.

Listing 4.
'********************************* PODPROGRAMY *********************************

' TEST STANU STYKÓW ENKODERA - z pamięcią poprzednich stanów (ważne tylko bity b3..b0 w zmiennej "Encportbyte")
Testenc:
$asm
'Obsługa stosu (odłożenie używanych rejestrów)
push R24
in R24, sreg
push R24
push R25
' 1. Odczyt poprzednich stanów styków enkodera
lds R24, {Encportbyte}
' 2. Usunięcie najstarszych stanów (2 bity)
LSR R24
LSR R24
' 3. Wczytanie aktualnych stanów enkodera z portu B (PB.4, PB.3)
LDS R25, pinb
' 4. Maskowanie zerami wszystkich bitów poza PB.4 i PB.3
andi R25, 24 ' maska 00011000
' 5. Dorównanie w prawo o jedną pozycję (przesunięcie pobranych wartości na b3 i b2)
lsr R25
' 6. Połączenie starych i nowych stanów w jednym bajcie
OR R24, R25
' 7. Zapamiętanie odświeżonych stanów
sts {Encportbyte}, R24
'Obsługa stosu (przywrócenie wartości używanych rejestrów)
pop R25
pop R24
Out Sreg , R24
pop R24
$end Asm
Return

' GENERATOR - CZESTOTLIWOŚĆ W DÓŁ
F_down:
F = F - Fstep
If F < Fstep Then ' Limit dolny - nie schodzimy poniżej kroku strojenia
F = Fstep
End If
Return

' GENERATOR - CZESTOTLIWOŚĆ W GÓRĘ
F_up:
F = F + Fstep
If F > 40000000 Then ' Limit górny 40 MHz
F = 40000000
End If
Return

' GENERATOR - CYKLICZNA ZMIANA KROKU STROJENIA
F_step_chng:
If Fstep < 1000000 Then
Fstep = 10 * Fstep
Else
Fstep = 1
End If
Gosub Df_disp
Waitms 700 ' zapobieganie zbyt szybkiemu powtarzaniu zmian
Return

' DDS AD9850 - PROCEDURA SETUP'U CZĘSTOTLIWOŚCI
Dds_setup:
Shiftout Dds_data , Dds_w_clk , Freq , 3 , 32
Shiftout Dds_data , Dds_w_clk , Init , 3 , 8
Set Dds_fq_ud : Reset Dds_fq_ud
Return


' GENERATOR - WYŚWIETLANIE SFORMATOWANEJ CZĘSTOTLIWOŚCI NA LCD
F_disp:
Upperline
Lcd Chr(4) ; "=" ' "F"
Sa = Str(f)
If F >= 10000000 Then ' >=10 MHz
Lcd Left(sa , 2) ; "." ; Mid(sa , 3 , 3) ; "." ; Right(sa , 3) ; "M" ; Chr(0)
Elseif F >= 1000000 Then ' >=1 MHz
Lcd Left(sa , 1) ; "." ; Mid(sa , 2 , 3) ; "." ; Right(sa , 3) ; "M" ; Chr(0) ; " "
Elseif F >= 100000 Then ' >=100 kHz
Lcd Left(sa , 3) ; "." ; Right(sa , 3) ; "k" ; Chr(0) ; " "
Elseif F >= 10000 Then ' >=10 kHz
Lcd Left(sa , 2) ; "." ; Right(sa , 3) ; "k" ; Chr(0) ; " "
Elseif F >= 1000 Then ' >=1 kHz
Lcd Left(sa , 1) ; "." ; Right(sa , 3) ; "k" ; Chr(0) ; " "
Elseif F >= 100 Then ' >=100 Hz
Lcd Sa ; Chr(0) ; " "
Elseif F >= 10 Then ' >=10 Hz
Lcd Sa ; Chr(0) ; " "
Else ' <10 Hz
Lcd Sa ; Chr(0) ; " "
End If
Return

' GENERATOR - WYŚWIETLANIE SFORMATOWANEGO KROKU STROJENIA NA LCD
Df_disp:
Lowerline : Lcd Chr(6) ; "=" ' "D"
Select Case Fstep
Case 1 : Lcd "1" ; Chr(0) ; " "
Case 10 : Lcd "10" ; Chr(0) ; " "
Case 100 : Lcd "100" ; Chr(0) ; " "
Case 1000 : Lcd "1k" ; Chr(0) ; " "
Case 10000 : Lcd "10k" ; Chr(0) ; " "
Case 100000 : Lcd "100k" ; Chr(0) ; " "
Case 1000000 : Lcd "1M" ; Chr(0) ; " "
Case Else : Lcd "Err "
End Select
'Lcd Chr(0) ; " "
Return

' GENERATOR - WYŚWIETLANIE ZMIERZONEGO, PRZESKALOWANEGO I SFORMATOWANEGO NAPIĘCIA WYJŚCIOWEGO (SINUS) NA LCD
U_disp:
'Uvolt = Unew * 5.00 : Uvolt = Uvolt / 1024
Uvolt = 0.0048828125 * Unew
Uvolt = Uvolt + 0.219 ' + 219 mV - korekta wyznaczona eksperymentalnie (pomiarowo) dla zakresu 1kHz..1MHz
Locate 2 , 9
If Uvolt => 0.22 Then
Lcd Chr(5) ; "=" ; Fusing(uvolt , "#.##") ; "V" ; Chr(1) ' "U= ... Vp-p"
Else
Lcd Chr(5) ; "<=0.22V" ; Chr(1) ' "U<=0.22V"
End If
Return

' WOBULATOR - WYZNACZENIE OPÓŹNIENIA W ELEMENTARNYM KROKU WOBULACJI WZGLĘDEM PRZYJĘTEJ CZĘSTOTLIWOŚCI PRZEMIATANIA
Fvob_chng:
Tvobwaitus = Fvob * 256
Tvobwaitus = 1000000 / Tvobwaitus
Tvobwaitus = Tvobwaitus - 90.938
Tvobwaitusword = Tvobwaitus
Return

' WOBULATOR - WYZNACZENIE ELEMENTARNEGO KROKU (PRZYROSTU) CZĘSTOTLIWOŚCI PRZY PRZEMIATANIU
Deltafcalc:
Deltaf = Fmax - Fmin
Deltaf = Deltaf / 255
Return

Procedurę Testenc w całości napisano w asemblerze dla procesorów z rdzeniem AVR ATmega – w celu maksymalnego zwiększenia szybkości jej działania, ponieważ jest wywoływana za pomocą przerwania generowanego z częstotliwością około 2 kHz. Procedura wykonuje test stanu styków enkodera z pamięcią poprzednich stanów, a wynik przekazuje do zmiennej Encportbyte, w której istotne są tylko bity b3…b0. W pierwszej kolejności na stos procesora odkładane są wszystkie używane rejestry (SREG, R24 i R25). Następnie poprzednie stany styków enkodera są przesyłane ze zmiennej Encportbyte do rejestru R24. Dalej są usuwane 2 najstarsze bity stanów (b1…b0) poprzez dwukrotne przesunięcie w prawo rejestru R24. Potem aktualne stany enkodera odczytywane są z portu B (PB.4, PB.3) do rejestru R25, w którym maskowane zerami są wszystkie pozostałe bity. Dalsze dorównanie w prawo o jedną pozycję powoduje przesunięcie pobranych wartości na bity b3 i b2. Połączenie alternatywą logiczną rejestrów R24 i R25 tworzy nowy zestaw czterech bitów stanu w rejestrze R24, który następnie jest zapamiętywany w zmiennej Encportbyte. Procedurę kończy pobranie ze stosu poprzednich wartości wszystkich używanych rejestrów.

Procedura F_down i F_up, odpowiednio: zmniejsza lub zwiększa częstotliwości pracy generatora o wartość kroku Fstep, dbając jednak o to, aby nie wykroczyły one poza zakres Fstep…40 MHz.

Procedura F_step_chng powoduje zmianę kroku strojenia generatora Fstep w sposób cykliczny, tzn. w ciągu od 1 Hz do 1 MHz (z powiększaniem 10×) i dalej z powrotem od 1 Hz. Po realizacji każdorazowej takiej zmiany wywołana zostaje także procedura aktualizacji wyświetlania wartości Fstep na wyświetlaczu LCD. Następnie odczekany zostaje czas, który pozwala uniknąć wielu kolejnych zmian tego parametru przy dłuższym naciśnięciu przycisku enkodera.

Procedura Dds_setup realizuje programowanie częstotliwości AD9850. Odbywa się to poprzez wprowadzenie szeregowo najpierw 32-bitowego słowa Freq reprezentującego nową częstotliwość, a następnie 8-bitowej sekwencji Init powodującej wprowadzenie nowej częstotliwości. Procedurę kończy wygenerowanie krótkiego impulsu zatwierdzającego tę zmianę na linii FQ_UD syntezera.

Procedura F_disp realizuje wyświetlanie sformatowanej częstotliwości generatora na wyświetlaczu LCD. Wykorzystywano w niej specjalną, pogrubioną czcionkę „F”, zdefiniowaną jako znak specjalny. Procedura ta najpierw zamienia całkowitą wartość częstotliwości F na ciąg tekstowy Sa, a następnie w ciągu instrukcji If-Then-Elseif-Else-EndIf dokonuje formatowania zależnego od przedziału, do którego należy wyświetlana wartość. Formatowanie to polega na wstawieniu kropek dziesiętnych, oddzielających kolejne trzycyfrowe bloki cyfr, a następnie na końcu dostawia właściwą jednostkę (Hz, kHz lub MHz). Jednostkę „Hz” zaimplementowano w formie pojedynczego, zdefiniowanego na początku programu znaku specjalnego, co pozwoliło na zaoszczędzenie jednego znaku na względnie niewielkim wyświetlaczu LCD.

Procedura Df_disp powoduje wyświetlenie sformatowanego kroku strojenia generatora na wyświetlaczu LCD, a odbywa się to z zastosowaniem specjalnej, pogrubionej czcionki „D”, zdefiniowanej jako znak specjalny. W procedurze użyto bloku instrukcji Select-Case-EndSelect, które selekcjonują poszczególne wartości kroków strojenia generatora Fstep i przypisują im odpowiednie napisy, składające się z liczby zakończonej odpowiednią jednostką wielokrotną (Hz, kHz lub MHz).

Procedura U_disp ma za zadanie przeskalowanie, sformatowanie i wyświetlenie na ekranie LCD zmierzonego napięcia wyjściowego z generatora. Skalowanie odbywa się wg współczynnika 5/1024 V, odpowiadającego przyjętemu napięciu referencyjnemu Uref=+5 V i rozdzielczości przetwornika A/C. Przeskalowana wartość jest powiększana o około 0,22 V, co odpowiada napięciu progowemu zastosowanego detektora-podwajacza napięcia z diodami Schottky'ego D1 i D2. Zmienna Unew odpowiada wielkości zmierzonej przez detektor, natomiast zmienna Uvolt jest wielkością wyświetlaną na ekranie LCD. Formatowanie z dokładnością do dwóch miejsc po przecinku ma charakter wariantowy, bowiem dla wielkości mniejszych od 0,22 V, z uwagi na niepewną wartość pomiaru, wyświetlany jest jedynie stały komunikat.

Procedura Fvob_chng wyznacza opóźnienie Tvobwaitus (w mikrosekundach), które należy wprowadzić w elementarnym kroku wobulacji dla przyjętej częstotliwości przemiatania Fvob. Pierwsze dwa wyrażenia realizują: podział jednego cyklu wobulacji na 256 przedziałów (rozdzielczość 8-bitowego przetwornika DAC/PWM) oraz skalowanie od zastosowanej dla parametru Fvob jednostki [Hz] do mikrosekund. Kolejny wiersz wprowadza oszacowaną pomiarowo korektę o stałe czasy wykonania pojedynczej iteracji, a ostatnie wyrażenie dokonuje rzutowania zmiennoprzecinkowego rezultatu opisanych obliczeń na wartość całkowitą.

Procedura Deltafcalc wyznacza elementarny krok (przyrost) częstotliwości Deltaf, zastosowany przy przemiataniu. Jest to po prostu różnica skrajnych częstotliwości wobulacji Fmin oraz Fmax, podzielona przez zastosowaną liczbę przedziałów, równą 255.

Jak widać, kod programu sterującego urządzeniem nie jest bardzo skomplikowany, choć względnie obszerny (plik w formacie HEX, przeznaczony do zaprogramowania mikrokontrolera ATmega8, wypełnia 99% jego pamięci FLASH). Zachowana w programie prostota struktury, sposób podziału i uporządkowanie różnych funkcji a także liczne, dość wyczerpujące komentarze zachęcają do własnych modyfikacji i eksperymentów z urządzeniem. Krótka, ilustrowana instrukcja obsługi oprogramowania przyrządu zostanie podana w dalszej części tego opracowania.

Obsługa

Tryb pracy można zmienić tylko w chwili włączenia urządzenia – poprzez naciśnięcie i przytrzymanie przycisku enkodera aż do momentu wejścia w menu trybu pracy przyrządu. Po kilku sekundach wyświetlania ekranu powitalnego (fotografia 19) zostanie wyświetlony jeden z dwóch ekranów wyboru stanu aktywności wyjścia (buforu) dla sygnału cyfrowego („DIGI OUT: OFF/ON”). Pokręcając gałką enkodera, ustawiamy wyjście cyfrowe jako aktywne („ON”) i zatwierdzamy ten wybór przyciskiem enkodera, tym samym przechodząc do kolejnego poziomu wyboru w menu konfiguracyjnym. W podobny sposób wybieramy tryb pracy przyrządu („MODE: GEN/WOB”). Po wyborze przez kilka sekund będziemy mogli oglądać ekranik podsumowujący wybrane ustawienia, które w przypadku wyboru trybu wobulatora i wyłączenia wyjścia cyfrowego (przykład) wyglądałyby tak, jak na fotografii 20.

Fotografia 20. Wygląd ekranu podsumowującego ustawienia

Na ekranie przyrządu pracującego w trybie generatora, w górnym wierszu są wyświetlane: po lewej – nastawiona częstotliwość F, po prawej – duża litera „G” lub „W” symbolizująca wybrany tryb pracy. W dolnym wierszu, po lewej stronie można odczytać wybrany krok regulacji częstotliwości, a po prawej międzyszczytową wartość [Vp-p] zmierzonego wyjściowego napięcia sinusoidalnego. Z uwagi na zastosowaną metodę pomiaru (detektor szczytowy w układzie podwajacza napięcia z diodami Schottky'ego, skalibrowany programowo dla częstotliwości zbliżonej do 1 MHz) wskazania napięcia należy traktować orientacyjnie. Dodatkowo, z uwagi na napięcie progowe detektora na poziomie około 0,22 V, sygnały wyjściowe o niższym poziomie nie zostaną zmierzone.

Obsługa generatora jest bardzo łatwa. Regulację częstotliwości F przeprowadzamy pokrętłem enkodera, a zmianę kroku tej regulacji wykonujemy poprzez naciskanie jego przycisku (kolejne kroki zmieniają się cyklicznie w kierunku rosnącym). Amplitudę sygnału wyjściowego sinusoidalnego zmieniamy liniowym potencjometrem obrotowym PR3, który wyprowadzono na przedni panel urządzenia. Należy w tym miejscu podkreślić, że wyjściowy wzmacniacz szerokopasmowy z tranzystorami Q1..,Q3, o wzmocnieniu około 12 dB, jest w stanie dostarczyć nieprzesterowanego sygnału wyjściowego o maksymalnym poziomie około 2 Vp-p. Może zatem być przesterowany, gdy zostanie zasilony sygnałem z modułu DDS o poziomie przekraczającym około 0,5 Vp-p.

Ponieważ różne typy (i różne wykonania) rozważanych tutaj modułów generatorów DDS mają różne poziomy napięć wyjściowych, zmieniające się także znacząco wraz z częstotliwością wytwarzanego przebiegu, kryterium utrzymania poziomu sygnału wyjściowego, nieprzekraczającego około 2 Vp-p, jest prostą i dogodną metodą ograniczania zniekształceń nieliniowych w napięciu wyjściowym generatora.

Bardzo ważną czynnością, którą koniecznie należy wykonać, jest wyregulowanie współczynnika wypełnienia generowanego przebiegu prostokątnego na wartość jak najbliższą 50%. Przebieg ten powstaje w szybkim komparatorze w układzie AD9850 jako efekt porównania odfiltrowanego sygnału sinusoidalnego ze stałym napięciem referencyjnym, ustalanym potencjometrem montażowym, umieszczonym na module generatora DDS. Regulację przeprowadzamy tym właśnie potencjometrem, a pomiaru dokonujemy np. oscyloskopem cyfrowym. W ostateczności, jeśli nie dysponujemy odpowiednim przyrządem pomiarowym, można zastosować metodę uproszczoną, polegającą na pomiarze odfiltrowanego dolnoprzepustowo napięcia średniego (filtr RC z R=10 kΩ i C=100 nF będzie wystarczający z zapasem dla testowej F=1 MHz) i regulacji potencjometrem, umieszczonym na module DDS, aż do uzyskania na wyjściu filtru RC wartości środkowej pomiędzy szczytami napięcia prostokątnego. Przy filtracji i pomiarze napięcia z wyjścia na porcie P3 będzie to wartość w bardzo dobrym przybliżeniu równa połowie napięcia zasilania, pobieranego ze stabilizatora U2 (LM7805), czyli około 2,5 V.

Fotografia 21. Wygląd ekranu przyrządu w trybie wobulatora

Przełączenie urządzenia do trybu wobulatora należy wykonać w sposób opisany wcześniej. Ekran w trybie wobulatora wygląda jak na fotografii 21. Po lewej stronie pokazano dolną (u dołu) i górną (na górze ekranu) częstotliwość graniczną wobulacji. Po prawej stronie wyświetlacza można zobaczyć krok regulacji (u dołu) oraz częstotliwość przemiatania (u góry). Duża litera „W” w prawym, górnym rogu informuje o wybranym trybie pracy wobulatora. Domyślne ustawienia wobulatora to Fmin=20 Hz oraz Fmax=20 kHz (pasmo akustyczne), krok regulacji 100 Hz, szybkość przemiatania 20 Hz. Wciśnięcie przycisku enkodera spowoduje przejście do cyklu zmiany tych parametrów, co będzie sygnalizowane zastąpieniem ikonki wskazującej modyfikowany parametr tymczasowym symbolem „*”. Przechodzimy wówczas kolejno przez: krok regulacji częstotliwości, jej granice zmian oraz szybkość wobulacji (w prawo w kierunku obrotu wskazówek zegara). Wybrany parametr zmieniamy pokrętłem enkodera, a jego wartość zatwierdzamy przyciskiem. Jeśli nie chcemy zmieniać parametru, to przechodzimy do kolejnego, po prostu naciskając przycisk enkodera. Podobnie opuszczamy menu zmiany parametrów wobulacji.

Korzystanie z trybu wobulatora wymaga wstępnego ustawienia zakresu wartości piłokształtnego napięcia sterującego wejściem „X” oscyloskopu (wyjście „SYNCHRO” na porcie P4 urządzenia). Można to zrobić za pomocą potencjometru montażowego PR1, zamontowanego w pobliżu środka głównej (wykonawczej). Na początku pracy z przyrządem rozsądnie będzie ustawić PR1 na maksimum amplitudy sygnału piłokształtnego na wyjściu „SYNCHRO”. Jeśli jako wyjście generatora-wobulatora wykorzystujemy sygnał cyfrowy (wyjście „DIGI 0/5V”), to potencjometr regulacji poziomu sygnału analogowego (sinusoidalnego) można ustawić na minimum. Natomiast jeśli do wysterowania badanego układu używamy wyłącznie sygnału sinusoidalnego, to przed rozpoczęciem pomiarów należy ustawić jego odpowiedni poziom wyjściowy, a wyjście cyfrowe „DIGI 0/5V” można całkowicie „wygasić” w trybie wstępnej konfiguracji przyrządu. Należy tu zaznaczyć, że pomiar poziomu napięcia wyjściowego sinusoidalnego nie jest dostępny w trybie pracy wobulatora. Poziom wyjściowy wobulowanego napięcia sinusoidalnego, po podłączeniu badanego obwodu, warto jest zatem skontrolować za pomocą oscyloskopu. Można też ewentualnie dokonać tego za pomocą woltomierza napięć zmiennych lub wbudowanej w przyrząd funkcji pomiarowej – w trybie generatora, zmieniając ręcznie częstotliwość pracy F w zakresie interesujących wartości.

Podsumowanie

Opisany generator-wobulator DDS powstał jako kontynuacja projektu generatora AVT-3111. Autor projektu ma poczucie, że udało się osiągnąć cel projektowy, którym był rozsądny kompromis pomiędzy: szerokim wachlarzem możliwości technicznych, ergonomią obsługi, względną prostotą wykonania we własnym zakresie oraz niskim kosztem nabycia potrzebnych podzespołów i elementów. Znaczącym atutem opisanego urządzenia, poza dwufunkcyjnością, jest także możliwość alternatywnego zastosowania jednego z dwóch dość szeroko dostępnych na rynku modułów generatorów DDS z układem AD9850. Kontynuacją tego projektu i publikacji będzie projekt trzech sond pomiarowych (jednej liniowej i dwóch logarytmicznych), w oparciu o które bardziej szczegółowo przedstawione zostaną możliwości opisanego tutaj przyrządu oraz sposoby jego wykorzystania w praktycznych zadaniach konstruktorskich i pomiarowych.

Na koniec chciałbym serdecznie podziękować koledze Lucjanowi Bryndzy SQ5FGB za pomoc okazaną przy konfigurowaniu nowej edycji programu KiCAD, którego użyłem do projektowania obu płytek, a także za cenne sugestie dotyczące samego procesu projektowego.

Adam Sobczyk, SQ5RWQ
sq5rwq@gmail.com
sq5rwq.pl

Artykuł ukazał się w
Elektronika Praktyczna
marzec 2017
DO POBRANIA
Pobierz PDF Download icon
Materiały dodatkowe
KIT do tego projektu
Generator DDS na zakres 1Hz…40MHz z wobulatorem, AVT5580
Generator DDS na zakres 1Hz…40MHz z wobulatorem, AVT5580
Generatory przestrajane stanowią ważną pozycję w warsztacie każdego konstruktora. Opisany generator pozwala na komfortową pracę m.in. z urządzeniami...
Zobacz w sklepie

Elektronika Praktyczna Plus lipiec - grudzień 2012

Elektronika Praktyczna Plus

Monograficzne wydania specjalne

Elektronik marzec 2024

Elektronik

Magazyn elektroniki profesjonalnej

Raspberry Pi 2015

Raspberry Pi

Wykorzystaj wszystkie możliwości wyjątkowego minikomputera

Świat Radio marzec - kwiecień 2024

Świat Radio

Magazyn krótkofalowców i amatorów CB

Automatyka, Podzespoły, Aplikacje marzec 2024

Automatyka, Podzespoły, Aplikacje

Technika i rynek systemów automatyki

Elektronika Praktyczna marzec 2024

Elektronika Praktyczna

Międzynarodowy magazyn elektroników konstruktorów

Elektronika dla Wszystkich kwiecień 2024

Elektronika dla Wszystkich

Interesująca elektronika dla pasjonatów