Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[AtMega8][Bascom] Problemy z komunikacją po SPI.

Pev4 01 Lut 2012 21:05 2772 10
  • #1 01 Lut 2012 21:05
    Pev4
    Poziom 12  

    Witam,
    Już kilka dni siedzę nad tą sprawą i nie mogę jej rozwiązać.
    Dwie AtMega8 nie chcą się dogadać przez SPI. Szukałem już w internecie i na Elektrodzie, bezskutecznie. Było kilka podobnych tematów, ale żaden mi nie pomógł.
    Ten temat jest najbliżej mojego problemu, ale nawet po użyciu źródeł z "rozwiązanego" problemu nie chce to poprawnie chodzić - nawet gdy ilość przesłanych bajtów ograniczę do jednego.
    Problem polega na tym, że dane z Mastera muszą być przesłane aż trzykrotnie, żeby Slave je odebrał. Pierwsze przesłanie aktywuje w slave przerwanie i Slave zawiesza się w bezczynności na którymś z poleceń SPIIN. Kolejne przesłanie odbiera dane w dziwnej (losowej) kolejności, lub odbiera jakieś śmieci, a dopiero trzecie przesłanie danych odbiera poprawne wartości. Sytuacja taka jest niedopuszczalna, bo przy takim transferze slave jest na 15s (3 pętle mastera) odcięty od realizacji swoich zadań.
    Dlaczego polecenie SPIIN zatrzymuje kontroler? Chyba nie powinno się tak dziać, nawet jeśli nie przychodzi żaden bajt.
    Bardzo proszę o pomoc, bo już nie mam pomysłu co może być nie tak. Poniżej zamieszczam moje listingi:

    Master:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Slave:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0 10
  • #2 01 Lut 2012 22:24
    marci4
    Poziom 29  

    ISP oznacza InSystem Programming i służy do programowania m.in. uC ATMELa w gotowych projektach.
    Myślę, że koledze chodzi o SPI.

    0
  • #3 03 Lut 2012 07:20
    Pev4
    Poziom 12  

    Udało się skomunikować te dwa układy po dodaniu:
    - dodatkowej komendy SPIOUT w Masterze (wysyłam 9 bajtów, odbieram 8)
    - waitms 2 po każdej komendzie SPIOUT w masterze,
    - waitms 1 po każdej komendzie SPIIN w Slave.

    Jednak nadal Slave zawiesza się średnio co 5-10 paczkach danych (obecnie wysyłam po 8 bajtów)
    Włączyłem watchdog, co zabezpiecza układ przed zawieszeniem się, jednak skutkuje to bezpowrotną utratą przesłanych danych, co jest bardzo niepożądane.

    Udało się komuś bezproblemowo skomunikować dwa kontrolery po SPI? Proszę o nakierowanie mnie na czym polega problem. Może napisać od nowa, po swojemu komunikacje SPI w asemblerze? Lub naprawić błąd w bibliotekach Bascoma?

    0
  • #4 03 Lut 2012 17:21
    Mundi1970
    Poziom 24  

    Pev4 napisał:
    Jednak nadal Slave zawiesza się średnio co 5-10 paczkach danych (obecnie wysyłam po 8 bajtów)

    I co w tym dziwnego :), po ile bajtów przydzieliłeś na stosy? Co w przerwaniu robi LCD, CLS i WAIT? Takich rzeczy nie powinno być w przerwaniu. Zauważyłem też , że nie masz skonfigurowanego /SS (Slave selected) na Masterze i Slave. Podczas wysyłania danych z mastera nie używasz /SS. Link

    0
  • #5 06 Lut 2012 17:58
    Pev4
    Poziom 12  

    Dzięki za odpowiedź.
    Siedziałem nad tym kilka dni i spróbowałem chyba wszystkich możliwych konfiguracji SPI. Listing, który wrzuciłem powyżej po prostu trochę działał. Inne listingi, gdzie miałem skonfigurowane SS i wszystko inne tak jak trzeba nie chciały działać.

    Mundi1970 napisał:
    po ile bajtów przydzieliłeś na stosy?

    Nie wiem jak to zrobić ręcznie. Myślałem, że bascom robi to automatycznie.

    Zmieniłem teraz listing wg Twoich sugestii - teraz układ Slave się zawiesza w podprogramie(nie odświeża wyświetlacza), a master musi wysłać całą paczkę 8 bitów po kilka razy (około 6-8 razy), żeby slave je odebrał. Slave odbiera poprawne wartości i w poprawnej kolejności. Nie wiem tylko dlaczego nie robi tego za pierwszym razem?
    Jednak jeśli wyślę o jeden bajt więcej, niż odbieram (czyli np. odkomentuję pierwszą linijkę w podprogramie Write_spi) to wszystko zaczyna działać dobrze. Dlaczego tak się dzieje? Zupełnie jakby pierwsza komenda SPIOUT tylko wywoływała przerwanie...
    Poniżej aktualne źródła:

    Master:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Slave:
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #6 07 Lut 2012 12:19
    Mundi1970
    Poziom 24  

    Cały problem jest w tym żeby te dwie ATmegi się zsynchronizowały. Przerwanie od SPI występuje po zakończenia transmisji pierwszego bajtu. Zanim nastąpi obsługa przerwania to pierwszy bajt zostanie utracony. Nie mamy też gwarancji że dwie Atmegi "wystrzeliły" :) równocześnie i Slave nie czyta np. 4 bajtu nadanego przez Mastera. Jeżeli to by była np. ATmega 48, 88, 168 lub 328 nie było by problemu, pin /SS można by ustawić na przerwanie PCINT. Wtedy Master ustawiając /SS wywoływałby przerwanie na SLAVE. I tu swoją słabość pokazuje Bascom'owy SPIIN :), sprawdza tylko bit SPIF w rejestrze SPSR, czyli czy nadszedł nowy bajt do odebrania. Jeżeli Slave ma odczytać 8 bajtów, a pierwszym bajtem jest np. 4 bajt nadany przez Mastera, po odczytaniu 4 bajtów zostanie w przerwaniu i będzie oczekiwał na następne bajty które wyśle Master i tak w kółeczko :). SPIIN nie sprawdza pinu /SS, gdzie przy wysokim stanie /SS odczyt powinien być przerwany i dane uznane za uszkodzone.

    Przykład jak odczytać dane w przerwaniu wykorzystując rejestry, a nie polecenie SPIIN. Master w pętli wysyła bajt 0xFF żeby wywołać przerwanie na SLAVE, jednocześnie odczytuje bajt nadany przez SLAVE. Jeżeli odczyta bajt 0x80, wysyła 8 zmiennych. Jeżeli MASTER nie odczyta 0x80 to błąd. SLAVE po wejściu do przerwania sprawdza czy jest jakiś bajt do odebrania, zeruje flagę, wysyła 0x80 i odbiera 8 zmiennych. SLAVE cały czas sprawdza stan /SS, jeżeli podczas odczytu wystąpił stan wysoki, ustawia błąd. Nie jest to doskonały przykład, czasami wyświetla się że dane są uszkodzone ale można to dopracować.

    MASTER:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    SLAVE:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #7 08 Lut 2012 18:47
    Pev4
    Poziom 12  

    Dzięki za pomoc.
    Zastanawiam się, czy nie lepszym rozwiązaniem będzie podanie SCK mastera dodatkowo na INT0 slave. Tak żeby pierwsze zbocze zegara wywoływało przerwanie. Czy wtedy transmisja przejdzie bez problemów? I bezbłędnie przy użyciu samych poleceń SPI IN/OUT?
    Zależy mi na transmisji od razu 8 bajtów.

    A jak jest z UARTem? Nie miałem okazji jeszcze się z nim bawić... Działa pewniej? Jest dużo wolniejszy?
    A inne prosokoły? I2C, 1wire?
    Potrzebuję czegoś niezawodnego co prześle 8 bajtów w obie strony pomiędzy masterem a kilkoma slave'ami i nie wiem na co się zdecydować.

    0
  • #8 09 Lut 2012 12:44
    Mundi1970
    Poziom 24  

    Pev4 napisał:
    Zastanawiam się, czy nie lepszym rozwiązaniem będzie podanie SCK mastera dodatkowo na INT0 slave. Tak żeby pierwsze zbocze zegara wywoływało przerwanie. Czy wtedy transmisja przejdzie bez problemów? I bezbłędnie przy użyciu samych poleceń SPI IN/OUT?

    Jeżeli przełożysz SCK na pin INT0 wtedy SPI nie będzie działało. Możesz wykorzystać jakiś wolny port Mastera do wywołania przerwania INT0.
    Pev4 napisał:
    Potrzebuję czegoś niezawodnego co prześle 8 bajtów w obie strony pomiędzy masterem a kilkoma slave'ami i nie wiem na co się zdecydować.

    A na jakie odległości? Jeżeli większe to SPI raczej się nie nadaje. No chyba że komunikacja ma się odbywać w obrębie jednego układu. Na większe odległości można wykorzystać uart + MAX485 (Link), ethernet lub moduły radiowe RF :).

    0
  • #9 10 Lut 2012 16:57
    Pev4
    Poziom 12  

    Mundi1970 napisał:
    Jeżeli przełożysz SCK na pin INT0 wtedy SPI nie będzie działało. Możesz wykorzystać jakiś wolny port Mastera do wywołania przerwania INT0.

    Nie chodzi mi o przełożenie SCK na INT0, tylko o równoległe połączenie również do tego pinu.

    Mundi1970 napisał:
    A na jakie odległości?

    poniżej 50cm - komunikacja ma się odbywać w obrębie jednego urządzenia z wieloma układami Slave. Musi działać bezbłędnie, gdyż urządzenie jest na początku kalibrowane i pamięta początkowe ustawienia. Nie może się zawiesić, ani zgubić żadnych danych. komunikacja musi odbywać się w obie strony. Planowałem użyć zmodyfikowanego SPI z programowym adresowaniem.

    0
  • #10 10 Lut 2012 17:43
    Mundi1970
    Poziom 24  

    Pev4 napisał:
    Nie chodzi mi o przełożenie SCK na INT0, tylko o równoległe połączenie również do tego pinu.
    To chyba lepiej będzie to to zrobić z linią /SS, przypuszczam że będzie działać (choć mogę się mylić :)). Każdy slave będzie sterowany osobną linią /SS z mastera.

    0
  • #11 10 Lut 2012 19:30
    Pev4
    Poziom 12  

    Tak bym zrobił, ale potrzebuje wiele slave'ów... Ponadto urządzenie może być rozwijane w przyszłości. Komunikacja musi być na równoległej magistrali bez dodatkowych modyfikacji przy dodawaniu kolejnego modułu. Dobry pomysł, żeby tak zrobić z pinem ss. Spróbuje i napisze jak wyszło.

    0
  Szukaj w 5mln produktów