Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

generowanie sinusa w '51 na wyjściu DAC w języku C

mototest 24 Jul 2006 18:41 3565 27
Optex
  • #1
    mototest
    Level 19  
    Witam kolegów

    czy ma ktoś jakiś prosty wzór na wygenerowanie sinusa na wyjściu DAC
    w procku '51 w języku C ? częstotliwość ma być maksymalna jaką wyciągnie procek, ale wartości Vpp czyli max. i min. napięcia sinusa chciałbym regulować programowo, w zasadzie wymyśliłem taki wzór ale jest dość skomplikowany, myślę że istnieją jakieś proste sposoby...

    Bogdan
  • Optex
  • #2
    Zaquadnik
    Level 27  
    Zapisujesz w pamięci próbki sinusa i kolejno podajesz je na wyjście. Robisz na przykład 1000 próbek. Dla najniższej częstotliwości podajesz każdą kolejną, dla wyższej, co drugą próbkę, aż do najwyższej, gdzie podajesz tylko 2 próbki. Taki mikrokontrolerowy DDS ;) Sposób może pamięciożerny, ale prosty :)
    Pozdrawiam :)
  • #3
    morph13
    Level 25  
    Tablica i odczyt z niej to najlepsze i najszybsze (w działaniu) rozwiązanie.
    Przejrzyj moje posty jak pamietam umieściłem gdzieś nawet tablicę do zassania.
    Tablica 256 próbek lub jej wielokrotnośc to sprawdzone rozwiązanie ze względu na to, że rej w 51 są 8 bitowe co po osiągnięciu wartości maksymalnej spowoduje "automatyczne przekręcenie" sie licznika i skok (wskazanie) do (na) wartośc poczatkowa w tablicy. Nie trzeba kombinoważ z wykryciem 1000 próbki lub tp a z tym zawsze się wiąże, że "wystapi ząbek" w generowanym przebiegu. Troszę namieszałem ale wiadomo o co chodzi dla cłowieka który siedzi w 51 lub AVR.

    Ta główna procedura generacji powinna być w asemblerze dla osiągnięcia max prędkości (częstotliwości) reszta spokojnie w C.
  • Optex
  • #4
    mototest
    Level 19  
    no tak ale ja potrzebuję rozdzielczość amplitudy regulować z dokładnością 12bit czyli 4095 próbek, tyle próbek wpisywać do tabicy to chyba zakwitnę... :) może jest jakiś program który generuje takie tablice ??

    B.
  • #5
    bis
    Level 21  
    Rozdzielczość amplitudy (wartość próbek) nie ma nic wspólnego z ilością próbek które będziesz wysyłał na jeden okres. Dla każdej założonej amplitudy trzeba osobnej tablicy, jeżeli chcesz zmieniać amplitudy musisz mieć ich wiele(dużo ROM-u) albo generować je dynamicznie (wtedy potrzeba RAM-u). mozna też generować próbki dynamicznie (przeskalowując jeden stablicowany "idealny" przebieg) (wtedy maksymalna czestotliwość zadawania próbek zależeć będzie od szybkości algorytmu skalowania). Każda z metod stawia trochę inne wymagania dla procesorka, albo duzy ROM, albo ponadstandardowy RAM, albo procek o dużej szybkości. Nie piszesz nic jaki DAC chcesz użyć, a z jego parametrów może wyniknąć realna maksymalna częstotliwość do uzykania. Jezeli ma on wejście równoległe 12 bitowe to można dołaczyc go do szyny adresowej (po zatrzaśnięciu multipleksowanej młodszej części) i jako danych do DAC używać adresu do pamięci zewnętrznej w cyklu zapisu, to może przyspieszać procedurę podawania danych (wtedy można też rozważyć jakiś algorytm "przyrostowej" generacji kolejnych próbeK na rejestrze DPTR). Podaj dokładniej jakie chcesz uzyskać parametry przebiegu na wyjściu DAC, jaki DAC. Z tego może się okazać że sprawa jest nieosiągalna na 51' albo że jest to trywialnie proste, albo że z jakimiś kompromisami uda się to zrobić.
    bis
  • #6
    Zaquadnik
    Level 27  
    Wygenerowanie tablicy próbek ? Żaden problem :] Albo Open Office Calc, albo Excel i dla 4096 próbek wrzucasz wzorek 2047*(sin((2k*pi)/4096)+1), gdzie k=0...4095 :) A z Excela możesz te próbki przekopiować do pliku .c, do tablicy ;) Wzór podałem dla przetwornika unipolarnego. Dla bipolarnego nie dajesz +1 za sinusem :]
    Pozdrawiam :)
  • #7
    mototest
    Level 19  
    no wszystkie informacje są przydatne, chcę użyć przetwornika wbudowanego w ADUC842 ma czas konwersji 2us ,częstotliwość jaka będzie max. zobaczymy wystarczy mi w granicach 5-10kHz
    wolałbym to zrobić w RAMie zrobić jeden idealny przebieg i obliczać amplitudę na poczekaniu ,amplituda musi się zwiększać w dwie strony w dół i w górę jednakowo, wstępnie jest środek na 2,5V potem amplituda się rozszerza, problem jest w tym że muszę mierzyć amplitudę tego sinusa z dokładnością do około 1mV więc dlatego potrzebuję amplitudę o tej rozdzielczości.


    No sinus w excelu wyszedł elegancki, może ten wzór wystarczy zaimplementować w kodzie C i będzie działać ?? tylko dołożyć obsługę zakresu liczby "k" ,ale chyba sie nie da bo czy da się zmienić tą amplitudę...
  • #9
    mototest
    Level 19  
    na pewno nie wyrobi się w 2us , byle da się wygenerować te 5kHz co daje wysyłanie próbek co 200us więc powinno być dobrze, muszę sie pobawić tym wzorem żeby jakoś regulować amplitudę wysyłania sinusa jeśli to będzie realne
  • #10
    bis
    Level 21  
    Dla 5kHz to 200us jest czasen jednego okresu tej sinusoidy, w tym czasie musisz wysłać kilkadziesiąt ( ile to zależy od jakości tego sinusa jaki chcesz uzyskać) próbek do DAC-a. Przy tym procku jest to całkiem możliwe, ma miejsce na tablice(2K XRAM), jest szybki (50ns na instrukcję dla 20MHz). ograniczeniem jest 2us (czyli 40 rozkazów procka) czas konwersji DAC. Z tego wynika że dla przebiegu 5kHz maksymalnie możesz mieć 100 punktów interpolacji, a dla 10kHz 50 punktów na cały okres sinusa. Rozwiązanie z tablicami i program z dokładnym wyliczeniem czasu wykonywania (albo nawet dobrze zoptymalizowany kod z przerwaniem od zegara) powinno się udać. A wartości trzeba wyliczać dynamicznie w programie procka(bo są zależne od amplitudy jaką chcesz uzyskać), wstawiać do tablicy w XRAM i wtedy odpalać generownie przebiegu.
  • #13
    mototest
    Level 19  
    chodzi mi o dokładne ,ja chcę regulować amplitudę sinusa proporcjonalnie do napięcia pobranego z wewnętrznego przetwornika ADC ale przeskalowaną czyli nie taką samą jak na ADC, na ADC mam potencjometr i według niego chcę zwiększać amplitudę
  • #14
    morph13
    Level 25  
    Wypowiedz oprę o tablicę w rozdzielcości 8bitów. Poprostu pobierasz wartość z tablicy odejmujesz zadaną wartość od pobranej próbki pamietając jeśli wynik bedzie "ujemny" zapisujesz wartść "0"(wartośc min półówki ujemnej to 0 a max półówki dodatniej to 255 - środek wypada na 127).
    Od razu wyjaśnię, że jeśli masz A/C 12 bitowy to nie licz na taką rozdzielczość regulacji, od razy przesuń wynik konwersji o 4 pozycje w prawo do wartości 8 bitowej a te 4 "stracone" bity odetną wszystkie szumy przetwornik i inne "niestabilności samego potencjometru" lub ręki operatora.
  • #16
    Zaquadnik
    Level 27  
    Jeśli piszesz w C zrób tablice int-ów, tylko pamiętaj, zeby nie przekraczać wartości 4095. Co do regulacji amplitudy, to robisz tak. Pobierasz wartość z tablicy i dzielisz ją przez wartość zależną od napięcia, oczywiście dzielenie będzie z pewnym przybliżeniem. Dzielnik ustawiasz w taki sposób, że im ma być niższa amplituda na wyjściu, tym większy dzielnik.
    Pozdrawiam:)
  • #17
    mototest
    Level 19  
    w taki mazie ten dzielnik będzie ułamkiem, spróbję się pobawić,
    myślę że dość mocno mi to spowolni sinusa (dzielenie float) ale może mi wystarczy, widziałem taką tablicę do generowania sinusa dwumymiarową w jednym wymiarze bity ADCL a w drugiej bity ADCH (ze wzgldu na 12 bit) ja musiałbym też stworzyć taką tablicę tylko jak to się ma do dzielenia przez dzielnik żeby obliczać bity L i H ?? bo przeliczanie na jedną liczbę i potem spowrotem na H i L jeszcze dodatkowo to wszystko spowolni, no chyba że procek sie wyrobi z tym wszystkim... jego max częstotliwość rdzenia to 16Mhz
  • #18
    morph13
    Level 25  
    mototest wrote:
    tylko że ja potrzebuję właśnie rozdzielczość 12bitową na wyjściu DAC potencjometr z ADC jest 20 obrotowy więc dokładny, więc nie mogę okrajać wyniku do 8 bitów


    OK, skoro tak twierdzisz. Pamiętaj jednak, że jeśli Vref dl A/C będzie miało 5V to dla 12bitów rodzielczość wyniesie 1,22mV a przy Vref 2,5V (często stosowane) da 0,61mV. A są to już wartości nakładające się na "szum cyfrowy" wystepujący w lini zasilania (zakłócenia wynikające z samej pracy jednostki centralnej czyli uP).
    Możesz dać i potencjometr 100 obrotowy i filtrację kondensatorową napięcia z suwaka potencjometru a tego faktu i tak nie przeskoczysz. To ociera się już o układy PROFESJONALNE.

    Tak się składa, że "siedzę w tym temacie" i musze Cie uprzedzić, że pewne fakty szybko sprowadą Cie na "Ziemię logicznego i praktycznego myślenia". - Poprostu założenia swoją droga a praktyka swoja.

    Sprawa rozdzielczośći 8 bitowej, moją wypowiedz oparłem własnie o nią bo niektórzy mają problemy ze zrozumieniem "istoty sprawy" gdy wykraca ona poza 8 bitów a chodzilo mi o udzieleni odpowiedzi na Twoje pytanie dotyczące metody cyfrowej regulacji amplitudy.

    Wątek ma już pare dnia więc czy wykonałes już jakieś testy lub układ prototypowy ???? Mające sprawdzić organoleptycznie daną koncepcję - generacja w oparciu o wyliczenia ze wzoru czy zczytywanie wartości z tablicy (8, 12, 16 ... bitów to mało istotne), metoda cyfrowej regulacji itp.

    Pamiętaj, że nawet procesory DSP korzystają z "wartości stablicowanych" i mało kiedy liczą sin, cosin .... wg jakiegoś tam wzoru.
    A mogę coś na ten temat powiedzieć bo bawię się DSP a konkretnie TMS320F2401 i nie tylko. Zapraszam do działu "DSP i Transmisja".


    Napisz też konkretnie, co "budujesz", generator, sterownik .......


    Życzę powodzenia.
  • #19
    mototest
    Level 19  
    sprawa jest taka że muszę "wyprodukować" fragment urządzenia które uległo spaleniu,a zakup modułu jest kosmicznie drogi wiec próbuję pomóc znajomemu, ten sinus potrzebuję do odczytu wartości z przemysłowego potencjometru indukcyjnego, jest tam taka druga maszyna w której zmierzyłem wszystko co sie da i tam jest voltomierz niby napięcia z tego potencjometru który ma dokładność 1mV stąd te 12bit, ten oryginalny procek produkuje 2 sinusy przesunięte w fazie o 180 stopni i wpuszczany jest na zewnętrzne nogi potencjometru z tym że ten odwrócony w fazie ma regulację amplitudy od 2-3.5Vpp (pomiędzy szczytami amplitudy na 2V jest dół sinusa na 3,5V góra sinusa) przy skręconej gałce na minimum do 0.5-4.5Vpp(0.5V dół sinusa 4.5V góra sinusa) przy skręconej na max., z kolei na środkowej nodze pojawia się sinus z amplitudą zależną od gałki potenc. i procek tak długo zwiększa ten sinus odwrócony w fazie aż na "suwaku" pojawi sie 0V (jak dwa sinusy są o tej samej amplitudzie to na "suwaku" jest 0V) (gałka przestraja indukcyjność tego pot.),teraz gdy jest 0V na suwaku to wartość tej amplitudy którą generuje procek wyświetla na voltomierzu, no to tyle na temat działania ,tablicę z wzorcowym sinuem zrobiłem w excelu według wzoru kolegi, ale nie potrafię jej przeskalować, masz jakiś sposób na to, jakis wzór ?
  • #20
    morph13
    Level 25  
    No to teraz sprawa jest jasna a nie zbędne kręcenie się w kółko.

    Przetwornik C/A w oryginale był na drabince rezystorowej R2R czy na scalaku ??.

    Rozdzielczość C/A 8 bitowa do generacji sinusa wystarczy (łatwiej to zaimplementowac programowo), ważniesza jest tu 12 bitowa rozdzielcość A/C o czym wspomniałeś. Należy zająć sie regulacją amplitudy ale z innej strony.
    Zakładam, że przetwornik C/A jest na "scalaku". Regulację amplitudy robisz przez zmianę napięcia Vref przetwornika a do tego możesz wykorzystać "potencjometr cyfrowy" połaczony z WO (wzm. operacyjny) o wzmocnieniu x 1 (niekonieczne ale tak zakładam) a z jego wyjścia napiecie podajesz na Vref.

    Generacja przebiegu w "przeciwfazie" nie jest problemem. Dla tablicy 256 bitowej z 8 bitowa rozdzielczościa odczytaną wartośc ładujesz do jednego przetwornika bezpośrednio a do drugiego wartość zanegowaną.
    Inne rozwiązanie to jeden przetwornik C/A i negacja przebiegu na WO (dość proste rozwiązanie) dla uzyskania przesunięcia o 180 stopni.

    Regulacja amplitudy od 2-3.5Vpp czyli amplituda zmienia się w zakresie tylko 1,5Vpp jak dobrze zrozumiałem.......
    Jeśli tak, to robisz przesównik poziomu napięcia stałego na WO który przy Uwej = 0V daje na wyjściu 2V wtedy napięcie Vref powinno przyjmowac wartość od 0 do 1,5V i rozdzielczość tego napięcia jest uzaleznona od rozdzielczości potencjometru cyfrowego, zalecane aby potencjometr miał przynajmniej 512 możliwych "nastaw wartości".

    Dodatkowo jak ma być częstotliwość przebiegu sinusoidalnego ??
    Jeśli dość wysoka to trzeba jego generację zrobić w pętli głównej a to komplikuje reszte regulacji, jesli jednak nie to robisz to w przetwaniu TIMER-a a w głownej całość regulacji amplitudą.

    Jeśli zrozumiałeś o co mi chodzi (bo mogłem namieszać) to powinieneś sobie już poradzić.
  • #21
    mototest
    Level 19  
    no z tym Vref mnie zaskoczyłeś , żeczywiście jest to ciekawe rozwiązanie,
    w oryginale wszystko jest zrobione w jednym procku plus 2 operacyjne na wyjściach sinusa z procka, ja chcę zrobić tak samo, ale widzę że brakuje mi jednego DACa bo jednym generuję sinus wzorcowy, drugim sinus regulowany a trzecim powinienem regulować Vref i byłby problem rozwiązany, wiec muszę poszukać innego procka (w oryginale był Philips ale z zakodowanym symbolem) albo musze sinus wzorcowy zrobić na innym układzie ,ale z kolei nie będzie zsynchronizowany z drugim sinusem, więc nie da się, one muszą być dokładnie przesunięte o 180stopni w fazie, ten potencjometr cyfrowy raczej odpada, nie spotkałem 12 bitowych a taką potrzebuję rozdzielczość amplitudy sinusa regulowanego , sinusy obydwa zrobiłem w pętli main() i działają ładnie
    częstotliwość w oryginale była 10kHz ale myślę że wystarczy o wiele niższa, myślę ze najlepszym rozwiązaniem jednak będzie procek z co najmniej trzema DACami... albo jeszcze analogowo spróbuję zrobić regulację Vref w zależności od "suwaka" tego pot. indukcyjnego ,to też może być sensowne rozwiązanie
  • #22
    morph13
    Level 25  
    mototest wrote:
    ....w oryginale wszystko jest zrobione w jednym procku plus 2 operacyjne na wyjściach ...


    W takim razie pomyśl o ADuC812 lub 814

    mototest wrote:
    ..... one muszą być dokładnie przesunięte o 180stopni w fazie ....

    Nie widze z tym problemu przy przetworniki "zewnętrznym" podwójnym D/A bo są scalaki z specjalnym wejście zatrzaskowym, które w tym samym czasie wystawia zapisane wczesniej wartości do pszczególnych kanałów jednoczesnie.

    Metodę cyfrowej regulacji amplitudy opisałem wcześniej.
  • #23
    mototest
    Level 19  
    pojawił się problem, otóż wszystko zrobiłem jak w oryginale czyli poziomy amplitud sinusa i ich położenie na osi napięcia i zrobiłem sobie układ próbny na stole podłączając potencjometr do Vref który reguluje amplitudą jednego sinusa , no i nie działa to jak w oryginale, otóż w oryginale sinus się spłaszcza i rozszerza w dwie strony równocześnie ,a regulując Vref tylko się spłaszcza do zera lub przesuwa cały góra dół w zależności gdzie go umieszczę na osi napięcia , wnioskuję w takim razie że w oryginale ten sinus jest przeliczany w programie i nie może być zależny od Vref...poza tym nie wiem jak to zrobili ale oni wyciągają 10kHz przy dwóch sinusach na DACach i przy kwarcu 8Mhz , a ja korzystając z bardzo okrojonej tablicy 8bitowej wyciągam jedynie połowę tej częstotliwości ... gdzieś tu jest problem...
  • #24
    morph13
    Level 25  
    Nie ma problemu.
    W takim razie w tablicy zakodowali nie jeden kompletny przebieg tylko np dwa co daje przy tych samych parametrach głównej pętli generacyjnej przebieg o x 2 częstotliwości.
    Wynika też z tego, że przy zmianie amplitudy zmienia się tez częstotliwość - pytanie tylko czy NAPEWNO !!!!. Sprawdzałeś to miernikiem częstotliwości ??
    Może to być tylko złudzenie widziane na oscyloskopie przy zmieniajacej sie amplitudzie.

    Piszesz, że 10kHz przy kwarcu 8MHz jest to możliwe przy procesorze ze zredukowaną liczbą cykli maszynowych, nie 12 dla standardowej '51 tylko np 6 lub 4 co daje ogromne przyspieszenie jak dla procka 8 bitowego.
  • #26
    mototest
    Level 19  
    nie ,częstotliwosc jest stała, mam oscyloskop cyfrowy i widzę dokładnie wszystkie parametry, mam problem jedynie z rozciąganiem amplitudy sinusa w górę i w dół naraz, próbowałem w excelu różnych symulacji i nic z tego, częstotliwosc sinusa wyciągnąłem przy 32 próbkach na okres 7,5kHz co już mnie zadowala chociaż sinus nie jest rewelacyjnie piękny, ale na razie do prób wystarczy, pomóźcie z tym rozciąganiem sinusa....
  • #27
    lechoo
    Level 39  
    Zmianę amplitudy najprościej i najlepiej zrealizować przy pomocy przetwornika C/A mnożącego.
  • #28
    mototest
    Level 19  
    ale je chcę wykorzystać ten DAC w procku, nie zewnętrzny dlatego potrzebuję jakiś wzór matematyczny który mi to zrobi, wydaje mi się że mnożenie zwiększy amplitudę od zero w zwyż a nie w dwie strony, ja mam sinusa na poziomie 2,7V (środek) i jego minimum to 2V ponad zerem i maksimum 3,5V i potrzebuję zwiększać 3,5V i jednocześnie zmniejszać 2V

    Dodano po 44 [minuty]:

    no w końcu znalazłem ten wzór po wielkich bojach wygląda tak :
    dla 32 próbek
    DAC =16*((SIN((2*PI*nr próbki)/32)*rozciągnięcie)+1)
    zmieniając parametr rozciągnięcie sinus się rozciąga w dwie strony
    z tym że parametr rozciągnięcie ma skok co 0,01 to tak jakby dodawać procent, nr próbki zawiera sie od 0-32,
    teraz jest problem jak to zoptymalizować bo obecnie procesor to liczy wiecznie, trzeba by zrobić z tego jakąś tablicę i ewentualnie przez coś pomnożyć, zasugerujcie coś...