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

atmega 128 - PWM w przerwaniu TOV1 nie działa, działa w pętli głównej

domija 26 Lip 2012 21:17 2035 8
  • #1 11146982
    domija
    Poziom 11  
    Witam,
    sytuacja wygląda następująco: chce zrobić PWM'a w przerwaniu TOV1, który sterowany jest z ADC. Problem polega na tym, że kod, który jest w tym przerwaniu nie powoduje żadnej zmiany na wyjściu PWM, jeżeli przenoszę kod do pętli nieskończonej wszystko chodzi jak należy i nie wiem dlaczego to w przerwaniu nie działa. Ponad to, gdy w przerwaniu tuż przed wpisaniem wartości do OCR uruchomię globalne przerwania znowu zaczyna działać, a przecież sama specyfikacja mówi o dostępie do 16 bitowych rejestrów OCR, że najlepiej zablokować przerwania, a przecież gdy uruchamia się przerwanie to wszystkie globalne przerwania są zablokowane i uruchamiane dopiero po instrukcji reti.

    poniżej kod w przerwaniu
    Kod: text
    Zaloguj się, aby zobaczyć kod


    a tu poniżej kod z pętlą nieskończoną
    Kod: text
    Zaloguj się, aby zobaczyć kod


    będę wdzięczny za wytłumaczenie sprawy
  • #2 11147619
    LordBlick
    VIP Zasłużony dla elektroda
    Straszna rzeźba.. :P Ten kompilator obsługuje incudowanie plików, można sobie zdefiniować co do czego podłączamy, dwa poziomy makr...
    To co mnie swędzi poza tym:
    - czemu używasz wartości liczbowych dla .org w tablicy wektorów ? Zajrzyj do m128def.inc, a najlepiej wygenerować sobie xmlconvert nagłówki do IAR C i stosować, idealnie pasują.
    - Gdzie masz TIM3_OVF ?
    - Żadnych pętli blokujących w przerwaniu.
    - Użyj przerwania od ADC, RAM-u też Ci nie brakuje (".dseg"), wystarczy w jednym przerwaniu zapisać do pamięci, a w drugim odczytać.
    Ech, napisałbym jakiś kursik, tylko nie ma kiedy się za to zabrać...
  • #3 11148494
    excray
    Poziom 41  
    A ja dorzucę od siebie że do sprawdzania końca konwersji ADC nie należy używać ADIF tylko ADSC. A przy okazji kasując bit ADIF kasujesz bit włączający ADC i preskaler. Poza tym jak wyżej - straszna rzeźba. Nadawanie nazw rejestrom moim zdaniem bez sensu. Sam się gubisz i nie wiadomo czy ma się do czynienia z rejestrem z grupy r16-r31 czy r0-r15.
  • #4 11148530
    LordBlick
    VIP Zasłużony dla elektroda
    excray napisał:
    Nadawanie nazw rejestrom moim zdaniem bez sensu. Sam się gubisz i nie wiadomo czy ma się do czynienia z rejestrem z grupy r16-r31 czy r0-r15.
    Tu się mogę nie zgodzić - nadawanie nazw może mieć sens, gdy się wie, co się robi:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Dolnych rejestrów is... używam do przechowywania stałych, zawartości SREG i rejestrów podczas obsługi przerwań, co czyni obsługę przerwania szybszą. Potem inkludujesz sobie taki pliczek i trzymając się tej konwencji większość dylematów masz z głowy (makro InitFastAccessRegs wywołujemy zaraz po inicjalizacji stosu).
    Przykład:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Oczywiście przykład zawiera trochę makr... ;)
  • #5 11148901
    Konto nie istnieje
    Konto nie istnieje  
  • #6 11149469
    LordBlick
    VIP Zasłużony dla elektroda
    Saabotaz napisał:
    Tak patrzę i na moje oko to włączyłeś przerwanie timera, ok ale timerem 1 generujesz pwm i chcesz też używać jego overflow?
    A w czym to przeszkadza ? Nie modyfikuje przecież wartości licznika...
    Moja propozycja (w/g w/w definicji) do przeanalizowania(trochę zmieniłem konfigurację):
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Dodatkowo nadmienię, że DataI służy tylko do obsługi przerwań, więc nie musi być odtwarzana dla normalnych procedur. Takie rzeczy tylko w asemblerze... ;)
  • #7 11151966
    excray
    Poziom 41  
    LordBlick napisał:
    TIM1_OVF:
    ; in isSREG, SREG ;save SREG
    ; - - - - - - - - - - - - - - - -
    sbi ADCSRA, ADSC
    ; - - - - - - - - - - - - - - - -
    ; out SREG, isSREG ;restore SREG
    reti

    sbi i cbi nie powodują żadnej zmiany SREG więc zapisywanie i odtwarzanie SREG w tym przypadku jest niepotrzebne.

    LordBlick napisał:
    ADC:
    in isSREG, SREG ;save SREG
    movw is1:is0, XH:XL ;save X
    ; - - - - - - - - - - - - - - - -
    in XL,ADCL
    in XH,ADCH
    out OCR1AL, XH
    out OCR1AH, XL
    ; - - - - - - - - - - - - - - - -
    movw XH:XL, is1:is0 ;restore X
    out SREG, isSREG ;restore SREG
    reti

    Nie rozumiem tego. Skoro już używasz rejestrów is0 i is1 to czemu bezpośrednio do nich nie załadujesz ADCH i ADCL. Ja bym to zrobił tak:
    Kod: text
    Zaloguj się, aby zobaczyć kod
  • Pomocny post
    #8 11152043
    LordBlick
    VIP Zasłużony dla elektroda
    excray napisał:
    sbi i cbi nie powodują żadnej zmiany SREG więc zapisywanie i odtwarzanie SREG w tym przypadku jest niepotrzebne.
    Zgadza się, dlatego są zakomentowane na wypadek, gdyby jeszcze coś w tym przerwaniu miało być robione... :P
    excray napisał:
    Nie rozumiem tego. Skoro już używasz rejestrów is0 i is1 to czemu bezpośrednio do nich nie załadujesz ADCH i ADCL.
    Dlatego, że w moim założeniu programistycznym te rejestry są z dolnej - mniej uniwersalnej połówki i służą do czego innego, a nie robię od tych założeń wyjątków, bo wszystkie procedurki używam w różnych projektach (#include rulez) i muszą być kompatybilne ze sobą.
    excray napisał:
    Ja bym to zrobił tak:
    Kod: text
    Zaloguj się, aby zobaczyć kod
    Co do twojego przykładu, zobacz różnicę dodatkowego narzutu w cyklach obsługi - twoje push/pop to 8 cykli, moje 2 x movw to 2. Nawet doliczając zbędne w tym przypadku in/out SREG, narzut u mnie jest o połowę mniejszy, a gdyby jednak w obsłudze przerwania coś zmieniało rejestr flag, ty swoją metodą musisz narzucić jeszcze 6 cykli (in/push/[...]/pop/out ), a ja nic - wychodzi 4 cykle vs. 14.
    BTW. O tym, co wyprawia avrr-gcc przy obsłudze przerwania, to już nawet lepiej nie wspominać... ;)
  • #9 11197555
    domija
    Poziom 11  
    Witam szanownych forumowiczów.
    Największym problem w tym przypadku okazało się zasilanie mikroprocesora. Jest nim przetwornica lm2672. Mimo, że prawidłowo zostały wyliczone wszystkie kondensatory i dławik ,to dla testów nie była wykorzystywana wyliczona wcześniej wartość obciążenia. Nie wiem co dokładnie się działo, czy mikroprocesor wariował czy może ADC nie radził sobie z konwersją. W każdym razie po podłączeniu zasilania do zasilacza laboratoryjnego wszystko zaczęło działać, nawet ten kod z pierwszego postu. Nie mniej jednak zmieniłem kod i cały mechanizm przepisywania wartości do OCR umieściłem w przerwaniu ADC według wskazówki LORDA BLICKA. Czas procesora to cenna rzecz dlatego trzeba go oszczędzać. Nie wiem dlaczego sam na to nie wpadłem. W każdym razie sprawa rozwiązana, dziękuje wszystkim za pomoc.
REKLAMA