Witam!
Usilnie próbuje opracowąć protokół komunikacji miedzy wieloma węzłami w sieci RS485 multimaster. Węzły zbudowane są za pomocą AtMega8. Ramka wyglada tak:
1 bajt - długosć ramki
2 bajty - adres odbiorcy (word)
2 bajty - adres nadawcy (word)
x bajtów - dane właściwie
1 bajt suma kontrolna z wszystkich poprzednich
Transmisja odbywa się na prędkosci 19200bps przy użyciu transcieverów MAX1483. Uporałem się z przypadkiem, gdy jeden z węzłów chce nadawać w momencie, gdy inny już nadaje, poprzez sprawdzanie ile czasu minęło od odebrania poprzedniego bajtu. Jeśli ten czas jest wystarczajaco duży, to uC uznaje ze linia jest wolna i nadaje, a jak nie, to kręci się w kółko aż ustalony czas minie.
Teraz męczę się z przypadkiem, gdy obydwa węzły miałyby ochotę nadawac w tym samym czasie. Wpadłem na pomysł, żeby automatycznie po wysłaniu wiadomości, odczytywać kolejne bajty tej wiadomosci. Coś na zasadzie feedbacku, sprzężenia zwrotnego, bo przecież wszystko co się pojawia na magistali może byc od razu odebrane przez wszystkie wężły - jak i przez węzeł nadający właśnie w celu sprawdzenia, czy to co miało zostać wysłane, zostało odebrane (a nie że przypadkiem 2 ramki się nałożyły na siebie).
Jeśli chodzi o kod, to fragment odbioru danych (wykonywany po przerwaniu Urxc):
Natomiast to jest fragment odpowiedzialny na wysyłanie:
Pod PORTD.3 podpięte jest wejscie uaktywniajace nadajnik w MAX'ie.
Pod każde inne wyjście występujące w kodzie podpięte są diody.
Ramka która jest wysyłana z urządzenia na komputerze jest odbierana w postaci:
9 - Długośc ramki
234 - Pierwszy bajt Odbiorcy (60000)
96 - Drugi bajt Odbiorcy (60000)
0 - Pierwszy bajt Nadawcy (1)
1 - Drugi bajt Nadawcy (1)
8 - Dane
0 - Dane
1 - Dane
93 - Suma kontrolna (Suma wszystkich poprzednich mod 256)
Natomiast sam węzeł widzi odebrane przez siebie dane w postaci:
234
234
234
234
234
234
234
234
234
Czy ktos ma jakiś pomysł co może powodowac takie zachowanie? Czy bascom/MAX1483/mega8 mają jakieś problemy z nadawaniem i równoczesnym odbieraniu danych w tym samym momencie? Z góry dzięki za pomoc:)
PS. Wcześniej dałem ten wątek do Milkrokontrolery AVR, ale właściwie to nie jest problem z uC, tylko z transmisją danych, dlatego wrzucam to tutaj...
Do moderatorów. Proszę o nie usuwanie na razie żadnego z wątków. Po uzyskaniu właściwiej odpowiedzi będzie można usunąć mniej konstruktywny wątek.
Usilnie próbuje opracowąć protokół komunikacji miedzy wieloma węzłami w sieci RS485 multimaster. Węzły zbudowane są za pomocą AtMega8. Ramka wyglada tak:
1 bajt - długosć ramki
2 bajty - adres odbiorcy (word)
2 bajty - adres nadawcy (word)
x bajtów - dane właściwie
1 bajt suma kontrolna z wszystkich poprzednich
Transmisja odbywa się na prędkosci 19200bps przy użyciu transcieverów MAX1483. Uporałem się z przypadkiem, gdy jeden z węzłów chce nadawać w momencie, gdy inny już nadaje, poprzez sprawdzanie ile czasu minęło od odebrania poprzedniego bajtu. Jeśli ten czas jest wystarczajaco duży, to uC uznaje ze linia jest wolna i nadaje, a jak nie, to kręci się w kółko aż ustalony czas minie.
Teraz męczę się z przypadkiem, gdy obydwa węzły miałyby ochotę nadawac w tym samym czasie. Wpadłem na pomysł, żeby automatycznie po wysłaniu wiadomości, odczytywać kolejne bajty tej wiadomosci. Coś na zasadzie feedbacku, sprzężenia zwrotnego, bo przecież wszystko co się pojawia na magistali może byc od razu odebrane przez wszystkie wężły - jak i przez węzeł nadający właśnie w celu sprawdzenia, czy to co miało zostać wysłane, zostało odebrane (a nie że przypadkiem 2 ramki się nałożyły na siebie).
Jeśli chodzi o kod, to fragment odbioru danych (wykonywany po przerwaniu Urxc):
Port:
Buff = Inkey() 'odczytanie bajtu
Bit_order_count = 0
If Pind.3 = 0 Then 'jeśli nie nadajemy (obca wiadomosć)
Verif = Verif + Buff 'Zliczamy sume kontrolną
Tbuff(index) = Buff 'wpisujemy dany bajt do tablicy
If Index = 1 Then 'Jeżeli jest to pierwszy bajt w ramce
Leng = Buff 'Ustawiami długośc ramki
Isbusy = 1 'Flaga zajętości linii (nie możemy w tym momencie niczego wysłać)
End If
If Leng = Index Then 'jeżeli została osiągnieta długosć ramki
Isbusy = 0 ' flaga zajętosci - można już nadawać jeśli trzeba
Verif = Verif - Buff ' usuwamy z sumy kontrolnej sume kontrolną (ostatni bajt któwy w tą sumę nie wchodzi
If Verif = Buff Then 'jezeli suma kontrolna zgadza się z ostatnim bajtem
Sendid = Tbuff(2); ' składanie adresu odbiorcy z 2 bajtów do zmiennej word
Shift Sendid , Left , 8
Sendid = Sendid + Tbuff(3)
If Sendid = Id Then Isramkaok = 1 ' Jeżeli id odbiorcy zgadza się z ID urządzenia, ustaw flagę, że ramka jest ok.
End If
Index = 1 ' przygotowanie do odbioru następnej ramki
Verif = 0
Else
Incr Index 'jeżeli nie została osiągnieta długosc ramki, zwiększaj index
End If
Else ' jeżeli nadajnik włączony = to nasza wiadomosć, i musimy sprawdzić czy się zgadza z tym co nadajemy
Thelp(erro) = Buff
Incr Erro
End If
Return
Natomiast to jest fragment odpowiedzialny na wysyłanie:
Portd.3 = 1 'włączenie nadajnika
Dlug = Dlug + 5 'dodanie do długosci danych długosci narzutu (id odb, id nad, suma)
Tbuffout(dlug + 1) = 0 ' czyszczenie sumy kontrolnej
Tbuffout(1) = Dlug + 1 ' ustawienie końcowej dlugosci ramki
Tbuffout(2) = High(adres) 'konwersja word do bajtów ramki
Tbuffout(3) = Low(adres)
Tbuffout(4) = High(id)
Tbuffout(5) = Low(id)
For I = 1 To Dlug ' generowanie sumy kontrolnej
Tbuffout(dlug + 1) = Tbuffout(dlug + 1) + Tbuffout(i)
Next I
Incr Dlug
Erro = 0
For I = 1 To Dlug ' wysyłanie kolejnych bajtów wiadomosci
Print Chr(tbuffout(i));
Next I
Waitms 1
For I = 1 To Dlug ' wysyłanie feedbacku (tego co sami odczytaliśmy z wiadomosci którą wysyłaliśmy)
Print Chr(thelp(1));
Next I
Waitms 1
Portd.3 = 0 ' wyłączenie nadajnika
Verif = 0
Pod PORTD.3 podpięte jest wejscie uaktywniajace nadajnik w MAX'ie.
Pod każde inne wyjście występujące w kodzie podpięte są diody.
Ramka która jest wysyłana z urządzenia na komputerze jest odbierana w postaci:
9 - Długośc ramki
234 - Pierwszy bajt Odbiorcy (60000)
96 - Drugi bajt Odbiorcy (60000)
0 - Pierwszy bajt Nadawcy (1)
1 - Drugi bajt Nadawcy (1)
8 - Dane
0 - Dane
1 - Dane
93 - Suma kontrolna (Suma wszystkich poprzednich mod 256)
Natomiast sam węzeł widzi odebrane przez siebie dane w postaci:
234
234
234
234
234
234
234
234
234
Czy ktos ma jakiś pomysł co może powodowac takie zachowanie? Czy bascom/MAX1483/mega8 mają jakieś problemy z nadawaniem i równoczesnym odbieraniu danych w tym samym momencie? Z góry dzięki za pomoc:)
PS. Wcześniej dałem ten wątek do Milkrokontrolery AVR, ale właściwie to nie jest problem z uC, tylko z transmisją danych, dlatego wrzucam to tutaj...
Do moderatorów. Proszę o nie usuwanie na razie żadnego z wątków. Po uzyskaniu właściwiej odpowiedzi będzie można usunąć mniej konstruktywny wątek.