Elektroda.pl
Elektroda.pl
X

Wyszukiwarki naszych partnerów

Wyszukaj w ofercie 200 tys. produktów TME
Europejski lider sprzedaży techniki i elektroniki.
Proszę, dodaj wyjątek elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

ATmega8 x2 SPI - Niestabilna komunikacja po SPI dwóch procesorów

Karol966 23 Lis 2012 20:17 2460 7
  • #1 23 Lis 2012 20:17
    Karol966
    Poziom 30  

    Witam

    Buduje pewne urządzenie składające się z dwóch procesorów Atmega8 oraz ATmega16 (aktualnie 2x mega8). Jeden z procesorów jest odpowiedzialny wyłącznie za multipleksowanie 10 wyświetlaczy 7seg. Jest to taki panel wyświetlaczy. Drugi jest odpowiedzialny za obsługę całego urządzenia oraz wysyłanie danych po SPI do drugiego procesora (slave = wyświetlacz).
    Na samym początku slave był na Atmedze32 no i wtedy zwykle działało wszystko poprawnie jednak z czasem też coś się działo z ramką danych i na wyświetlaczu pojawiały się krzaki.

    Podaje kody, najpierw master ale tu na razie nic praktycznie nie ma:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    To tylko wysyłanie sztywnych danych, DP służy do zapalenia dwukropka na jednym z wyświetlaczy właśnie do wyświetlania czasu.
    Program dla slave wygląda skrótowo tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Program w teorii powinien po obraniu 9 bajtów delikatnie porozdzielać dane i wyświetlić je na wyświetlaczach LED. Jednak ramka danych rozjeżdża mi się całkowicie. na pozycji cyfra10 mam wyświetlą de facto liczbę odebranych bajtów danych i widzę jak cięgle się zmienia. Tym samym wyświetlacz wyświetla głupoty.
    Co może być tego przyczyną? Przewody ma "byle jakie", kawałek skrętki o długości ok 20cm (domyślnie chciałbym dać taśmę ok 1.5m dlatego prędkość taktowania SPI jest dzielona przez 128).

  • #2 25 Lis 2012 23:49
    dondu
    Moderator Mikrokontrolery Projektowanie

    Karol966 napisał:
    Tym samym wyświetlacz wyświetla głupoty.
    Co może być tego przyczyną? Przewody ma "byle jakie", kawałek skrętki o długości ok 20cm (domyślnie chciałbym dać taśmę ok 1.5m dlatego prędkość taktowania SPI jest dzielona przez 128).

    SPI na 1.5m (?) - pokaż lepiej schemat i podaj częstotliwość taktowania mikrokontrolera.
    Programu nie sprawdzałem.

  • #3 26 Lis 2012 00:11
    mattsk
    Poziom 12  

    Witam, większość moich problemów z komunikacją SPI było związanych z ustawieniem pinu Select Slave (niestabilność działania, krzaki itd..) więc w pierwszej kolejności na to bym popatrzył.

  • #4 26 Lis 2012 11:12
    Karol966
    Poziom 30  

    Taktowanie 8MHz, dzielnik CLK=Fcpu/128 = 62,5kHz. Wiem, że przewód jest długi, napisałem 1,5m a mam 2,2m no i w końcu zaczęło działać chociaż nie wiem dla czego pierwszy bajt transmisji jest nie tym co wysyłałem. Teraz w przerwaniu tylko sprawdzam czy w buforze znajduję się znak końca ramki oraz czy długość bufora jest większa niż liczba transmitowanych bajtów. Pierwotnie miałem tak, że sprawdzałem początek bufora, koniec oraz długość, tzn szukałem początku i końca ramki przy założonej jej długości no i nic nie działało (potem dopiero sprawdziłem ,że bufor[0] wcale nie zawiera pierwszego transmitowanego bajtu danych a zwykle 0. Teraz robię to tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Pierwsza pozycja w buforze minPos = 1.
    Nie podoba mi się obsługa tego przerwania przez te dodatkowe if-elsy na końcu ale na razie nie mam pomysłu na dodatkowe zabezpieczenie przed śmieciami.

    mattsk o co dokładnie Ci chodzi? O to aby ręcznie w programie slave ustawić pin SS jako wejście?

    Tak jak napisałem wyżej układ mi działa poprawnie, cały dzień pracował bez najmniejszego objawu niestabilności. Dla bezpieczeństwa użyję przy masterze kwarcu np 4MHz by chociaż o połowę zmniejszyć prędkość transmisji SPI chociaż skoro teraz działa a później przewód będzie krótszy to może nie ma takiej potrzeby. Z drugiej strony i tak mam bardzo długi przewód więc projektując PCB wyprowadzę też RS232 oraz dodatkowo INT0 by napisać programową obsługę rs'a dla mastera (sprzętowy będzie zajęty) lub własną, prostą komunikację.

    Zastanawiam się w jaki sposób z np bufora o długości np 2-3 razy większej niż długość rami danych wyodrębnić właściwą ramkę danych z dowolnego miejsca bufora. Zakładam, że mam znak początku i/lub końca ramki oraz wiem jaka ma być długość. Jest na to jakaś sprawdzona metoda? Czy po prostu szukam początku ramki, potem do indeksu pod którym znalazłem znak początku ramki dodaję długość ramki no i sprawdzam czy pod tym indeksem znajduje się w buforze znak końca ramki. Jeżeli tak to raczej jest to właściwa ramka danych. Dobrze myślę?

  • #5 26 Lis 2012 12:04
    tmf
    Moderator Mikrokontrolery Projektowanie

    Przede wszystki zmniejszenie częstotliwości SCK nie ma wielkiego wpływu na jakość transmisji. Ważna jest nie częstotliwość a stromość zboczy, a ta jest niezależna od oczęstotliwości. Aby to działało poprawnie (przy 2 m SPI to i tak może działać tylko na zasadzie szczęścia) warto byłoby ograniczyć stromość zboczy - np. jakiś kondensator itd. Lub wręcz dedykowany driver do linii długiej. Co do detekcji początku ramki - od tego jest sygnał SS, on też określa konie. Aktywacja SS określa początek, a deaktywacja koniec nadawanej ramki.

  • #6 26 Lis 2012 12:09
    Karol966
    Poziom 30  

    tmf napisał:
    Co do detekcji początku ramki - od tego jest sygnał SS, on też określa konie. Aktywacja SS określa początek, a deaktywacja koniec nadawanej ramki.


    Tak, jest jak piszesz ale co w przypadku gdy chcę mieć dłuższy bufor danych niż ramka? Dlaczego mogę potrzebować bufora, a to dlatego, że jeżeli procesor wyświetlacza włączyć się później/ zostanie zresetowany przez watchdoga lub cokolwiek innego wówczas może złapać tylko kawałek ramki. Sygnał SS będzie aktywny, obierze np połowę ale uzna, że odebrał całą (chyba, że sprawdzę wtedy długość odebranej ramki).

  • #7 26 Lis 2012 16:14
    tmf
    Moderator Mikrokontrolery Projektowanie

    Przecież SPI to komunikacja dwukierunkowa. W efekcie master wystarczy, że sprawdzi odebrany bajt - slave wyłączony to odbiera 0xff co sygnalizuje problem. Na to master resetuje transmisję poprzez ustawienie i po jakimś czasie wyzerowanie SS. Oczywiście slave musi coś wystawiać, sensownym pomysłem jest np. ostatnio odebrany bajt, dzięki temu master kontroluje poprawność odbioru. Dla ciebie to o tyle istotne, że przy tak długim połączeniu nie masz żadnej gwarancji poprawnego odbioru.

  • #8 27 Lis 2012 00:58
    Karol966
    Poziom 30  

    Wiem, że ostro nagiąłem długość połączeń dlatego dziś zaprojektowałem pcb z wyjściem RS-232 + dodatkowy wyprowadzony pin INT0 (dla w ostateczności własnej komunikacji). Fak SPI jest typu full duplex to ja u siebie zauważyłem (zapewne przez ten długi przewód), że gdy mam podłączony przewód MISO to czasami slave wyświetla śmieci. Z tego powodu odłączyłem przewód od MISO, używam tylko MOSI, SCK, CS.
    Dla pewności - nie podoba mi się to rozwiązanie dlatego na 90% z niego zrezygnuje i zastosuje najchętniej RS-232. Później pobawię się CRC i chyba juz wyeliminuje potencjalne źródła błędów.
    PS. W brew wszelkim pozorom i obawom układ działa już trzeci dzień bez najmniejszego błędu.
    Przy okazji pytanie do tmf W swojej książce opisałeś programowanei wielu procesorów 1 gniazdem ISP. O ile mnie pamięć nie zawodzi (a czytałem to zdaje się dość dawno) to napisałeś, ze można to wykonać odłączając jedynie linię SCK (zwierać wybraną linię danego procka na czas programowania). Przetestowałem ten sposób u siebie teraz i niestety nie zadziałał (a chyba powinien bo w końcu każdy procesor ma RESET aktywny).
    W zeszłym roku zbudowałem układ na 14 procesorach ATmega8 programowanych przez 1 gniazdo ISP jednak rozwierałem/ zwierałem przyciskami sygnał RESET. Nie miałem wtedy z tym żadnych problemów. Zapewne dla tego, że nie używałem tych linii do niczego innego.
    Tym razem rozłączając SCK często miałem np błąd sygnatury lub błąd weryfikacji kodu.

 Szukaj w ofercie
Zamknij 
Wyszukaj w ofercie 200 tys. produktów TME