Elektroda.pl
Elektroda.pl
X

Search our partners

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

Za mała częstotliwość fali nośnej (przebiegu trójkątnego) ATMEGA16

xyzboro 23 Feb 2012 19:22 2864 23
Tespol
  • #1
    xyzboro
    Level 9  
    Proszę o pomoc w zwiększeniu częstotliwość fali nośnej, którą jest przebieg trójkątny. Mam kod który porównuje dwa przebiegi sinusoidalny i trójkątny, a na wyjściu generuje przebieg prostokątny. Jest to nic innego jak sinusoidalna modulacja szerokości impulsów PWM do sterowania falownikiem trójfazowym. Wszystko jest napisane w C, a procesor jaki użyłem to ATMEGA16.
    Jednak po sprawdzeniu na oscyloskopie częstotliwości przebiegu trójkątnego wyszło mi niecałe 2 kHz, a potrzebuję co najmniej 6kHz.
    I teraz pytanie do szanownych kolegów, czy da się wyciągnąć coś więcej z tego procesora jeżeli chodzi o ten przebieg czy to jest max??

    Poniżej zamieszczam kod.

    Code: c
    Log in, to see the code




    Dodam, że zmniejszanie ilości próbkowanie trójkąta już próbowałem i za wiele nie pomogło tylko pojawił się większy błąd pomiarowy.
    Dziękuję za każdą pomoc.
  • Tespol
  • #2
    User removed account
    User removed account  
  • Tespol
  • #3
    xyzboro
    Level 9  
    Nie próbowałem bo boje się że nie będzie stabilny, a błąd pomiarowy wzrośnie jeszcze bardziej.
  • #5
    xyzboro
    Level 9  
    dziękuję dondu Twoje wskazówki pomogły i o jakieś 0,5kHz zaczął szybciej generować przebieg. Jednak to i tak jeszcze mnie nie ratuje.

    Poniżej podaję program główny:
    Code: c
    Log in, to see the code
  • #6
    _StinG_
    Level 14  
    Co jest w funkcjach:
    A=amplituda();
    W=wypelnienie();
    T=okres();

    Czy mógł byś wstawić cały kod (np. w formie pliku)?
    To by mogło ułatwić nieco analizę.
  • #10
    xyzboro
    Level 9  
    _StinG_ pisał żebym dał w pliku więc tak zrobiłem.... Ale to chyba nie jest najważniejsze? ;)

    Dodano po 1 [minuty]:

    Code: c
    Log in, to see the code
  • #11
    dondu
    Moderator on vacation ...
    Zawsze można wrzucić tak i tak :)
    Rzucę okiem za parę minut.

    EDIT:
    Czytałem dokładnie pierwszy post, ale opisz proszę w paru słowach co za co odpowiada, poszczególne timery, ADC, które przerwanie jest do czego, itd. ... bo w kodzie tego nie masz.
  • #12
    xyzboro
    Level 9  
    Starałem się jak tylko potrafię żeby opisać poszczególne etapy kodu.
    Ale ogólnie zasada działania jest prosta:
    Deklarujemy dwie tablice sinusa i trójkąta, następnie deklaruję 3 zmienne, które są regulowane on-line. Podczas pracy sterownika możemy regulować amplitudą sinusoidy (od 0 do 5V), dalej możemy również regulować częstotliwością trójkąta (wypełnieniem) poprzez przełączanie odpowiednich zakresów, czyli:
    Code: c
    Log in, to see the code


    dodatkowo jest również możliwa płynna regulacja:
    TCNT2=W;//dodatkowa płynna regulacja częstotliwości.
    Dalej mamy deklarację częstotliwości sinusoidy (okres) którą regulujemy płynnie.
  • #13
    dondu
    Moderator on vacation ...
    Przede wszystkim powinieneś inaczej rozwiązać przerwanie TIMER2_OVF_vect,
    Ono wykonuje się rzadko, ale za to bardzo długo - czy wiesz dlaczego?
    A w tym czasie, masz zablokowane przerwania.

    EDIT:
    Dodatkowo czy jesteś świadomy, z jaką częstotliwością pracuje tak ustawiony ADC?
  • #14
    xyzboro
    Level 9  
    Na wyjściu musiałem zrobić trzy fazy, które są przesunięte o 120st, a następnie unormować przebieg sinusa (okres T) do przebiegu trójkąta czyli ilość próbek 32. Sinus może się tutaj długo wykonywać, ale jeżeli zmniejszę ilość jego próbek to boję się, że te przebiegi troche się rozjadą.

    Dodano po 5 [minuty]:

    tak się zastanawiam czy faktycznie ten sinus i ilość próbek (1021) to nie jest za dużo?

    A i wydaję mi się że częstotliwość ADC to częstotliwość taktowania zegara przez wartość preskalera. Max. może być CK/2.
    Zatem w naszym przypadku ADC to 8Mhz?
  • #15
    dondu
    Moderator on vacation ...
    Zacznijmy od wyjaśnienia i poprawy sprawy ADC.

    xyzboro wrote:
    A i wydaję mi się że częstotliwość ADC to częstotliwość taktowania zegara przez wartość preskalera. Max. może być CK/2.
    Zatem w naszym przypadku ADC to 8Mhz?

    Skąd to info o CK/2?

    Ograniczenia dla zegara ADC to przedział 50kHz-200kHz (o ile dobrze pamiętam) - sprawdź w datasheet
    Ty masz ustawiony preskaler na 8, czyli ADC traktujesz zegarem 2MHz (!)
    Jeżeli tak jest, to ADC pracuje stanowczo poza jego możliwościami.
    Sprawdź program i datasheet.
  • #16
    xyzboro
    Level 9  
    Masz racje dzielnik częstotliwości dla kwarcu 16MHz powinien mieć 128 i tylko ta wartość, bo 16000000/128=125 kHz, a więc mieści się nam w zakresie od 50 do 200kHz. Tylko to chyba sprawie, że częstotliwość trójkąta będzie jeszcze mniejsza;/
  • #17
    dondu
    Moderator on vacation ...
    To pierwszy problem z głowy.

    Teraz drugi - zadałem Ci wcześniej pytanie dot. czy wiesz dlaczego Twoje przerwanie TIMER2_OVF_vect wykonuje się strasznie długo.
    Analizując swój kod podaj przyczyny tego problemu.

    Dodam, że teraz wykonywać się będzie jeszcze dłużej.
  • #18
    xyzboro
    Level 9  
    Pewnie przez to: pgm_read_word, więc funkcja zwraca wartość stałej 16-bitowej? Sugerujesz, że powinno być pgm_read_byte?
  • #19
    dondu
    Moderator on vacation ...
    xyzboro wrote:
    Pewnie przez to: pgm_read_word, więc funkcja zwraca wartość stałej 16-bitowej? Sugerujesz, że powinno być pgm_read_byte?

    Jest coś znacznie gorszego. Zastanów się nad tym fragmentem:

    Code: c
    Log in, to see the code
  • #20
    xyzboro
    Level 9  
    Przez to, że wszędzie tam gdzie pojawia się zmienna A, W, T odnosimy się do funkcji amplituda, wypełnienie, okres, a te wykonywane są od nowa. Ale za bardzo i tak nie wiem do czego chcesz mnie naprowadzić i jak to zmienić żeby było dobrze (jeszcze dłużej).
  • #22
    xyzboro
    Level 9  
    jakieś 100us dla jednej funkcji. Ale czy możesz mi w końcu zdradzić tajemnice czy w ogóle da się podkręcić tą częstotliwość czy chcesz żebym sam doszedł do tego - że się nie da;)
  • #24
    dondu
    Moderator on vacation ...
    Spróbowałem dogłębnie zrozumieć Twój program, ale mam z tym duży problem.

    Timer2 ustawiasz na przerwania w celu pomiaru zadanych potencjometrami wartości.
    Taktowany jest 16MHz / 1024 preskaler = 15.625Hz

    W funkcji przerwania od przepełnienia timera2 zmieniasz mu licznik na odczytaną wartość z potencjometru regulującego wypełnienie:

    Code: c
    Log in, to see the code


    Przy tak skonstruowanym programie, masz baaardzo niepewne momenty przerwań, ponieważ zmieniasz licznik TCNT2, w trakcie zliczania przez niego przy jednoczesnym czekaniu na pomiary (łącznie ok. 300us). To kompletnie pomieszanie z poplątaniem :)

    Reszta kodu (algorytm) niestety jest dla mnie niezrozumiały.
    Nawet przy zmianie o której pisałeś mi na PW, także kodu nie rozumie.

    Dlatego potrzebny jest algorytm jaki chcesz osiągnąć. dokładnie opisujący zależności czasowe itp.
    Sądzę, że z tego samego powodu, nikt inny za ten temat się nie wziął :)