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

[atmega16][bascom] - obsługa nadajnika odbiornika RS485

ditomek 08 Sty 2012 15:27 1611 2
REKLAMA
  • #1 10367414
    ditomek
    Poziom 22  
    Witam.
    Miałem dwie atmegi spięte przez port szeregowy. Full duplex.
    Master, wysyłał do slave znak "Q" a w odpowiedzi otrzymywał stan wszystkich ośmiu bitów wybranego portu.
    Master odebrany komunikat wysyłał na port i zapalał LEDy.
    Ukłąd prosty. Wszystko działało przepięknie.
    Odbieranie znaków w układach master i slave realizowałem przerwaniem od URXC
    W momencie przejścia na interface 485 pojawiły się problemy.
    Wiadomo ze sterowanie (w moim przypadku driverem RS485 jest DS96176CN) nadawaniem odbiorem musi uwzględniać przełączanie z nadawania w odbiór ina odwrót.
    Niestety wydawałoby się prosty kod trzeba było uzupełnić o dwie komendy wait.
    Fragment kodu mastera wysyłający znak Q
    portc.0 = 1
    waitms 5
    print "Q"
    waitms 4
    portc.0 = 0

    na porcie C.0 wisi sterowanie 485, dlatego przed wysyłaniem przełączam kość w nadawanie stanem 1.
    po wysłaniu znaku wracam do odbioru wpisując na port 0.
    sam kod banalnie prosty, niestety mimo to układ na początku wysyłał brednie.
    metodą prób i błędów ustaliłem ze czekając 5 ms przed i po wysłaniu znaków transmisja odbywa sie prawidłowo.

    po wpisaniu tych komend do nadajnik i odbiornika układ działa jak powinien.

    szukając rozwiązania problemu znalazłem taki kod
    portc.0 = 1
    waitus 200
    print "Q"
    waitms 2
    portc.0 = 0

    opóźnienie w jednym układzie slave rzędu 10 ms trochę mnie niepokoi bo w sytuacji kiedy na magistrali jest kilkadziesiąt kości nazbiera się z tego prawie sekunda.
    Wydaje mi sie ze problemem jest sama komenda print, której chyba nie do końca rozumiem.
    Może ręczne przepisywanie zmiennych do rejestru nadawczego i odczyt przerwania by pomógł....
    A może to zupełnie coś innego.

    Nie wklejam całości kodu bo nie ma sensu zaśmiecać tekstu niepotrzebnymi fragmentami które działają jak należy...

    Chętnie wysłucham Waszego zdania.

    Pozdrawiam
    Ditomek
  • REKLAMA
  • #2 10370220
    ditomek
    Poziom 22  
    po krótkiej kalkulacji wychodzi, że przy prędkości 9600 jeden znak wysyła się przez około jedną ms. W takim razie wysłanie 9 znaków (plus 2 na przejście do nowej linii) to ponad 10ms.

    Rozpisałem printa na składowe elementarne.

    Poniżej wysyłam toś takiego "A00000000<lf><cr>"

    Sub wyslij

    Portc.0 = 1
    waitus 10

    udr = 65
    waitus dly
    udr = Pinb.7 + 48
    waitus dly
    udr = Pinb.6 + 48
    waitus dly
    udr = Pinb.5 + 48
    waitus dly
    udr = Pinb.4 + 48
    waitus dly
    udr = Pinb.3 + 48
    waitus dly
    udr = Pinb.2 + 48
    waitus dly
    udr = Pinb.1 + 48
    waitus dly
    udr = Pinb.0 + 48
    waitus dly
    udr = 10
    waitus dly
    udr = 13
    waitus dly
    waitus dly

    portc.0 = 0
    End Sub

    End

    jak widać musiałem użyć wait po wpisaniu w rejestr kolejnego znaku (const dly=999). Nadal nie rozumiem dlaczego po wysłaniu ostatniego znaku czas oczekiwania do przełączenia sie w odbiór musi być dwukrotnie większy.
    chciałem zastąpić waitus czymś takim

    while UCSRA.txc = 0
    waitus 10
    wend

    niestety nie działa....
  • #3 10371015
    ditomek
    Poziom 22  
    mam nadzieje ze to ktoś czyta :)

    While raczej nie będzie działało bo jest źle zastosowane...

    Może coś takiego:

    do
    waitus 10
    loop until UCSRA.TXC=0

    srawdzę w domu...

    PS
    zastanawiam się czy to ze nikt nie odpisuje to wynik mojego geniuszu czy głupoty
REKLAMA