logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATmega32][C] - generator DDS ustawienie częstotliwości

piecyk_se 23 Sie 2012 15:00 1809 5
  • #1 11237641
    piecyk_se
    Poziom 10  
    Witam.
    otóż tworzę prosty generator na ATmega32 i 8-bitowym przetworniku C/A. Niestety nie potrafię regulować częstotliwości pracy. Nie wiem jak to zrobić. Większość przykładów znalazłem w Asemblerze a ja piszę w C. Chodzi o to że posiadam tablicę z zapisanymi próbkami. I częstotliwość jaką potrafię uzyskać to (fzeg/(2^8))*aku. Nie wiem jak ją zmniejszyć. Próbowałem dać delay`a ale sygnał wygląda nie ciekawie. Jak najlepiej to zrobić?

    Z góry dziękuję za pomoc.
    P.
  • #3 11237851
    piecyk_se
    Poziom 10  
    schemat prosty do portów I/O podłączony przetwornik C/A. Sygnał się generuje ale o jednej częstotliwości. Kod odpowiedzialny za generowanie:

     for (int i=0;i<256;i++)
    {
    PORTA=(SIN[j/256]);
    j=j+aku; 
    }


    zastanawiałem się czy po wzroście akumulatora nie dać funkcji delay. ale jak pisałem wcześniej nie daje to ciekawego efektu. Jeszcze będę musiał pominąć for bo zajmuje za dużo cykli.
  • #4 11238002
    LordBlick
    VIP Zasłużony dla elektroda
    Moja rada jest jedna - po inżyniersku - zapoznać się dokładnie z:
    - Notą katalogową, zwłaszcza jeśli chodzi o Timer i przerwania.
    - Bogactwem biblioteki avrlibc.
    - Oczywiście wujek Google też na pewno coś wie... ;)
    Sinusa wrzucić do tabeli i w przerwaniu np. CTC wyrzucać próbkę. Liczenie co chwilę sinusa w mikrokontrolerze to nie jest najlepszy pomysł.
    Edit: Nie zauważyłem, że czytanie z tablicy już mamy... ;)
  • #5 11238085
    piecyk_se
    Poziom 10  
    ja nie liczyłem. SIN to biblioteka która ma 256 próbek a tam jest dodany akumulator fazy aby nieco zwiększyć częstotliwość. a o przerwaniach nie pomyślałem a faktycznie może być dobre rozwiązanie. zaczynam czytać o CTC. myślałem na początku aby co każdą próbkę wsadzić opóźnienie ale nie wygląda to ładnie.
  • #6 11238689
    Andrzej__S
    Poziom 28  
    piecyk_se napisał:
    Większość przykładów znalazłem w Asemblerze...

    Nie zastanawiałeś się, dlaczego? Kod w C jest zwykle mniej optymalny, przez co nie daje się uzyskać tak dużych częstotliwości, jak w przypadku asm.
    piecyk_se napisał:
    Jeszcze będę musiał pominąć for bo zajmuje za dużo cykli.

    No to jeżeli zamierzasz przerzucić wystawianie próbek do przerwania timera, to jednak radziłbym napisać obsługę w assemblerze, lub przynajmniej użyć atrybutu ISR_NAKED (ze świadomością, co ten atrybut oznacza), bo sam prolog i epilog obsługi przerwania generowany przez kompilator C zajmie pewnie więcej niż pętla for.

    Tak czy inaczej trzeba mieć też świadomość, że przeniesienie wyprowadzania próbek do przerwania timera zmniejszy maksymalną częstotliwość możliwą do uzyskania, choćby ze względu na takty potrzebne na wejście i wyjście z przerwania (zwykle trzeba też odłożyć przynajmniej SREG na stos). Z kolei umieszczenie kodu w pętli głównej programu (lub we funkcji) nastręcza problem z uzyskaniem równych odstępów czasowych pomiędzy próbkami i znacznie ogranicza możliwości wykonywania przez mikrokontroler innych operacji poza generowaniem przebiegu.

    Sądząc po fragmencie kodu, jaki przedstawiłeś, zmienne j i accu są typu uint16_t. Jeśli chcesz uzyskać mniejsze częstotliwości (i przy okazji większą rozdzielczość regulacji częstotliwości) użyj typu uint32_t. Oczywiście wtedy obliczenie indeksu wyprowadzanej próbki należy zmienić z SIN[j/256] na SIN[j/16777216] lub może lepiej na SIN[j>>24]. Wprawdzie taka zmiana też spowoduje ograniczenie maksymalnej częstotliwości, ale jeśli użyjesz wtedy zmiennej accu równej 1, częstotliwość będzie naprawdę bardzo mała. Bardziej optymalnym rozwiązaniem byłoby zastosowanie zmiennej 24-bitowej, ale to w C będzie trudne.

    EDIT:
    piecyk_se napisał:
    myślałem na początku aby co każdą próbkę wsadzić opóźnienie ale nie wygląda to ładnie.

    Dodam jeszcze, że jeśli próbujesz zmieniać częstotliwość poprzez zmianę odstępów czasowych pomiędzy próbkami, to przestaje to być DDS, gdyż jej podstawową ideą jest zmiana częstotliwości poprzez zmianę kroku, o jaki zmienia się faza w jednostce czasu.
REKLAMA