Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Atmega328p] [C] - Żle odmierzana czas, zła konfiguracja timera?

10 Kwi 2013 09:38 2925 14
  • Poziom 9  
    Witam.

    Mam układ 3 grzałek połączonych w trójkąt do 3-fazowej sieci, każdy triak jest włączany optotriakiem, podłączonym do pinów wyjściowych expandera. Pomiędzy wszystkie 3 fazy podpięte mam detektory przejścia przez 0 ( Link ) które podpięte są przez transoptory do wejścia expandera. Expander generuje przerwanie przy każdej zmianie pinu wejściowego (stąd też takich przerwań w moim układzie jest dokładnie 600 na s), każde przerwanie jest obsłużone w µC ( każdy triak ma przypisany swój detektor, więc na każdym opadającym zboczu przerwania wyłączam odpowiedniego triaka ) i ta część działa cacy ;)
    Problem pojawia się dopiero kiedy chcę włączać triak. Mój sposób na włączanie tego jest następujący.
    Najpierw odmierzam czas opóźnienia (np połowę sinusoidy od przerwania na L1), następnie włączam triaka na L1. Następnie aby każdy triak był włączony na tym samym odcinku sinusoidy muszę zmienić czas przerwania na dokładnie 1/3 sinusoidy i skakać po fazach z L1 na L3 z L3 na L2 i z L2 na L1...
    Widać to dość dobrze na obrazku
    A- początkowe opóźnienie
    B- stały czas 1/3pi okresu sinusoidy
    na górze są narysowane przerwania z detektorów przejść przez 0
    [Atmega328p] [C] - Żle odmierzana czas, zła konfiguracja timera?

    do odmierzania czasu wykorzystuję timer1. Wartość OCR1A obliczam ze wzoru OCR1A = (t*F_CPU/preskaler), gdzie t=1/3pi => 3.(3)ms
    F_CPU = 14745600
    OCR1_DEF = 6144, 1/3pi

    Kod: c
    Zaloguj się, aby zobaczyć kod


    obsługa przerwania timera1

    Kod: c
    Zaloguj się, aby zobaczyć kod


    aktualnaFaza jest zmienną przechowującą fazę na której timer ma włączyć triaka.

    Niby wszystko ok. ale widać że żarówka (która póki co służy mi jako zamiennik grzałki ;) ) nie świeci jednostajnie tylko cały czas przygasa dochodzi, aż do momentu dojścia do "końca" sinusoidy i zapala się pełnym światłem i znów przygasa...

    Próbowałem zmieniać wartość timera ale niestety nic to nie daje (uzyskuję mniej więcej równe świecenie, ale po chwili albo zaczyna gasnąć albo świecić lepiej, albo chwilę gasnąć i chwilę świecić mocniej :D )
    Kiedy w obsłudze przerwania detektorów przejścia przez 0 umieściłem licznik liczący do 600, który po każdym zliczeniu wysyłał czas po RS232 do kompa i to samo zrobiłem z timerem okazało się że timer po ok. 10 min jest opóźniony o prawie 1 s w stosunku do licznika przerwań od detektorów...

    Siedzę już nad tym od kilku ładnych chwil i nie mogę dojść do tego dlaczego triaki nie włączają się zawsze w tym samym miejscu. Mam nadzieję że dobrze nakreśliłem mój problem.
    Pozdrawiam zawisza
  • Specjalista - Mikrokontrolery
    Ten if możesz sobie spokojnie darować, ale bez pokazania większej części kodu trudno zgadywać, co zepsułeś.

    if (OCR1A != OCR1A_DEF )

    - obliczenie warunku zajmuje więcej czasu niż zapis nowej wartości.
  • Poziom 9  
    jedyne co mogę jeszcze dołożyć to

    definicja struktury
    Kod: c
    Zaloguj się, aby zobaczyć kod



    funkcja pomocnicza

    Kod: c
    Zaloguj się, aby zobaczyć kod


    obsługa przerwania INT0
    Kod: c
    Zaloguj się, aby zobaczyć kod


    definicje funkcji obsługi expandera
    Kod: c
    Zaloguj się, aby zobaczyć kod





    tą są praktycznie wszystkie używane funkcje podczas sterowania triakami. Pętla główna wyświetla temperaturę na LCD-ku żadna funkcja oprócz podanych nie używa atomic_block. Przerwania od ADC nie wpływają na działanie układu stąd też nie zamieszczam tutaj kodu odpowiedzialnego za nie. I dzięki za podpowiedź o if'ie ;)

    Pozdrawiam zawisza
  • Poziom 19  
    Pokaż fragment gdzie masz definicje wyliczania stałej OCR1A_DEF; :)
  • Poziom 9  
    To jest po prostu stała obliczana ze wzoru

    OCR1A = (t*F_CPU/preskaler)
    gdzie:
    t= pi/3 = 3.(3)ms
    F_CPU = 14745600
    stąd OCR1_DEF = 6144

    a tu definicja ;)
    Kod: c
    Zaloguj się, aby zobaczyć kod
  • Poziom 19  
    Wzór na czas pomiędzy przerwaniami na podstawie datasheeta uwzględnia jeszcze jedną małą rzecz - wartość 1. Po przekształceniu otrzymujemy:

    $$t = \frac{t \cdot F_{CPU}}{N} - 1$$

    Przy założeniu że
    $$t = \frac{\pi 20}{3} [ms]$$

    Wartość do timera powinna wynosić 6143.

    Inna sprawa jest taka, że zacytyhę kolegę BoskiDialer:
    Cytat:

    W trybie CTC wartość timera jest zerowana, gdy TCNTx jest równe OCRxA. Nie pojawia się tutaj sprawdzenie w relacji większy/równy. Tak więc jeśli w danym momencie OCRxA jest równe 100, TCNTx 98 i w tym momencie zostanie wpisane do OCRxA wartość 96 to nie zostanie spełniony warunek dla TOP, timer będzie się zwiększał aż do 65535 (długa przerwa) kiedy to się przepełni (powrót do normalnej pracy). Rozwiązanie - po zaktualizowaniu OCRxA sprawdzić czy TCNTx jest większe lub równe - jeśli tak, to wpisać tam 0.

    Takie niefortunne wpisanie wartości do timera bądź jego niewłaściwy start może powodować problemy. Miałem już kiedyś taką sytuację. Pokaż funkcje timer1_init() i timer1_on(). Pozdrawiam
  • Poziom 9  
    timer1_on() wygląda tak

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Nie zeruje tu TCNT1 bo nie mam takiej potrzeby, bo timer włączam tylko 1 raz, a po inicjalizacji zeruje licznik, później wartość OCR zmienia się tylko w pierwszym przerwaniu po włączeniu timera, więc o takiej sytuacji jak wspomniałeś nie może być mowy.


    A o tej jedynce faktycznie zapomniałem :) niestety zmiana wartości w dalszym ciągu nie pomaga..
  • Poziom 2  
    cszawisza napisał:
    Kiedy w obsłudze przerwania detektorów przejścia przez 0 umieściłem licznik liczący do 600, który po każdym zliczeniu wysyłał czas po RS232 do kompa i to samo zrobiłem z timerem okazało się że timer po ok. 10 min jest opóźniony o prawie 1 s w stosunku do licznika przerwań od detektorów...

    Siedzę już nad tym od kilku ładnych chwil i nie mogę dojść do tego dlaczego triaki nie włączają się zawsze w tym samym miejscu.


    Wg mnie przyczyna jest prosta: obliczenia wykonałeś dla częstotliwości sieci równej 50 Hz i częstotliwości oscylatora układu równej 14745600 Hz, tyle że
    1. częstotliwość w sieci niekoniecznie wynosi równiutkie 50 Hz
    2. kwarc praktycznie nigdy nie pracuje z częstotliwością nominalną
    3. ponieważ 1 i 2, a nie synchronizujesz timera z siecią, to się rozjeżdżają

    Zmieniłbym tryb pracy timera na normalny i zerował licznik timera w co szóstym przerwaniu od detektorów, a w każdym przerwaniu timera (TIMER1 COMPA) ustawiał kolejny moment wystąpienia tego przerwania (OCR1A) modulo czas trwania jednego okresu sieciowego.
  • Poziom 41  
    Obecnie 50Hz jest dokładne, można korzystać do "napędzania" zegarków. Falsifier ma nieaktualne informacje.
  • Moderator Mikrokontrolery Projektowanie
    Dar.El napisał:
    Obecnie 50Hz jest dokładne, można korzystać do "napędzania" zegarków. Falsifier ma nieaktualne informacje.


    IMHO to dokładna jest średnia częstotliwość, chwilowe odchyłki mogą być znaczne.
  • Poziom 41  
    Macie rację, do odmierzania krótkich odcinków czasu nie nadaje się częstotliwość sieci. Do zegarka wystarczy.
  • Poziom 9  
    Ostatnio w końcu dopadłem oscyloskop i mogłem pooglądać przebiegi napięć i powiem szczerze że wygląda to dość dziwnie :)

    Po pierwsze częstotliwość sieci i częstotliwość przerwań = 50.00Hz a jednocześnie można zaobserwować dość szybkie przesuwanie się obydwóch tych sygnałów między sobą :) i co jeszcze ciekawsze, widać wyraźne przeskoki w przesunięciu fazowym pomiędzy fazą a moim przerwaniem. Zachowuje się to tak jakby 100 okresów miało dobrą częstotliwość a 101 miał 51 zamiast 50Hz. Niestety nie udało mi się zaobserwować tego krótszego okresu.
    Póki co wiem że muszę po prostu wymyślić sposób na synchronizację sygnału sterującego z siecią.

    Jeszcze do kolegi falsifiera.
    tak jak Krokus22 napisał, miałem błąd w obliczeniach OCR (było większe o 1 od wartości która miała być) stąd też mógł wynikać problem o którym pisałem.

    Dzięki za pomoc ;)
    Pozdrawiam
  • Poziom 39  
    Tak na marginesie odnośnie częstotliwości sieci - jest ona korygowana dziennie. Tzn jeśli w którymś momencie dnia z jakiegoś powodu częstotliwość spadnie poniżej 50Hz to później jest ona celowo podnoszona do góry aby całkowita dobowa ilość cykli wynosiła 4320000 cykli. Dlatego do zegarka można wykorzystać sieciowe 50Hz.
  • Poziom 9  
    Zmieniłem uC na ATXmege i zastosowałem osobne przerwanie na każdą fazę, zrezygnowałem również z expandera