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

atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

prociomen007 25 Paź 2013 08:07 3126 24
REKLAMA
  • #1 12878439
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Witam, zbudowałem następujący układ:

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    ( Potencjometry mają po 100kilo ohmów. )

    Układ jest generatorem z regulowaną częstotliwością i długością pulsu, regulowaną za pomocą potencjometrów. Niestety mam dziwny problem z jego obsługą. Kiedy programowo WYŁĄCZĘ wyświetlacz wszystko działa elegancko. Kiedy jednak wyświetlacz jest włączony pojawia się problem! Sygnał generowany przez PMW zanika. Pojawia się na ułamek sekundy i znika ( na około sekundę ) - i tak w kółko. Programowo wyświetlacz aktualizuję kiedy wykryta zostanie zmiana na potencjometrach. Wiadomo że charakteryzują się one dużą niedokładnością przez co aktualizacja wyświetlacza zachodzi bardzo często. ( może to powoduje jakieś krzaki ) Aby zrezygnować z generowania programowych opóźnień ( przy sterowaniu LCD ) korzystam z flagi zajętości. Sam program wygląda tak:

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


    Natomiast kod obsługi wyświetlacza:

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



    No i konfiguracja LCD:

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


    Zaznaczam jeszcze raz że wyłączenie obsługi LCD ( usunięcie jej z kodu ) usuwa problem. Atmega sterowana wewnętrznym oscylatorem 4 Mhz. Czy możliwe jest uszkodzenie wyświetlacza?
  • REKLAMA
  • #2 12878696
    2rs232
    Poziom 18  
    Posty: 141
    Pomógł: 28
    Ocena: 20
    Na początku ustawiasz wyrównanie
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a w pętli while z niego rezygnujesz
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    zamierzone działanie?
  • #3 12878791
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Nie rezygnuję z niego. Na początku do rejestru ADMUX wpisuję 0! czyli go nie ustawiam a zeruję. Dzięki temu przetwornik działa mi w trybie 8 bitowym.
    Ta linijka:

    ADMUX = 0x00;

    służy do wyboru wejścia przetwornika które aktualnie pracuje w tym przypadku ADC0 potem w dalszej części programu przełączam się na ADMUX |= (1 <<MUX0); ( czyli wejście ADC1 ). Trybu 8 bitowego w ten sposób nie wyłączam.

    Na symulatorze Proteus ISIS wszystko działa elegancko. Tylko w 'realu' powstają takie krzaki. Może uszkodzony jest wyświetlacz i mocno obciąża linie procesora przez co powstają takie wariacje? Dodam że kiedy rezystory wykręcone są na max albo miniumum nie zachodzi wtedy warunek który powoduje pisanie na wyświetlaczu ( mowa o kodzie ) i generator PMW działa prawidłowo. Wyraźnie jego praca zaczyna być szarpana kiedy wywołuję metody obsługujące LCD.
  • #4 12878799
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    2rs232 napisał:
    Na początku ustawiasz wyrównanie
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    a w pętli while z niego rezygnujesz
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    zamierzone działanie?


    1. Zero przesunięte dalej jest zerem... więc pod tym względem oba są równoważne
    2. ADLAR=0 to "tryb 10 bitowy" - wyrównanie wartości do dołu rejestru ADC.

    prociomen007 napisał:
    Dzięki temu przetwornik działa mi w trybie 8 bitowym.

    Nie, odczytujesz jedynie młodsze 8 bitów wyniku, czyli poprawnie odczytasz dolne 25% zakresu przetwornika powyżej zaczną się dziać śmieszne rzeczy.
    Poprawka:
    OdczytywałBYŚ, gdybyś tylko ADCL pobierał, ale wszędzie są manipulacje na obu bajtach ADC, bo zarówno ICR1 ma 16 bitów jakby i zmienne których używasz są typu int.

    Pozdrawiam,
    GSM
  • REKLAMA
  • #5 12878813
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    To jak to poprawnie odczytać wszystkie 10 bitów?
  • #6 12878826
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    prociomen007 napisał:
    To jak to poprawnie odczytać wszystkie 10 bitów?

    Zdecyduj się w końcu czy chcesz 8 czy 10 bitów. Jeśli 10 to tak jak jest, czyli ADLAR=0.

    Pozdrawiam,
    GSM
  • #7 12878838
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Może być 10 bitowy ale wtedy jak poprawnie pobrać wynik?
  • #8 12878840
    2rs232
    Poziom 18  
    Posty: 141
    Pomógł: 28
    Ocena: 20
    GSM racja, zasugerowałem się komentarzem i oczy same dodały 1. :|
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #9 12878888
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    E sprawdziłem dokumentację i pobranie wartości w stylu

    short int a = ADC;

    jest prawidłowe i zwraca wartość 10 bitową z przedziału 0...1023. Więc to nie jest problem.
  • #10 12878965
    2rs232
    Poziom 18  
    Posty: 141
    Pomógł: 28
    Ocena: 20
    Masz warning przy liniach z itoa ?
    Brakuje jeszcze tego:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #11 12879011
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Dostaję przy kompilacji dwa warningi:

    Warning 1 #warning "F_CPU not defined for <util/delay.h>"
    Warning 2 implicit declaration of function 'itoa'
  • REKLAMA
  • #12 12879023
    2rs232
    Poziom 18  
    Posty: 141
    Pomógł: 28
    Ocena: 20
    O definiowaniu F_CPU poczytaj tu Definiowanie F_CPU

    Dodaj jeszcze to skoro korzystasz z itoa:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #13 12879733
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Tym razem kod skompilowany bez żadnych warningów. Niestety problem cały czas występuje niezmiennie. Wypełnienie reguluję się pięknie bez najmniejszych problemów. Kiedy jednak choćby delikatnie ruszę potencjonometr od częstotliwości sygnał wyjściowy zaczyna 'pojawiać się i znikać'. Aktualnie to już nie mam pewności czy problemem jest wyświetlacz. Kiedy do rejestru ICR wpiszę 100 wszystko hula. Każda większa wartość powoduje wyżej opisany problem. Poniżej umieszczam film z pracy oscyloskopu i komentarz. Widać na nim wyraźnie jaki mam problem.





    Nie mam już koncepcji gdzie szukać problemu...
  • #14 12879915
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    prociomen007 napisał:
    sprawdziłem dokumentację i pobranie wartości w stylu (...) jest prawidłowe i zwraca wartość 10 bitową

    Nikt nie mówił, że nie jest.

    prociomen007 napisał:
    Nie mam już koncepcji gdzie szukać problemu...

    Uporządkuj kod, okrój go jak najbardziej i postaraj się raz jeszcze przeanalizować jego działanie. W szczególności dla wartości pryz której obserwujesz nieprawidłowe zachowanie układu. Najlepiej z opisem działania WGM timer-a w ręku.

    Pozdrawiam,
    GSM
  • #15 12880073
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Pytanie co mam analizować kiedy wiem jak 'kod' działa. Dodatkowo dziwi mnie całość bo PMW jest sprzętowe więc praktycznie co by się nie działo w pętli głównej to sygnał powinien być generowany prawidłowo nawet jak mikrokontroler wykonywał by polecenia delay...

    Sam program działa tak:

    -Wybranie odpowiedniego wejścia dla przetwornika ADC (0 )
    - włączenie konwersji i czekanie aż się wykona ( w tym czasie PMW powinno sobie generować sygnał )
    - jeśli wartość po dokonaniu obliczeń jest inna niż przy ostatnim przebiegu pętli to aktualizuję rejestr czasu wypełnia i wyświetlacz LCD

    -Wybranie odpowiedniego wejścia dla przetwornika ADC (1 )
    - włączenie konwersji i czekanie aż się wykona
    - jeśli wartość po dokonaniu obliczeń jest inna niż przy ostatnim przebiegu pętli to aktualizuję rejestr częstotliwości i wyświetlacz LCD

    I TO TAK LECI SOBIE W KOŁO

    Na lcd widzę jaka wartość wpisywana jest do rejestru częstotliwości kiedy wpisuję do niego 100 wszystko działa. Każda wartość większa od 100 ( wpis przy pomocy adc ) powoduje ze sygnał zaczyna znikać.
  • #16 12880238
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    prociomen007 napisał:
    Na lcd widzę jaka wartość wpisywana jest do rejestru częstotliwości kiedy wpisuję do niego 100 wszystko działa. Każda wartość większa od 100 ( wpis przy pomocy adc ) powoduje ze sygnał zaczyna znikać.

    O, jesteśmy coraz bliżej. Teraz przeanalizuj przebieg działania timer-a (jeden cykl pracy) dla wartości która działa i jeden dla której nie działa według twoich oczekiwań.

    Pozdrawiam,
    GSM
  • #17 12880380
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Chym, nie bardzo rozumiem jak mam to zrobić. Pmw działa sprzętowo wiec nie bardzo jest możliwość podejrzenia jak działa. Mogę programowo tylko podglądać rejestry które go konfigurują. Zaglądając do katalogu procesora niestety tez nie znajduje odpowiedzi na problem. Wszystko robię zgodnie z tym co tam opisano.

    Ps. Do rejestru ICR1 można maksymalnie wpisać wartość 16 bitową a to jest 1024. Wiec poza zakres też nie wychodzę.
  • REKLAMA
  • #18 12880449
    GSM
    Poziom 25  
    Posty: 543
    Pomógł: 72
    Ocena: 16
    Nie podglądaj, krok po kroku prześledź jak działa timer w tej konfiguracji, tak jak jest to chociażby zilustrowane w nocie katalogowej - postaci wykresów, wartości rejestrów od czasu.

    Pozdrawiam,
    GSM
  • #19 12881156
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    No więc po koleji. Tryby pracy ilustruje ta tabela:

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    Ja korzystam z 'Fast'. Czyli wypełnienie siedzi w OCR a ICR trzyma częstotliwość. Nie mogę nigdzie doszukać się jakiś informacji bardziej pomocnych. Są tam rozpisane czasy ale nic na temat przerywania generacji. Proszę jeśli ktoś wie jak mnie naprowadzić niech pokaże jakiś wykres lub informację która mnie wesprze.

    PS. Na symulatorze nie ma kompletnie żadnych problemów.
  • #20 12881229
    zumek
    Poziom 39  
    Posty: 3352
    Pomógł: 695
    Ocena: 51
    prociomen007 napisał:
    No więc po koleji. Tryby pracy ilustruje ta tabela:

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    Ja korzystam z 'Fast'. Czyli wypełnienie siedzi w OCR a ICR trzyma częstotliwość.

    Tak :?: To popatrz jeszcze raz na tabelkę, którą sam tu zamieściłeś.
  • #21 12881351
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Czyzby calos nalezalo uruchomi w phase corect? Bo w fast widze jest wartosc bootom zamias top.
  • #22 12881833
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Tabelka, którą pokazałeś, dotyczy Timera 0. Ty używasz Timera 1, który ma więcej trybów FastPWM - Tobie pasuje tryb 14.
  • #23 12882075
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    No więc tak:

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    w kodzie właśnie w taki sposób nadpisuje rejestry WGM. Czyli tryb jest wybrany dobry. Do tego odpowiedni konfiguruję wyjścia z procesora ( pozycja 3) :

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    No i jeszcze dodatkowo wybieram prescaler 64 :

    atmega8535 - Obsługa wyświetlacza LED demoluje generator PMW

    Czyli wszystko ustawione jest prawidłowo i powinno działać. Zastanawia mnie jednak inna sprawa. Na wiadomo że rezystory nie mają idealnej dokładności i na wyświetlaczu widzę że wartość z przetwornika zawsze leko pływa. Co za tym idzie LCD jest aktualizowany co przebieg pętli. Tylko wartość maksymalna rezystora powoduje że ADC wykrywa zawsze to samo. Jeśli LCD jest aktualizowane co przebieg to znaczy że częstotliwość PMW też. Może tu jest 'pies pogrzebany'. Może jak tak często nadpisuje ten rejestr to PMW wariuje?
  • #24 12882091
    BlueDraco
    Specjalista - Mikrokontrolery
    Posty: 6479
    Pomógł: 939
    Ocena: 421
    Nie wiadomo, jak jest ustawione - pokaż najnowszą i najkrótszą wersję kodu. Byłoby Ci łatwiej, gdybyś nie przekonywał siebie, że "wszystko ustawione jest prawidłowo i powinno działać".

    To oczywiste, że ADC pływa, niezależnie od stabilności wejścia, więc okres PWM te będzie się zmieniał co chwila przy sterowaniu go z odczytów ADC.
  • #25 12883788
    prociomen007
    Poziom 18  
    Posty: 701
    Pomógł: 1
    Ocena: 30
    Proszę uprzejmie oto najnowsza i aktualnie używana wersja kodu:

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


    Osobiście nie widzę nic co może powodować błąd. To że po ustawianiu ICR z przetwornika ADC częstotliwość może pływać jest zrozumiałe. Jednak nie powinna ona zanikać. Może częste zmiany powodują że generator PMW wariuje? Może zmiana wartości w tym rejestrze zajmuje mikrokontrolerowi chwilę a w tym czasie sygnał nie jest generowany ?

Podsumowanie tematu

✨ Użytkownik zbudował układ z mikrokontrolerem ATmega8535, który działa jako generator PWM z regulowaną częstotliwością i długością pulsu. Problem pojawia się, gdy wyświetlacz LCD jest włączony - sygnał PWM zanika, co może być spowodowane częstymi aktualizacjami wyświetlacza w odpowiedzi na zmiany na potencjometrach. Użytkownik podejrzewa, że obciążenie linii procesora przez wyświetlacz może wpływać na stabilność sygnału PWM. W dyskusji poruszane są kwestie dotyczące konfiguracji rejestrów ADC, trybów pracy timera oraz wpływu aktualizacji wyświetlacza na generację sygnału PWM. Użytkownicy sugerują analizę działania timera oraz stabilności odczytów ADC, a także sprawdzenie, czy częste aktualizacje rejestru PWM mogą powodować problemy.
Wygenerowane przez model językowy.
REKLAMA