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

[ATmega32][C][AVR Studio 4] Slave SPI, timery i przerwania - kolizja.

Co_pat 23 Paź 2011 14:40 1952 6
REKLAMA
  • #1 10056932
    Co_pat
    Poziom 15  
    Witam!

    ATmega32 16MHz jako slave odbiera dwa bajty po SPI 1MHz ( 15cm taśmy 10 żyłowej )od mastera LPC2148 . Jeżeli jest włączone tylko SPI, a inne przerwania są wyłączone jest wszystko dobrze. Jeżeli włączę przerwanie od timera2 generowane co 100us to zdarza się że atmega gubi jeden bajt i krzaczy się cała transmisja, ale po jakimś czasie jak zgubi następny to wraca wszystko do normy.
    Czy istnieje możliwość, że podczas przerwania generowanego przez SPI przerwanie zgłaszane przez timera2 psuje całość?
    Myślałem, aby wyłączać inne przerwania podczas obsługi SPI, ale problem jest w tym, że zarówno dokładne odmierzanie czasu jak i poprawna transmisja SPI jest dla mnie kluczowa ponieważ jest to układ regulacji silnikiem prądu stałego gdzie timer2 wyznacza częstotliwość pracy regulatora, a przez SPI przesyłana jest wartość referencyjna.
    Za wszelkie wskazówki będę wdzięczny.

    Poniżej obsługa przerwań:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • REKLAMA
  • #2 10057039
    tadzik85
    Poziom 38  
    Przerwanie od t1 nieblokowane lub w jego wnętrzu sprawdzasz flagę SPI i obsługujesz przerwanie programowo od SPI odbierając bajt
  • REKLAMA
  • #3 10057118
    Co_pat
    Poziom 15  
    tadzik85 dziękuję za błyskawiczna odpowiedź. Próbowałem tego rozwiązania i niestety gdy w przerwaniu od SPI umieszczę flagę i bez względu gdzie realizuję odbiór czy w przerwaniu od timera czy w pętli głównej drugi bajt wraca do mastera czyli wydaje mi się, że ATmega nie nadąża z odczytem.
  • REKLAMA
  • #4 10057119
    janbernat
    Poziom 38  
    Albo wręcz zrobić naked i wykorzystać jakiś rejestr sprzętowy.
    Co prawda jest to 16 bitów.
    Ale można to zrobić albo w dwóch 8 bitowych- żeby było atomowo albo jako Atomic Block.
  • REKLAMA
  • #5 10057181
    tadzik85
    Poziom 38  
    a czemu transmisji SPI nie zrobisz buforowanej? widzę ze masz tam sporo obliczeń w przerwanie od T1 jest bardzo krótkie.
  • #6 10057207
    BoskiDialer
    Poziom 34  
    Jeśli układ nadrzędny nadaje te dwa bajty jeden po drugim, to może się okazać, że przerwa między bajtami jest zbyt mała: realizując proste wyślij-czekaj_na_koniec-wyślij-czekaj w poolingu uzyska się odstęp między bajtami rzędu pojedynczych us, co może być zbyt małe na zareagowanie układu podrzędnego. Używając na masterze DMA (jeśli jest taka możliwość) odstępy te będą jeszcze krótsze. Rozwiązania sprzętowe układów podrzędnych zawsze można ciągnąć do wysokich prędkości przy znikomych opóźnieniach, tutaj jeśli obsługa slave'a wymaga ingerencji programu, nie można sobie już na to pozwolić - należy wstawić jakieś opóźnienia.

    Warto w tym przypadku użyć jakiegoś timera na masterze, który dawał by przerwanie np co 20us, to przerwanie wyzwalało by wymianę jednego bajtu. Wymiana trwała by 8us, pozostały czas był by czasem dla układu podrzędnego na zareagowanie.
    Inne rozwiązanie, to rozwiązanie kombinowane - dodatkowy przewód sygnalizujący gotowość układu podrzędnego - po przetworzeniu bajtu, slave zmieniał by stan na tym przewodzie.
    Jeśli jest możliwość użycia kanałów DMA na tym lpc, to może warto by zamienić ze sobą role układów?
  • #7 10174705
    Co_pat
    Poziom 15  
    Dziś wróciłem do sprawy po krótkiej przerwie. Zastosowałem się do rady:
    BoskiDialer napisał:
    Jeśli układ nadrzędny nadaje te dwa bajty jeden po drugim, to może się okazać, że przerwa między bajtami jest zbyt mała

    i okazało się, że transmisja zaczęła śmigać znacznie lepiej. W LPC2148 pomiędzy wysyłanymi bajtami dałem minimalne opóźnienie w postaci pustej pętli for X100. Ale niestety zdarzyły się błędy mniej więcej raz na kilka sekund gdzie bajty były wysyłane z częstotliwością 50Hz.

    janbernat napisał:
    Ale można to zrobić albo w dwóch 8 bitowych- żeby było atomowo albo jako Atomic Block

    Po zrobieniu przerwania jako Atomic Block udało się uzyskać jak na razie bezbłędną transmisję. Domyślam się, że takie rozwiązanie wpływa na opóźnienie timera, ale zliczany czas przez timer jest sukcesywnie resetowany więc błąd się nie kumuluje

    Problem uważam za rozwiązany.
    Dziękuję wszystkim za pomoc!
REKLAMA