Skocz do zawartości

[C] SPI problem z komunikacją


Nider

Pomocna odpowiedź

Witam,
chcę wykonać komunikację między dwoma procesorami Atmega16 (jedna tht druga smd), wszystko połączyłem i zaprogramowałem jak w kursie znalezionym na forbocie, ale niestety przychodzące dane są błędne, wręcz wariują. Przychodzą mi różne wartości, mimo że wysyłam tą samą co chwilę. Sprawdzałem przebiegi na MISO I MISO, MOSI wydaje się ok ładny prostokątny przebieg zaś MISO mam dziwny przebieg. na różnych poziomach napięciowych. Niby jest prostokątny, ale część jest na ok.3V a cześć na 5V pozostałe na 0V. Zamieniałem Mastera ze Slave i to samo.

Link do kursu

https://www.forbot.pl/forum/topics20/programowanie-spi-szeregowy-interfejs-urzadzen-peryferyjnych-vt2275.htm

Pozdrawiam

Link do komentarza
Share on other sites

Takie zachowanie (bardzo dobrze to opisałeś) wskazuje jednoznacznie na konflikt dwóch wyjść. Jedno usiłuje zrobić jedynkę a drugie w tym samym czasie zero. Wychodzi wtedy coś pomiędzy (ok. 2-3V), z jednoczesnym poborem bardzo dużego (jak na porty procesora) prądu.

Dlaczego? Musiałeś coś pokręcić z połączeniami.

Sprawdź, czy jest tak:

Master MOSI → Slave MOSI

Master MISO ← Slave MISO

Master SCK → Slave SCK

czyli nie ma przeplotu linii jak w UART.

Sprawdź też, czy jeden układ na pewno pracuje w trybie MASTER a drugi na pewno w trybie SLAVE.

Upewnij się też, czy Twój programator - jeśli korzysta z SPI - odwiesza swoje linie do stanu wysokiej impedancji gdy nie jest używany albo go po prostu wypnij ze złącza na czas testu.

  • Lubię! 1
Link do komentarza
Share on other sites

Nie rozumiem dlaczego odpięcie jakiejś linii na której stany są OK miałoby poprawić działanie tej złej. A w ogóle to gdzie jest źle? Na nie podpiętej do niczego linii portu?

Zobacz: masz jeden drut. Z jednej strony podłączony do MISO jednego procesora a z drugiej do takiego samego MISO drugiego układu - czy tak jest? Żeby wszystko było OK, tylko jedna strona tego drutu może nadawać, tak? Która? Slave oczywiście, bo linia nazywa się Master Input - Slave Output. Jeżeli sprawisz, że jeden z procesorów będzie pracował w trybie MASTER a drugi w SLAVE to nie ma walca, konfliktu nie będzie. Jeżeli naprawdę nie wiesz co zrobić pokaż schemat (ale taki prawdziwy - jak naprawdę to zrobiłeś) oraz dwa różne programy - te, które rzeczywiście nie działają. Inaczej nic więcej nie zgadniemy.

Sprawdziłem, producent procesora zadbał nawet o to, byś nie musiał ustawiać prawidłowo kierunków portów. Wystarczy, że włączysz SPI bitem SPE, ustawisz odpowiednio tryby Master/Slave bitem MSTR i nie będziesz więcej przy tym grzebał, a reszta zrobi się sama.

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Ok, sprawdziłem wszystko 🙂 Jak zawsze prosty błąd. Jedna jedynka nie w tym miejscu i z wejścia zrobiło się wyjście. Dzięki za pomoc PIWKO leci do Ciebie.

[ Dodano: 22-10-2013, 19:01 ]

Jeszcze jedno pytanie, żeby nie otwierać nowego tematu. Czemu co mniej więcej 8 pomiarów wartość odbierana jest o połowę mniejsza?

Link do komentarza
Share on other sites

Możesz mieć problem z odbiciami sygnału przez niedopasowanie portów do linii przesyłowych i co jakiś czas dostajesz np. jedno zbocze zegara SCK extra. Wtedy wszystko się przesuwa w rejestrze odbiorczym o 1 pozycję w prawo (w jakiej kolejności nadajesz?) i masz model błędu jak na dłoni. Opisz jak to wszystko wygląda. Czy oba układy są na jednej płytce? Jak daleko? Czy po drugiej stronie płytki jest masa? Czy masz jakieś kable łączące? Jakieś zdjęcie?

Nie wspominam o błędzie w programie 🙂

Link do komentarza
Share on other sites

#include <mega16.h>
#include <delay.h>

#define LED_ON PORTD |= 0b10000000;
#define LED_OFF PORTD &= 0b01111111;

char odebrane=0;

char wyniki[255];
int i=0;
void SPI_init_master(void)
{
DDRB |= 0b10110000;
SPCR = ( 1 << SPE ) | ( 1 << MSTR ) | ( 1 << SPR1 ) | ( 1 << SPR0 );
}

void wyslij_bajt(char bajt)
{
SPDR=bajt;
delay_us(100);
while( !(SPSR & 0b10000000) );   
delay_us(100); 

wyniki[i] = SPDR;
i++;

odebrane=SPDR;
if(odebrane==88) LED_ON;
else LED_OFF;
}
void main(void)
{

DDRB |= 0B10000000;

SPI_init_master();

while(1)
{

wyslij_bajt(69);
delay_ms(100);
odebrane=0;
delay_ms(100);
if(i>250) break;
}

}


#include <mega16.h>
#include <delay.h>

char odebrana=0;
int i=0;

interrupt [SPI_STC] void SPI_interrupt(void)
{
//delay_us(200);
odebrana=SPDR;
}

void SPI_init_slave(void)
{
DDRB = 0b01001111;
SPCR = ( 1 << SPIE ) | ( 1 << SPE );
}


void main(void)
{


SPI_init_slave();
SREG |= 0b10000000;

while(1)
{
SPDR=88;
}
}

Program CodeVision.

Na 2 osobnych płytkach są procesory. Kabel ok 1,5m. cienka skrętka.

Sprawdziłem oscylogramy i mam dość duże picki na SCK max 1,5V

Niestety nie przewiduję krótszych może w przyszłości RFM12.

Myślałem o pierścieniach ferrytowych na przewody, ale nie mam pod ręką niestety.

Nie mam pojęcia ile to pomoże, ani pomysłu jak inaczej mogę pozbyć się picków. Pierwszy raz borykam się z zakłóceniami. Dlatego dzięki za cierpliwość.

Masy są ze sobą zwarte.

[ Dodano: 22-10-2013, 20:40 ]

Wszystkie zasilania są filtrowane zarówno od tętnień 220uF i od wysokich czętotliwości 100nF na każdym zasilaniu AVR i za każdym półprzewodnikiem

Link do komentarza
Share on other sites

E tam, każdy prędzej czy później o to się potyka. Raz sobie poczytasz jakiś dobry artykuł i będzie na zawsze.

W skrócie jest tak: sygnały na swojej drodze nie lubią zmian impedancji toru przesyłowego. Każda skokowa zmiana powoduje podział energii - część idzie dalej a część odbija się od "uskoku" i wraca jak echo. Im więcej się odbije tym mniej pójdzie dalej, to jasne. W takiej skrętce jak Twoja nie ma po drodze raczej żadnych niejednorodności, ale są końce. Z jednej strony masz port wyjściowy procesora, czyli nadajnik. Z drugiej port wejściowy czyli odbiornik. Można przyjąć, że sama skrętka ma impedancję ok 120Ω. No i teraz nadajnik o impedancji wyjściowej raczej małej, np. 20Ω wpuszcza zbocze sygnału do linii. Wędruje sobie to zbocze przez skrętkę aż tu nagle widzi koniec. Ponieważ impedancja odbiornika jest bardzo duża, praktycznie możemy przyjąć, że nieskończona to wszystko co przyleciało odbija się z powrotem. Port wejściowy oczywiście zbocze zobaczył i je zaliczył ale to nie koniec historii. Powracające echo dolatuje do początku, tam znów widzi uskok impedancji (120Ω → 20Ω stale włączonego nadajnika sygnału) więc znów się odbija i tak wiele razy. Ile? Na szczęście skrętka tłumi sygnał więc jest tego coraz mniej. U Ciebie - skoro piszesz, że widzisz jeden dzwon 1.5V - to pewnie dwa-trzy razy choć kolejne są na tyle słabe, że już ich nie liczysz. Oczywiście są na to odpowiednie reguły mówiące o tym czy echo robi się w fazie czy w przeciwfazie, wzory na wielkości amplitudy w zależności od wielkości uskoku impedancji, diagramy graficzne dla tych co nie chcą liczyć a "linia długa" - bo tak to się nazywa jest jednym z podstawowych elementów w programach do symulacji.

Teraz najważniejsze: co możesz zrobić? Pewnie już sam czujesz: musisz po prostu dopasować końce skrętki do jej impedancji charakterystycznej. Wtedy nic się nie odbije i sygnały będą czyste. Jak? Są dwa podstawowe sposoby i ich kilka odmian.

1. Dopasowanie po stronie nadajnika. Szeregowo z wyjściem portu procesora dajesz opornik taki, by w sumie z impedancją tego portu wyszło 120Ω. Spokojnie możesz spróbować ze 100Ω przy wyjściu SCK z MASTERa, MOSI z Mastera i MISO ze Slave'a. Dopasowanie nadajnika nie poprawia tego, że odbiornik nadal ma nieskończoność i tam wszystko się odbije, prawda? Tylko że teraz powracające echo "zobaczy" 120Ω nadajnika i nic już nie wróci. Odbiornik dostanie tylko jedno, czyste zbocze.

2. Dopasowanie po stronie odbiornika. Równolegle z wejściem portu procesora (np. do masy) dajesz opornik taki, by było dopasowanie czyli 120Ω. Teraz już pierwsze przejście zbocza sygnału przez linię zostanie całkowicie pochłonięte przez rezystor dopasowujący po stronie odbiorczej i nic nie wróci. Proste?

Każde z tych rozwiązań ma swoje plusy dodatnie i plusy ujemne - jak to mówią, ale nie chcę tego tutaj rozwijać. Wszystko jest w literaturze. Spróbuj tego które Ci się podoba - wystarczy tylko jedno z nich i napisz o wynikach. Pamiętaj, by dobrze określić co jest nadajnikiem a co odbiornikiem linii bo od tego w ogóle zależy działanie tych metod.

Pierścienie ferrytowe to w ogóle nie ten przypadek, zapomnij.

Zakładam, że skrętka to para skręconych przewodów z których jeden to masa a drugi to linia sygnałowa i takich par masz trzy, tak? Albo chociaż płaska taśma z masą na co drugim przewodzie. Inaczej to nie ma sensu.

Kodu nie oglądałem - zakładam, ze skoro tyle działa w tak prostym programie to raczej nie zrobiłeś błędu polegającego na złej obsłudze co 8 bajtu 🙂 Może ktoś z Kolegów programujących z zamkniętymi oczami rzuci na to okiem (otwartym)?

Link do komentarza
Share on other sites

Nie mam już siły do tego SPI. Wstawiłem szeregowo oporniki 100ohm , zmieniłem przewód na 4x0,25 w ekranie (taki szary). Przebiegi wyglądają teraz naprawdę dobrze. Szumy na poziomie 400mV. A problem pozostaje dalej nie rozwiązany.

Myślałem nad tym, aby wstawić diodę na linię SCK w kierunku Master->Slave, żeby echo się nie odbijało i odciąć szumy mniejsze od 0,6V. Fakt, że sygnał zegarowy też by się zmniejszył, ale 4,4V Slave dalej powinien widzieć.

Dzisiaj wstawię tą diodę i zobaczymy jak to wyjdzie. Na razie nie działa :/

Link do komentarza
Share on other sites

Tutaj nie ma miejsca na żadne diody a przynajmniej nie w ten sposób. Myśl o impedancji linii przesyłowej a nie o urywaniu 0.7V składowej stałej - to zupełna pomyłka. Najlepiej przeczytaj jeszcze raz co napisałem wcześniej. Jeśli to naprawdę rozumiesz, powinieneś sobie poradzić.

Pokaż dokładny, prawdziwy schemat tego, co już zrobiłeś (nie wszystko, tylko obie strony SPI wraz z opornikami) i może jakieś zdjęcie?

Kabel nie musi być ekranowany ale musi być skrętką: każda para masa-sygnał osobno skręcona.

Jak to szumy 400mV?

Dawaj obraz z ocyloskopu dla tego konkretnie schematu. Pokaż przede wszystkim koniec którejś linii z masą sondy zapiętą dokładnie na masie tej strony, którą mierzysz plus oznacz miejsce na schemacie z którego pokazujesz przebieg. I nie wymyślaj już żadnych diodek, to nie żadna magia - nie takie rzeczy przecież przesyła się po kablach, ale też nie zabawa w szkółkę elektroniczną.

EDIT: Acha, i opisz dokładnie co nie działa, objawy.

EDIT2: Jak to przewód 4x0.25??? Moim zdaniem dla 3 sygnałów ma być minimum 6 żył. Jakim cudem zmieściłeś się w 4? Podałem Ci wyraźne reguły.

Link do komentarza
Share on other sites

Problem rozwiązałem stosując skrętkę 3 pary i pisząc swoje SPI. Nie mam żadnych problemów. Nigdy nie przychodzi wadliwa informacja. Nie miałem już sił do sprzętowego SPI, a własna komunikacja daje radę.

Dzięki za pomoc

Link do komentarza
Share on other sites

Acha, czyli w odbiorniku (bo to jest krytyczna część) programowo badasz stan linii zegara i po wykryciu odpowiedniego zbocza wczytujesz kolejny bit danych? No tak, to działa bo metoda nie jest czuła na zbocza tylko na poziom. W czasie (tym najciekawszym 🙂 ) kiedy odbywa się "ruch" w linii transmisyjnej, zbocza wędują z lewa na prawo i następuje powolne wygaszanie odbić Twój program nie jest w stanie (i dobrze) zauważyć tych "fajnych" zjawisk. Po prostu w kilka us po zmianie zegara wczytuje daną i już.

OK, dobrze, że zadziałało choć szkoda, że nie rozwaliłeś tego jak na to zasługiwało. Nie zawsze da się tak obejść a i prędkość transmisji jest pewnie o rząd wielkości mniejsza - co tu pewnie nie jest problemem.

Link do komentarza
Share on other sites

Dokładnie działa to tak jak mówisz. Nie straciłem prędkości transmisji nadal w granicach 170kHz. No też ubolewam, że nie udało się tego rozwiązać inaczej, ale trzeba sobie jakoś radzić.

Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.