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

Stabilizacja napięcia boost converter sterowanego atmegą

kamil94goldman 08 Wrz 2017 19:17 1212 4
REKLAMA
  • #1 16688778
    kamil94goldman
    Poziom 3  
    Posty: 261
    Pomógł: 5
    Ocena: 3
    Witam,

    Zrealizowałem przerywacz podwyższający napięcie z 5 V do 10 V, który jest sterowany atmegą a program napisałem w języku C, lecz mam problem ze stabilizacją napięcia wyjściowego przy zmianach obciążenia. Napięcie przy dużych zmianach obciążenia potrafi wzrosnąć na chwile nawet o 10 V.

    Sterowanie wypełnieniem PWM zrealizowałem w przerwaniach poprzez zwiększanie "+/- 1", chciałem zrealizować programowy regulator PID lecz nie mogę sobie z tym poradzić. Robiliście może coś podobnego?

    Tutaj schemat układu:
    Stabilizacja napięcia boost converter sterowanego atmegą

    Atmega działa z f = 16 MHz a PWM zaprogramowałem z częstotliwością f = 32 kHz. Sterowanie mosfetem odbywa się poprzez driver IR2121. Zwiększanie/zmniejszenia wypełnienia (wartości zadanej) zrealizowane jest za pomocą dwóch przycisków. Napięcie wyjściowe mierzone jest poprzez przetwornik w przerwaniu od timera0 i porównywana jest z wartością zadaną.

    Oraz program z komentarzami:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Układ zmontowałem na płytce stykowej:
    Stabilizacja napięcia boost converter sterowanego atmegą

    Próbowałem zrealizowac regulator propocjonalny P ale układ nie działał kompletnie :/
    próbowałem to zrobic tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Z góry dziękuję za pomoc.
  • REKLAMA
  • Pomocny post
    #2 16689311
    BogdanGut
    Poziom 9  
    Posty: 22
    Pomógł: 1
    Ocena: 5
    Witam,
    sterowanie przetwornicą za pomocą atmelka jest dość ciężkim zadaniem. I tak naprawdę nie wiem, po co to robisz. Do swojego układu masz doprowadzone 12 V, z którego mógłbyś zrobić pożądane 10 na zwykłym liniowcu. Ale jeśli chcesz... Po pierwsze zwiększyłbym R6, albo dał inną diodę, bo ograniczenie jest ustawione bez żadnego zapasu. Poza tym wartość indukcyjności wydaje mi się za mała. Nie grzeje się dławik i tranzystor?
    Dla pracy w trybie ciągłego przepływu prądu powinna być chyba kilka razy większa.
    Sterowanie jest trudne, przetwornica step-up, zanim wyhamuje przy braku obciążenia upłynie zbyt dużo czasu. Należałoby ją wyłączyć przy przekroczeniu określonego napięcia wyjściowego (PWM = 0). Jeśli napięcie spadnie ponownie wprowadzić ją w tryb +/- 1, który stosujesz. Może to prowadzić do pracy szarpanej przy gwałtownych zmianach obciążenia, ale przy pracy ze stałym obciążeniem może być znośnie.
    Generalnie lepiej zastosować jakiś gotowy układ stabilizatora impulsowego. Pracują one z wyższą częstotliwością, mają zaszyte "algorytmy" sterowania. I tak stosujesz driver, a na taką moc pewnie gotowy stabilizator nie bedzie potrzebował tranzystora.
    Ze schematu wynika, że chcesz regulować napięciem wyjściowym, a gotowce nie mają regulacji - żaden problem. Ustawiasz kilka wyjść w tryb pull-down i załączasz nimi powielone rezystory R4 do masy (oczywiście tutaj może być problem z ich doborem).
    Jeśli chodzi o program sterowania proporcjonalnego to moje uwagi:
    - rejestry sterujące peryferiami to nie pamięć, zapisujemy do nich dopiero wtedy, kiedy wiemy co zapisać, najpierw zapisałeś wartość, a dopiero później sprawdzasz, czy ta wartość jest prawidłowa. Najpierw powinieneś odczytać zawartość rejestru do zmiennej, póżniej sprawdzić, czy zapisać sumę, czy zero i dopiero zapisać. Wyobraź sobie, że miedzy zapisaniem do rejestru OCR1A = OCR1A + error;, a sprawdzeniem wartości przychodzi długie przerwanie. Wówczas procek działa wg tej wartości.
    - dlaczego po else odejmujesz error? jeśli nie był dodatni to teraz jest ujemny i trzeba go również dodać. Nie wiem jakich typów używasz, ale jesli sądzisz, że w typach uint w wyniku odejmowania dostajesz wartość bezwzględną to jesteś w błędzie.
    - dlaczego w if-ie ponownie odczytujesz przetwornik? Masz jego już odczytaną wartość w wartosc_zmierzona i z niej powinieneś korzystać. Nie wiem, czy dobrze pamietam, ale w jakiś prockach można było tylko raz odczytywać wartość ADC.
    - if (OCRA<1) to OCRA musi już być zerem i nie trzeba tego ponownie zapisywać. Pewnie kompilator i tak to przypisanie wyrzuci.
    Powodzenia w dalszych działaniach.
  • REKLAMA
  • #3 16690190
    kamil94goldman
    Poziom 3  
    Posty: 261
    Pomógł: 5
    Ocena: 3
    Witam,

    1. Tak wiem że można by to zrobic łatwiej lecz chciałbym bardzo spróbować zrobić zasilacz impulsowy sterowany atmegą i takim układem posługuję się na razie żeby napisać dobry program.

    2. Jeśli chodzi o cewkę to: maksymalny (średni) prąd wyjściowy zakładam 1 A, jeśli chodzi o dobór cewki to tętnienia prądu wówczas będą wynosić 0,34 A. Posłużyłem się obliczeniami ze strony :http://schmidt-walter-schaltnetzteile.de/smps_e/aww_smps_e.html
    Nie, nic się nie grzeje :)

    Zmodyfikowałem trochę kod programu:
    3. Zmodyfikowałem częstotliwość PWM i ustawiłem 62 kHz:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    4. Przerwania od timera w których występuje odczyt napięcia mierzonego oraz regulacja, zmodyfikowałem zeby również działały od przerwania od timera0 z częstotliwością 64 kHz
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    5. Ustawiłem również tryb free running:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    6. A obsługa przerwania od przepełnienia timera0 wygląda teraz następująco:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    7. Po zastosowanych zmianach muszę przyznać że układ działa zadowalająco a stabilizacja napięcia na wyjściu przy zmianach obciążenia jest dosyć dobra :) lecz występuje jeszcze jeden problem który występował również wcześniej a nie pisałem jeszcze o tym.

    Np. Gdy ustawie napięcie wyjściowe około 10 V i podłącze obciążenie 100 ohm to napięcie wyjściowe spada o około 1,5 V (czyli napięcie wyjściowe wynosi około 8.5 V i takie się utrzymuje) a układ pracuje z maksymalnym wypełnieniem(wyświetlam wartość rejestru OCR1A na wyś. LCD). Układ zasilam z zasilacza do komórki 5V. Zmierzyłem również to napięcie: przy braku obciążenia wynosi 4,98 V a przy obciążeniu opisanym wcześniej spada do 4,60 V.

    Jaka jest przyczyna tego że napięcie przy obciążeniu 100 ohm (czyli prądzie tylko 0,1 A) spada aż o 1,5V? trochę to wygląda tak jakby ten zasilacz komórkowy ograniczał moc bo jak wyświetlam OCR1A to przy obciążeniu 100 ohm jest cały czas maksymalne czyli wynosi 130. :/
  • REKLAMA
  • #4 16690289
    ryba884
    Poziom 19  
    Posty: 273
    Pomógł: 33
    Ocena: 49
    Zauważ, że prąd średni po stronie zasilacza od komórki wynosi ponad 0,2A, a w impulsie może być wielokrotnie więcej. Spróbuj to zasilić z jakiegoś pewniejszego źródła.
  • #5 16690873
    BogdanGut
    Poziom 9  
    Posty: 22
    Pomógł: 1
    Ocena: 5
    1. Nie widzę na schemacie kondensatora elektrolitycznego na 5V. Dołóż jakieś 100u, żeby nie pakować do ładowarki 64kHz z harmonicznymi. Dołóż jeszcze ceramiczny ze 100n.
    2. Rozumiem, że to 130 max odpowiada wypełnieniu ciut ponad połowę. Daje to podwojenie napięcia wejściowego. Jeśli napiecie z ładowarki spada do 4,6 V, to siłą rzeczy uzyskasz w trybie cięgłego prądu co najwyżej 9,2 V - straty na kluczu i diodzie. Luzuj stopniowo ten limit.
    3. Dopiero dziś spojrzałem na zdjęcie układu, który zmontowałeś. Przetwornica powinna być konstrukcyjnie zwarta, kilkucentymetrowe przewody łączące poszczególne elementy to źródła oscylacji, zakłóceń. Poza tym powinieneś rozdzielić masy i zasilania przetwornicy i procka.
    Stabilizacja napięcia boost converter sterowanego atmegą
    W ten sposób ograniczy się dostęp spadków napięcia i zakłóceń z przetwornicy do procesora i ładowarki. Te zakłócenia powinny zamykać się na kondensatorze(rach) na wejściu. Nie powinny zakłócać również ładowarki.
    4. Jeśli to wszystko nie pomoże, zewrzyj kontrolnie R6. Może oscylacje pojawiające się na przewodach powodują skracanie przewodzenia drivera.
    Osobiście obstawiam punkt 2., że pomoże, ale 1 i 3 są ważne - zastosuj je.
    I jeszcze jedno odnośnie stylu kodowania. Jeśli używasz pewnej wartości np. 130 w kontekście maksymalnej wartości współczynnika wypełnienia i na dodatek używasz jej w kilku miejscach to skorzystaj z deklaracji #define, np. #define MAX_OCR1 130, później tam, gdzie korzystasz z tego piszesz np. if (a>MAX_OCR1){...}. Wydaje się to może na początku utrudnianiem sobie życia, ale w bardziej skomplikowanych projektach, które składają się z wielu modułów (plików c, czy cpp) ułatwia wprowadzanie zmian.
    I jeszcze drugie: zamiast
    Cytat:
    ISR( TIMER0_OVF_vect )
    {
    licznik++; //zmienna do odmierzania czasu z jakim ma byc wyswietlany wynik na LCD
    war_nap = ADCW;
    if(war_nap < a) //Warunek: Czy wartośc zmierzona jest mniejsza od wartości zadanej?
    {
    OCR1A = OCR1A + 1; //TAK wiec zwiększ wypełnienie PWM
    if(OCR1A > 130) OCR1A = 130; //ograniczenie wypełnienia
    blok = 0;
    }
    else //Nie wiec zmniejsz wypełnienie PWM
    {
    if(blok == 0) OCR1A = OCR1A - 1;
    if(OCR1A < 1) blok = 1; //Zablokowanie dalszago zmniejszenia OCR1A gdy jest zmniejsze od 1
    }
    return ADCW; //zwrocenie wyniku pomiaru w rejestrze ADCW(parze rejestrów ADCH i ADCL)
    }

    napisałbym:
    Cytat:
    ISR( TIMER0_OVF_vect )
    {
    licznik++; //zmienna do odmierzania czasu z jakim ma byc wyswietlany wynik na LCD
    war_nap = ADCW;
    uint16_t ocr1a = OCR1A ;
    if(war_nap < a) //Warunek: Czy wartośc zmierzona jest mniejsza od wartości zadanej?
    {
    if (ocra1a<MAX_OCR1 )
    {
    ocra1a++;
    }
    }
    else //Nie wiec zmniejsz wypełnienie PWM
    {
    if (ocra1a)
    ocra1a--;
    }
    OCRA1A = ocra1a;
    return ADCW; //zwrocenie wyniku pomiaru w rejestrze ADCW(parze rejestrów ADCH i ADCL)
    }
REKLAMA