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

[atmega1284P]i[atmega8] - [max485]USART pomiędzy procesorami się nie wyrabia

proku 22 Paź 2012 11:27 1386 1
REKLAMA
  • #1 11437630
    proku
    Poziom 2  
    Witam,
    mam problem z połączeniem po USARCIE tych dwóch procesorów. Sprawa wygląda następująco: atmega1284p ma być docelowo masterem, wysyła ramkę i w odpowiedzi dostaje ramkę zwrotną od atmega8. Obsługa ramek nie jest jeszcze napisana, na razie wysyłam 8 bajtów atmegą1284p i jeżeli wszystkie bajty zostają poprawnie odebrane, to atmega8 odsyła mi 11 bajtów. I tu zaczyna się problem, mianowicie ramka od atmegi8 przy prędkości 9600 zostaje odebrana prawidłowo kilka pierwszych razy, potem "się rozjeżdża" bajty wysyłane później są odbierane jako pierwsze, nie ma reguły które. Warto dodać, że przy prędkości 230400 wszystko działa idealnie. Kwarce w obu atmegach 14,7456MHz. Muszę jeszcze napisać, że atmega1284p ma w sobie wgranego także freemodbusa, który komunikuje się z komputerem przez drugiego USARTA. Funkcja while(1) wygląda w niej następująco:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Sam USART napisany jest na podstawie książki Pana Kardasia "Mikrokontrolery AVR Język C Podstawy Programowania", oczywiście na przerwaniach, z buforem cyklicznym, tak wyglądają funkcje:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Natomiast część odpowiedzialna za komunikację z Atmegą8 jest następująca:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Czyli zwyczajnie wypisane wszystkie funkcje które chcę zrealizować. Próbowałem zarówno w Atmega8 jak i Atmega1284p korygować wszystko delay'ami, żeby poczekało na odbiór, ale nie chciało mi to działać. Siedzę nad tym już kilka dni, nie wiem czy to jakaś głupota czy nie, dlatego zdecydowałem się napisać. Czy ma ktoś jakiś pomysł, jak to rozwiązać? Z góry dziękuję za wszystkie rady
  • REKLAMA
  • Pomocny post
    #2 11437706
    tmf
    VIP Zasłużony dla elektroda
    Jest tu co najmniej kilka błędów. Pierwszy to taki, że funkcja uart_getc nie jest atomowa. W ogóle kolejka jest zrealizowana źle - nie uwzględnia, że odczyty/zapisy następują asynchronicznie, w związku z tym pewne operacje (np. uaktualnienie wskaźników początku i końca) muszą być robione atomowo. Przypadkowo to działa przy zapisie, bo ISR jest wykonywane atomowo, ale już odczyt może krzaczyć. Może to dawać efekty o jakich piszesz, bo problem wystąpi losowo w chwili odebrania znaku w traksie modyfikacji wskaźnika. Drugi problem - twoja ramka ma nieprawidłową budowę. Musisz mieć możliwość wznawiania poprawnej transmisji po dowolnym błędzie. A więc musi być dodana detekcja końca ramki, nawet nieprawidłowej. Zauważ, że w twoim przykładzie jakieś proste zakłócenie może być odebrane jako bit startu, w efekcie cała transmisja się rozsynchronizowuje na wieki. Najprościej dodać jakiś timer, który przy zadanym okresie bezczynności magistrali resetuje transmisję.
REKLAMA