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

AVR136: Czas obsługi przerwania na Atmega162 przy 32 kanałach PWM

Krokus22 13 Lut 2012 00:26 1975 11
REKLAMA
  • #1 10538027
    Krokus22
    Poziom 19  
    Witam, pracuję obecnie nad pewnym projektem, w którym używam 32 kanałów PWM na procesorze Atmega162 generowanych programowo wg. dokumentu AVR136, program napisany w języku C. Mogę powiedzieć, że generalnie wszystko działa zgodnie z oczekiwaniami, modulacja działa prawidłowo, jednak chciałbym poznać, jaki procent czasowy zajmuje obsługa przerwania. Nie znam zbytnio assemblera, ale interesuje mnie, ile zajmuje martwa pętla przerwania, to jest kiedy nie ma nic do roboty (aktualizacja stanu pinów) oraz taka która ustawia wszystko.

    Po prostu procesor obsługuje jeszcze komunikację po UART i generację komunikatów zwrotnych itd, itd.

    Dany jest fragment programu w C:

    Inicjalizacja timerów (procesor pracujący na 16MHz):
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


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


    Oraz odpowiadający mu fragment w assemblerze:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Domyślam się, że należałoby wykorzystać opcję debugowania i patrzeć, ile czasu zajmuje przerwanie na oscyloskopie, co z resztą zrobię, jednak chciałbym poznać od strony procesora, ile zajmuje wykonanie tego konkretnie przerwania, niewykluczone, że trzeba będzie wykorzystać timer 16bit, zliczający do 512, dlatego proszę o poradę, pozdrawiam.
  • REKLAMA
  • #2 10538345
    Mundi1970
    Poziom 24  
    W tym dokumencie jest spis komend asemblera Link. W kolumnie #Clock Note jest podane ile cykli wykonuje się rozkaz. I tak np. NOP (1 cykl) przy zegarze 1MHz, wykonuje się 1us, ale przy zegarze 16 Mhz w czasie 1us wykona się 16 NOP'ów :). Można to podliczyć na karteczce.

    EDIT: W symulatorze też można to sprawdzić.
  • REKLAMA
  • Pomocny post
    #3 10538647
    tmf
    VIP Zasłużony dla elektroda
    No właśnie, zamiast liczyćna piechotkę, odpal w AVR Studio symulator, ustaw breakpoiny i porównaj wartość licznika taktów.
    Inna sprawa, że generuje ci dziwny kod dla zmiennych pinlevel, nie wiem czemu nie umieszcza ich w rejestrach. Dodanie do nich register skróci kod o połowę i przy okazji go mniej więcej dwa razy przyśpieszy.
  • #4 10540260
    Krokus22
    Poziom 19  
    No niestety, AVR studio nie obsługuje Atmega162 dla potrzeb symulacji, próbowałem VMLAB, udało się skompilować i uruchomić symulację, jednak nie umiem wstawić tam breakpointów, powinny być widoczne jakieś kwadraty przy liniach, chyba muszę poszukać. Przyznaję się, że nie mam żadnego doświadczenia w symulacji mikrokontrolerów, więc pragnę spytać, czy istnieje jakaś ciekawa alternatywa dla wbudowanego symulatora i VMLAB-a?

    Swoją drogą, dodanie "register" skróciło niewątpliwie czas obsługi przerwania, oto kod w ASM:

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #5 10540443
    Mundi1970
    Poziom 24  
    Krokus22 napisał:
    No niestety, AVR studio nie obsługuje Atmega162 dla potrzeb symulacji

    Czy aby na pewno nie obsługuje?

    AVR136: Czas obsługi przerwania na Atmega162 przy 32 kanałach PWM
  • REKLAMA
  • #6 10542401
    Krokus22
    Poziom 19  
    Przepraszam, niefortunnie zasugerowałem się AVRStudio w wersji 5 oraz jego dokumentacji w PDF-ie. Uruchomiłem już licznik cykli w AVR Studio 4 i rzeczywiście można wyciągnąć następujące wnioski:

    dla kodu ze zmiennymi statycznymi są 443 cykle
    dla kodu ze zmienną typu "register" jest 198 cykli

    Dziękuję tmf za podpowiedź, rzeczywiście przyspieszyłem przerwanie dwukrotnie, teraz zastanawia mnie jedno. Jeżeli przerwanie wykonuje się co 255 cykli, a trwa 198 cykli plus jakiś tam mały czas na jego wywołanie, to chyba rozsądnym jest, aby wywoływać je nieco rzadziej kosztem odświeżania, czyli zaprzęgnąć do działania timer 16bit i zliczać do 512 albo więcej. Przy wywoływaniu przerwania co 255 cykli @ 16Mhz odświeżanie dla 8bit PWM jest około 250Hz, chyba można to bez większych konsekwencji zmniejszyć do np. 100Hz. Proszę o komentarz:)
  • REKLAMA
  • #7 10543527
    tmf
    VIP Zasłużony dla elektroda
    Może mi umknęło, ale czym sterujesz? Jeśli to LED to 100Hz to mało. Ale powyższy kod można jeszcze bardziej przyśpieszyć. Poza tym co 255 cykli, to przy 16 MHz wychodzi mi ponad 31kHz.
  • #8 10546824
    Krokus22
    Poziom 19  
    Witam,

    Oczywiście steruję diodami LED, układ już dawno zmontowany, ale nim wdrożę go w życie, naszło mi na myśl wprowadzić parę udogodnień, to 32kanałowy sterownik RGB po interfejsie modbus.

    Koncept jest następujący: Co 255 cykli wywoływane jest przerwanie (przepełnienie timera 0) które wymusza zwiększenie programowego licznika 'sofcount', kiedy zrówna się z zerem (modulo 255), bufor wartości jasności przepisywany jest do tablicy porównań i wyjścia są ustawiane w stan wysoki. Następnie za każdym razem sprawdzane jest, czy zrównały się z wartością licznika programowego, wtedy zdejmowana jest jedynka.

    Pytanie skąd wziąłem wartość ok 250Hz? Otóż dla zegara 16MHz cykl przepełnienia trwa 255 taktów zegara oraz cykl PWM trwa 255 przerwań od timera, zatem 16MHz/(255*255)=246Hz.

    Generalnie moje wątpliwości dotyczą faktu, że procentowo 198 cykli względem 255 to jest 78%, gdzie w międzyczasie są jeszcze generowane i analizowane komunikaty modbus, chciałem to trochę zoptymalizować lub ewentualnie dać więcej czasu między przerwaniem do obsługi PWM, tylko jak to można bardziej zoptymalizować, wzorowałem się na AVR136 - low jitter software PWM.

    Teraz znalazłem ciekawe rozwiązanie, BAM (bit angle modulation), podobno jest to całkiem efektywne dla wielu kanałów do modulacji. Jednak wolę dalej pytać, jak zoptymalizować tego wielokanałowego PWM.

    Swoją drogą ustawiłem zmienne pinlevelX jako globalne, wygląda to tak:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Czemu tak? W procedurze przerwania nie chciało działać, a tak wymusiłem nawet konkretne rejestry. Przerwanie zajmuje ok 158 cykli.
    Czy jest to poprawne, avr-gcc wypisuje warningi: ../pwm.h:11:1: warning: file-scope declaration of 'pinlevelA' specifies 'register' (oczywiście tryb pedantic, bez tego zero warningów).

    Nie brzmi to groźnie, ale jak się tego pozbyć?
  • #9 10547963
    tmf
    VIP Zasłużony dla elektroda
    Niekoniecznie jest groźne, lecz pamiętaj, że cały program musi zostać tak przekompilowany aby te deklaracje były widoczne we wszystkich modułach. Sprawdź też czy wykorzystanie tych rejestrów nie koliduje z AVR-libc. Co do optymalizacji - jeśli posortujesz tablicę z wartościami PWM to mocno skrócisz średni czas wykonywania przerwania. Można też wygenerować odpowiednie wzorce w pamięci RAM - dla 32 PWM potrzebowałbyć 32/8*256 bajtów pamięci, ale dzięki temu procedura obsługi zajęłaby zaledwie parę taktów.
  • #10 10548593
    Krokus22
    Poziom 19  
    Witam, oczywiście deklaracje są we wszystkich modułach, program działa jak najbardziej poprawnie. Próbowałem wzorca w pamięci RAM, niestety procesor posiada tylko 1kB RAM, dlatego odbyło się to kosztem zmniejszenia rozdzielczości. Dzisiaj wykorzystałbym dedykowany układ - TLC5940, ale póki co, dopracuję to co zostało zrobione.

    Moje właściwie finalne pytanie po wszystkich bojach dotyczy jednego. Czy jeżeli przerwanie wywoływane co 255 taktów zajmuje 158 taktów, to nie doprowadzę do zagłodzenia innych peryferiów? Teraz jest 3 razy lepiej jak było wcześniej, jednak zastanawia mnie, jak radzą sobie w tej sytuacji funkcje obsługujące UART, sumy kontrolnej, które również wymagają z racji protokołu jakiś reżimów czasowych.
  • Pomocny post
    #11 10548677
    tmf
    VIP Zasłużony dla elektroda
    Nie da się na to pytanie odpowiedzieć nie widząc kodu. USART obsługujesz w przerwaniach? Pamiętaj, że na czs jego wykonania inne przerwania są blokowane, użycie nieblokujących handlerów przerwań wymaga głębszej analizy. Ale generalnie spójrz na to w ten sposób - procesor przez 40% czasu się nudzi. Więc dla 16MHz masz sytuację taką, jakbyś miał cały procesor taktowany zegarem koło 6MHz, czyli całkiem nieźle.
  • #12 10548939
    Krokus22
    Poziom 19  
    Oczywiście, USART w przypadku wysłania i odbioru jest na przerwaniach, w pętli głównej sprawdzana jest tylko flaga, czy zostało już zakończone odbieranie całego komunikatu i następuje dalsza obróbka, ogólnie właśnie dodałem korekcję gamma i mogę powiedzieć że po wspomnianych poprawkach projekt spełnił oczekiwania. Oczywiście na małych jasnościach 8bitów modulacji to trochę mało, ale i tak efekt jest niezwykle ciekawy.

    Co do pracy na 6MHz to ciekawe podejście, z tego co widzę procesor wyrabia się znakomicie z przetwarzaniem komunikatów, więc zostaje go jeszcze gruntownie przetestować na wielu kanałach. Bardzo dziękuję za pomoc, wykonam odpowiednie próby i w razie potrzeby będę pytał.
REKLAMA