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

[2xAtmega16]+[Bascom]+[RS485]+[Transmisja dwukierunkowa]

FastProject 19 Lip 2009 12:54 4139 6
REKLAMA
  • #1 6796639
    FastProject
    Poziom 28  
    Witam,
    potrzebuję zrobić komunikację miedzy 2 procesorami ATmega16. Jeden wysyła zmienną typu Byte (Status) z informacją o stanie wejść, a 2 to odbiera. Natomiast 2 będzie wysyłał do 1 także zmienną Byte (Settings) z informacjami konfiguracyjnymi. Dodatkowo chciałbym wysyłać sumę CRC w obu kierunkach. Transmisja w obu kierunkach jednocześnie!

    Bity będą miały np takie znaczenie:
    'STATUS: |B7 |B6 |  B5 |  B4 |  B3 |  B2 |  B1 |  B0 |
    '        | 1 | 1 |LIGHT|CLEAN|PROG3|PROG2|PROG1|PROG0|
    
    'SETTINGS WORD:|B7 | B6| B5|   B4  |  B3 |  B2 |  B1 |  B0 |
    '              | 1 | 1 | 1 |SERVICE|BASE3|BASE2|BASE1|BASE0|


    Po przeczytaniu kilku postów wiem, na co zwracać uwagę i co robić jak gubię znaki. W moim przypadku będę prawdopodobnie musiał zrobić transmisje buforowaną.

    Układ do RS485, w który się zaopatrzyłem to MAX490E(full-duplex).

    Ponieważ jest to moja pierwsza przygoda z transmisją danych po RS485 i piszę w Bascom to chciałbym was prosić o wskazanie najlepiej nadającej się do tego celu instrukcji Bascom.

    Jak zwykle mile widziane fragmenty kodów.

    Dotychczas zrobiłem transmisje w następujący sposób:

    Układ 1:
    
    $crystal = 8000000
    $baud = 19200
    Config Serialin = Buffered , Size = 8
    
    Do
       Waitms 5
    
       Print Bin(status);
    
       Do
          Waitms 1
          Received = Ischarwaiting()
          If Received <> 0 Then
             Znak = Inkey()
             Rx_byte = Rx_byte + Chr(znak)
             Incr Bit_number
             If Bit_number = 8 Then
                Received = Binval(rx_byte)
                If Received = 6 Then
                   Added = 777
                   Exit Do
                Else
                   Added = 111
                   Waitms 100
                   Added = 0
                   Waitms 100
                End If
             End If
          End If
       Loop
    
    Loop
    End


    Układ 2:
    
    $crystal = 4000000
    $baud = 19200
    Config Serialin = Buffered , Size = 8
    
    Do
       Waitms 10
    
       Do
          Waitms 1
          Received = Ischarwaiting()
          If Received <> 0 Then
             Znak = Inkey()
             Rx_byte = Rx_byte + Chr(znak)
             Incr Bit_number
             If Bit_number = 8 Then
                Received = Binval(rx_byte)
                If Received = 3 Then
                   Program = 7
                   Exit Do
                Else
                   Program = 11
                   Waitms 100
                   Program = 10
                   Waitms 100
                End If
             End If
          End If
       Loop
    
       Waitms 1
    
       Print Bin(settings);
    
    Loop
    End




    Układy po uruchomieniu odbierają pojedyncze znaki i zbierają je z zmiennej tekstowej Rx_byte, która później (po odebraniu 8 bitów) zamieniana jest na liczbę binarna.

    Najpierw dane wysyła układ 1, a 2 odbiera je z opóźnieniem 10ms. 2 po odebraniu 8 znaków (bitów) wysyła swoje dane (Settings). W tym czasie 1 (po wysłaniu danej Status) czeka już w pętli na te dane, które mają przyjść z 2. Po odebraniu 8 znaków od 2 znowu wysyła swoje dane i sekwencja powtarza się.

    Komunikacja taka działa, po jednoczesnym włączeniu zasilania do obu układów, wtedy jeden (pierwszy) nada swoje dane wcześniej a 2 odbierze je z opóźnieniem i nie ma konfliktu.

    Sprawa komplikuje się gdy np w którymkolwiek momencie zresetujemy jeden z układów. Wtedy układy chyba pozostają w pętli i brak jest wymiany danych.

    A tak przy okazji, czy pobieranie liczby 8bitowej w ten sposób:
           Znak = Inkey()
           Rx_byte = Rx_byte + Chr(znak)
           Incr Bit_number
           If Bit_number = 8 Then
                Received = Binval(rx_byte)
           End If

    jest poprawne, czy nie da się tego zrobić lepiej?

    Połączenie układów wg. schematu niżej. Układy są połączone za pomocą skrętki UTP 8zył około 5m. Ta samą skrętka pozostałymi żyłami przesyłane jest zasilanie +12V(2 żyły) i masa zasilania (2 żyły).
    [2xAtmega16]+[Bascom]+[RS485]+[Transmisja dwukierunkowa]
    Jaką należy tu zrobić komunikacją aby w każdym momencie odłączenie układu sygnalizowany było błędem , a podłączenie nawiązaniem komunikacji, bez utraty danych?

    Pozdrawiam i z góry dziękuje za pomoc.
  • REKLAMA
  • #2 6796821
    gothye
    Poziom 33  
    wprowadź w programie flagę statusu połączenia ,przy odbieraniu danych flaga przyjmowała by wartość 1 ,w przerwaniach od timer wprowadź warunek jesli flaga jest rózna od 0 następuje inkrementacja jej , przy istnieniu transmisi flaga przyjmuje wartość 1 jesli jednak brak transmisji ,w przerwaniach od timera wartość flagi bedzie rosła ,do ilu ? zależy od Ciebie ile ustawisz ,czyli czas po jakim uC stwierdzi że nastąpiło odłączenie od magistrali
  • REKLAMA
  • #3 6796905
    FastProject
    Poziom 28  
    Masz na myśli taki timeout, ok ale co później zrobić po tym czasie timeout? Tu chyba będzie potrzebna jakaś synchronizacja?
  • REKLAMA
  • #4 6796958
    gothye
    Poziom 33  
    wprowadź w komunikacji coś na wzór PING'a ;)

    nawet jesli nic nie wysyłasz a magistrala jest ok posłuży Ci to do diagnostyki
  • #5 6796986
    FastProject
    Poziom 28  
    Hmm kombinuje ale coś mi nie wychodzi, możesz na podanych listingach wyżej dopisać w którym miejscu co trzeba sprawdzać? Już chyba za długo przy tym siedzę i nie mam świeżego umysłu ;)

    Coś już działa:
    Udało mi się wysyłać i odbierać dane w obu uP, ale teraz mam problrm z wysłaniem i odebraniem sumy CRC8. Ponieważ także 1-wszy raz w życiu wykonuje generowanie sumy kontrolnej i sprawdzanie CRC proszę sprawdźcie poprawność kodów:

    1:
    Dim Rx_data(2) As Byte
    Dim Received As Byte
    Dim Timeout As Byte
    Dim Status_string As String * 8
    Dim Crc As Byte
    
    Status = 3
    Status_string = Str(status)
    
    Do
       Crc = Checksum(status_string)
       Printbin Status ; Crc;
    
       Received = Ischarwaiting()
       If Received <> 0 Then
          Inputbin Rx_data(1) , 2
          Crc = Crc8(rx_data(1) , 1)
          If Rx_data(1) = 6 And Crc = Rx_data(2) Then
             Dig1 = 7                                                               'jak transmisja poprawna to '7-ki' na wyświetlaczu
             Dig2 = 7
             Dig3 = 7
             Reset Buzzer
             Timeout = 0
          Else
             Gosub Time_out
          End If
       Else
          Gosub Time_out
       End If
    
    loop
    End
    
    Time_out:
       Waitms 1
       Incr Timeout
       If Timeout > 100 Then
          Dig1 = 11                                                                 'brak transmisji to '---' na wyświetlaczu
          Dig2 = 11
          Dig3 = 11
          Timeout = 0
          Waitms 100
       End If
    Return


    2:
    Dim Rx_data(2) As Byte
    Dim Received As Byte
    Dim Timeout As Byte
    Dim Settings_string As String * 8
    Dim Crc As Byte
    
    Settings = 6
    Settings_string = Str(settings)
    
    Do
       Printbin Settings;
       Crc = Checksum(settings_string)
       Printbin Crc;
    
       Received = Ischarwaiting()
       If Received <> 0 Then
          Inputbin Rx_data(1) , 2
          Crc = Crc8(rx_data(1) , 1)
          If Rx_data(1) = 3 Then                                                    'And Crc = Rx_data(2) Then
             Program = 7                                      'jak transmisja poprawna to '7-ka' na wyświetlaczu 
             Timeout = 0
          Else
             Gosub Time_out
          End If
       Else
          Gosub Time_out
       End If
    
    Loop
    End
    
    Time_out:                                          'brak transmisji to '-' na wyświetlaczu 
       Waitms 1
       Incr Timeout
       If Timeout > 100 Then
          Program = 11
          Timeout = 0
          Waitms 100
       End If
    Return


    Gdy wyłączę sprawdzanie CRC :
     Crc = Rx_data(2) Then
    to układy przesyłają do siebie nawzajem dane i wyświetlają na wyświetlaczach 7-ki. Jak sprawdzam CRC porównując z wysłanym CRC to albo źle generuje to CRC, albo źle coś odbiera. Dodam, że w obu uP wykonywany jest multipleks wyświetlaczy na timerze0.
  • REKLAMA
  • #6 6798733
    FastProject
    Poziom 28  
    Z tego co stwierdziłem, to czy odbieram:

    Inputbin Rx_data(1)
    Inputbin Rx_data(2)

    Czy
    Inputbin Rx_data(1),2

    To zawsze odbiera mi tylko wysłany pierwszy bajt.

    Dodano po 31 [minuty]:

    Kolejna dziwna sprawa:
    Jak wysyłam :

    Send_data = 6
    Printbin Send_data ; 8;<----------wysyłam daną send_data i jakąś liczbę to w odbiorniku obie są poprawnie odbierane i sprawdzane.

    Ale jak wyśle:
    Send_data = 6
    Jakas_zmienna=8
    Printbin Send_data ; Jakas_zmienna;<--------czyli wysyłam zawartości zmiennnych send_data i jakas_zmienna to po odebraniu mam tylko tą pierwszą zmienna send_data.

    I o co tu chodzi?

    Dodano po 40 [minuty]:

    Pytanie:

    Mamy zmienną send_data=7 i generując sumę:

    Send_string=Str(send_data)
    Suma = Checksum(send_string)

    Otrzymam jakąś liczbę, sumę....powiedzmy 111.
    A teraz sprawdzając następnie:

    Utworzona_suma(1)=Suma.....zapisuje do tablicy bo CRC działa na tablicach...wieć

    Crc = Crc8(utworzona_suma(1) , 1)

    powinienem otrzymać wysłaną daną czyli 7 tak?
    Ale wychodzi z tego że nie działa to tak jak bym chciał, albo coś pomijam.


    Obecnie odbieram 2 bajty ale coś z tą sum i jej weryfikacją jest nie tak.
    Wysyłam:
    Send_data = 3
    Send_string = Str(send_data)
    Crc = Checksum(send_string)
    Printbin Send_data;
    Printbin Crc;

    Odbieram:
    Inputbin Rx_data(1) , 2
  • #7 16933291
    Mariane
    Poziom 1  
    Hej, czy ja sie zle uczylem pytam powaznie, moze sie cos zmienilo. Podstawy informatyki mowia, iz bajt jest wyliczalny jako 01234567 do slowa 01234567 01234567
    Poniewaz jest apostrof, rozumiem ze to komentarz.
    Ale co jest z uszeregowaniem ???, czyzby to skladnia jezyka ??? prosze o wyjasnienie. Dziex

    'STATUS: |B7 |B6 | B5 | B4 | B3 | B2 | B1 | B0 |
    ' | 1 | 1 |LIGHT|CLEAN|PROG3|PROG2|PROG1|PROG0|

    'SETTINGS WORD:|B7 | B6| B5| B4 | B3 | B2 | B1 | B0 |
    ' | 1 | 1 | 1 |SERVICE|BASE3|BASE2|BASE1|BASE0|
REKLAMA