Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[Bascom] RS485 - Master nadaje - slave nie odsyła

maximus22_kr 28 Gru 2011 23:57 3034 15
  • #1 28 Gru 2011 23:57
    maximus22_kr
    Poziom 18  

    Witam
    Atmega328 i Attiny2313 przez RS485

    Atmega328 Master - zapis na razie wyzwalany przez Timer

    Code:

    If Flaga_001 = 1 Then
    Set Re_de
    Waitms 1
    Print "MOD001 " ; Chr(13);
    Waitms 1
    Reset Re_de
     Flaga_001 = 0
     Licznik_mod001 = 0
    End If


    ATtiny2313 Slave
    Code:

    $regfile = "attiny2313.dat"
    $crystal = 8000000
    $baud = 4800

    '********************* Konfiguracja magistrali 1-Wire
    Config 1wire = Portd.5

    '*********************
    Config Serialin = Buffered , Size = 12 , Bytematch = 13
    Enable Interrupts

    '********************* Konfiguracja wejść i wyjść

    Config Portd.2 = Output                                     ' sterowanie RS485
    Reset Portd.2
    '********************* Deklaracje zmiennych
    Dim Dsid1(8) As Byte
    Dim Dsid2(8) As Byte
    Dim I1 As Integer
    Dim I2 As Integer
    Dim Flaga_rs As Bit
    Dim Tx As String * 7
    Dim Tx1 As String * 7

    Declare Sub Odczytaj
    Flaga_rs = 0
    Re_de Alias Portd.2

    '********************* Adres pierwszego DS18B20
    Dsid1(1) = &H28
    Dsid1(2) = &H9F
    Dsid1(3) = &H79
    Dsid1(4) = &H25
    Dsid1(5) = &H03
    Dsid1(6) = &H00
    Dsid1(7) = &H00
    Dsid1(8) = &H00

    '********************* Adres drugiego DS18B20
    Dsid2(1) = &H28
    Dsid2(2) = &H24
    Dsid2(3) = &H47
    Dsid2(4) = &H25
    Dsid2(5) = &H03
    Dsid2(6) = &H00
    Dsid2(7) = &H00
    Dsid2(8) = &HD9

    Do

    '********************* odczyt pierwszego DS18B20
       1wreset
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       I1 = 1wread(2)

       Waitms 750
    '********************* odczyt drugiego DS18B20
       1wreset
       1wwrite &H55
       1wverify Dsid2(1)
       1wwrite &HBE
       I2 = 1wread(2)
       Waitms 750
    '********************* konwersja dla wsaystkich DS18B20
       1wreset
       1wwrite &HCC
       1wwrite &H44
     Waitms 750

    If Flaga_rs = 1 Then
      Input Tx
      Flaga_rs = 0
    End If

    Tx1 = Mid(tx , 1 , 6)

    If Tx1 = "MOD001" Then
     Gosub Odczytaj
    End If

    Loop
    End

    '*********************** Obsługa bufora UART
    Serial0charmatch:
    Flaga_rs = 1
    Return

    Sub Odczytaj
    Set Re_de
    Waitms 1

    Print "MOD001" ; I1 ; "," ; I2 ; Chr(13);
    Waitms 1
    Reset Re_de

    End Sub


    Wpięcie się PC-tem pomiędzy układ RS485 i ATtiny2313 - mam na konsoli MOD001. Ale Attiny2313 nie raczy nic odpowiedzieć. Chyba nie przeszkadza mu to, że początki ciągu są takie same ?

    Połączone kablem płaskim czterożyłowym z wtykami RJ11, oprócz sygnałów A i B jest GND

    0 15
  • #2 29 Gru 2011 08:23
    FastProject
    Poziom 28  

    Spróbój ustawić kierunki portów TxD i RxD w attiny na odpowienio wejściowy i wyjściowy-może to to.

    Po 2 spróbój dać większe opóźnienie po:

    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod


    Nie 1ms a może 10ms...nie liczyłem czasu wysyłania danych, ale może w ciągu 1ms dane nie zdążą przejść?

    0
  • #3 29 Gru 2011 13:14
    maximus22_kr
    Poziom 18  

    może dam obsługę LED- żeby zaświecił jak przetworzy ?

    Jeśli dochodzi do układu RS485, tzn, że kabel zaciśnięty dobrze - bo terminal w PC pokazuje string.

    Mierzyłem napięcie na końcówkach RE-DE. W Atmega328 pojawia się, natomiast w Attiny2313 nie - więc chyba coś z odbiorem a raczej z analizą stringu przychodzącego od Atmega328 jest nie tak.

    0
  • #4 29 Gru 2011 14:17
    jousto
    Poziom 16  

    A co jaki czas w Master uruchamiany jest Timer?

    0
  • #5 29 Gru 2011 14:29
    maximus22_kr
    Poziom 18  

    Na razie testowo co jakieś 15 sekund. Docelowo co 10 minut

    0
  • #6 29 Gru 2011 14:40
    jousto
    Poziom 16  

    Tu poniżej jest nieźle namieszane

    '*********************** Obsługa bufora UART
    Serial0charmatch:
    Flaga_rs = 1
    Return

    Odbiór bufora i przepisanie do zmiennej Tx powinien zostać wykonany w całości w tym przerwaniu, a nie ustawiana flaga że coś jest w buforze a potem dopiero za jakiś bliżej nieokreślony czas odbiór.
    A co będzie jeśli zostanie zasygnalizowana flaga a w międzyczasie pojawią się w buforze nowe dane?

    Dodano po 6 [minuty]:

    Poza tym coś takiego

    If Flaga_rs = 1 Then
    Input Tx
    Flaga_rs = 0
    End If

    nie odbierze ci danych z bufora.
    W taki sposób możesz odbierać jeden znak i to pod warunkiem, że najpierw jest polecenie Input a potem oczekiwanie kontroler czeka na znak.

    0
  • #7 29 Gru 2011 14:57
    maximus22_kr
    Poziom 18  

    tzn. rozbudowałem trochę wersja, jaką testowałem zwykły RS232, dodając obsługę
    układu do RS485.

    Próbowałem trochę z Inkey, ale tam znowu blokuje cały program - odczyt z zegara PCF8363 zatrzymuje się.

    0
  • #8 29 Gru 2011 15:20
    Krotki
    Poziom 13  

    Bardzo często jeżeli nic nie jest odbierane przez slave'a powodem jest złe zasilanie szyny rs485. Masz tam zamontowane rezystory ustalające odpowiednie napięcie i terminatory na końcach ?

    0
  • #9 29 Gru 2011 15:22
    Mundi1970
    Poziom 24  

    maximus22_kr napisał:
    Próbowałem trochę z Inkey, ale tam znowu blokuje cały program - odczyt z zegara PCF8363 zatrzymuje się.

    Przed Inkeyem dobrze jest sprawdzić czy coś jest w buforze, funkcja IsCharWaiting():
    Kod: basic4gl
    Zaloguj się, aby zobaczyć kod

    0
  • #10 29 Gru 2011 15:24
    kamyczek
    Poziom 34  

    Cały problem leży w zależnościach czasowych i sterowaniu sygnałem nadawanie odbiór . Jeśli chcesz przetestować poprawność transmisji wystarczy połączyć układy pomijając Max 485 i łącząc odpowiednio rx mastera z tx układu czujnika i tx mastera z rx odbiornika . Jeśli będzie działało poprawnie błędy należy szukać w zależnościach czasowych układu sterowania sygnałem nadawanie odbiór.

    0
  • #11 29 Gru 2011 15:24
    jousto
    Poziom 16  

    Napotkanie Inkey() powoduje zatrzymanie pracy programu aż do odczytu znaku z bufora UART.

    0
  • #12 29 Gru 2011 16:18
    maximus22_kr
    Poziom 18  

    Krotki napisał:
    Bardzo często jeżeli nic nie jest odbierane przez slave'a powodem jest złe zasilanie szyny rs485. Masz tam zamontowane rezystory ustalające odpowiednie napięcie i terminatory na końcach ?


    Tzn. terminatory zawsze daję wraz z jumperem, aby opcjonalnie móc włączyć. Na razie kabel ma 1.5 metra długości.

    Ale transmisja wydaje się być OK, bo podpięcie komputera z konsolą pomiędzy MAX485 a Attiny pokazuje, że dochodzi do MAX485 i wychodzi właściwy string.

    0
  • #13 30 Gru 2011 01:33
    maximus22_kr
    Poziom 18  

    zrobiłem tak:
    Atmega328 - Master

    Code:

    Do
    Config Serialin = Buffered , Size = 24
    Enable Interrupts

    If Ischarwaiting() = 1 Then                              ' sprawdź czy jest jakiś znak do odebrania  w buforze lub HW UART
     Gosub Odczyt_rs

    End If

    '***************************** wysyłanie żadania danych do modułu 001

    If Flaga_001 = 1 Then
    Set Re_de
    Waitms 2
    Print "MOD001" ; Chr(13) ;
    Waitus 600
    Reset Re_de
     Flaga_001 = 0
     Licznik_mod001 = 0
    End If

    Loop
    End
    '***************************** Odczyt UART

    Odczyt_rs:

      Ttt = ""

      Do

        Znak = Inkey()
        Select Case Znak
           Case 0
           Case 10
           Case 13 : If Ttt <> "" Then Exit Do                  ' jeśli coś odebrane
           Case Else
            Ttt = Ttt + Chr(znak)
        End Select

      Loop

    Return




    Przesyła i analizuje string prawidłowo przy połączeniu przez RS232. Przy wysyłaniu zapytania podświetlanie LCD trochę ciemnieje - w momencie przełączenia w nadajnik ( nie usuwałem sterowania MAX485 z programu, mimo, że go na razie nie używam ).

    Natomiast odłączenie przewodów RS232 powoduje zawieszenie się programu - zatrzymanie wyświetlania zegara na LCD. Co ciekawe zatrzymanie występuje nie w momencie nadawania, tylko w momencie ustawienia flagi żądania nadawania przez Timer. Flagę mam wyświetlaną na LCD i w momencie zawieszenia zostaje w stanie 1.

    Płytki są zasilane z osobnych zasilaczy - RS485 ma A,B oraz GND

    0
  • #14 01 Sty 2012 23:48
    maximus22_kr
    Poziom 18  

    Przy takim kodzie:

    Attiny2313 - temu raczej nic nie dolega - odbiera i wysyła:

    Code:

    $regfile = "attiny2313.dat"
    $crystal = 8000000
    $baud = 9600

    '********************* Konfiguracja magistrali 1-Wire
    Config 1wire = Portd.5

    '*********************

    Config Serialin = Buffered , Size = 10                 
    Enable Interrupts

    '********************* Konfiguracja wejść i wyjść
    Config Portd.2 = Output
    Reset Portd.2
    Config Portb.0 = Output
    Set Portb.0

    '********************* Deklaracje zmiennych
    Dim Dsid1(8) As Byte
    Dim I1 As Integer
    Dim T1 As String * 6
    Dim Flaga_rs As Bit
    Dim Tx As String * 7
    Dim Znak As Byte

    Declare Sub Wyslij
    Declare Sub Odczyt_rs
    Re_de Alias Portd.2
    Led Alias Portb.0


    '********************* Adres pierwszego DS18B20
    Dsid1(1) = &H28
    Dsid1(2) = &H9F
    Dsid1(3) = &H79
    Dsid1(4) = &H25
    Dsid1(5) = &H03
    Dsid1(6) = &H00
    Dsid1(7) = &H00
    Dsid1(8) = &H00

    Do

    '********************* odczyt pierwszego DS18B20
       1wreset
       1wwrite &H55
       1wverify Dsid1(1)
       1wwrite &HBE
       I1 = 1wread(2)

       Waitms 750

    '********************* konwersja dla wsaystkich DS18B20
       1wreset
       1wwrite &HCC
       1wwrite &H44
     Waitms 750

    If I1 <= 100 Then
       T1 = Str(i1)
       T1 = Format(t1 , "000")
       Else
       T1 = Str(i1)
    End If


    Echo Off


    If Ischarwaiting() = 1 Then                                 ' sprawdź czy jest jakiś znak do odebrania  w buforze lub HW UART
     Gosub Odczyt_rs

    End If

    If Tx = "MOD001" Then
       Reset Led
       Gosub Wyslij
       Else
       Tx = ""

    End If

    Loop
    End

    Odczyt_rs:

      Tx = ""

      Do

        Znak = Inkey()
        Select Case Znak
           Case 0
           Case 10
           Case 13 : If Tx <> "" Then Exit Do                   ' jeśli coś odebrane
           Case Else
            Tx = Tx + Chr(znak)
        End Select

      Loop

    Return

    Sub Wyslij
    Set Re_de
    Waitms 2

    Print "MOD001" ; T1 ; Chr(13);

    Waitms 12
    Reset Re_de
    Tx = ""
    End Sub


    Attiny2313 odbiera i wysyła w odpowiedzi ciąg z pomiarem.

    Niestety ATmega328 zawiesza się w momencie odebrania ciągu.
    Code:

    $regfile = "m328pdef.dat"
    $crystal = 8000000
    $baud = 9600                                                ' predkość transmisji
    $hwstack = 128                                              ' rozmiar stosu sprzętowego
    $swstack = 128                                              ' rozmiar stosu programowego
    $framesize = 128                                            ' rozmiar ramki

    '*********************

    Config Serialin = Buffered , Size = 24                   
    Config Serialout = Buffered , Size = 15
    Enable Interrupts

    '***************************** wysyłanie żadania danych do modułu 001
    If Flaga_001 = 1 Then
    Set Re_de
    Waitms 2
    Print "MOD001" ; Chr(13) ;
    Waitms 8
    Reset Re_de
     Flaga_001 = 0
     Licznik_mod001 = 0
    End If

    If Ischarwaiting() = 1 Then                                 ' sprawdź czy jest jakiś znak do odebrania  w buforze lub HW UART
     Gosub Odczyt_rs

    End If

    '***************************** Odczyt UART
    Odczyt_rs:

      Ttt = ""

      Do

        Znak = Inkey()
        Select Case Znak
           Case 0
           Case 10
           Case 13 : If Ttt <> "" Then Exit Do                  ' jeśli coś odebrane
           Case Else
            Ttt = Ttt + Chr(znak)
        End Select

      Loop

    Return



    Resztę kodu pomijam - zawiera menu ustawiania daty/czasu, obsługi klawiatury na PCF8574 oraz obsługę zapisu na SD - tylko, że z tym nie było problemu ( dwa tygodnie działało bez problemu ), do momentu uruchomienia UART.

    I jeszcze drugi problem, Atmega328 przy zasilaniu z zasilacza ( trafo 2,9A, kondensator 2200uF/35 12V, 2 x stabilizator 8V/1A + kondensatory 100nF ) wysyła jakieś bzdury przez RS485, po podłączeniu - dodatkowo - zasilania z programatora ( równolegle z tym z zasilacza ) wysyła właściwe ciągi.

    Zależności czasowe dobrałem eksperymentalnie- tak, żeby cały ciąg dochodził

    Głupie pytanie

    Cy przyczyną może być zasilacz, który daje więcej niż trzeba ? zauważyłem, że procesor jest gorący- może lepiej byłoby zrobić jakiś zasilacz na układzie LM ?

    0
  • #15 02 Sty 2012 20:35
    xury
    Poziom 39  

    Wcale nie głupie pytanie. Właściwe zasilanie to podstawa podstaw. Ja widzę, że nie masz stabilizatorów 5V !!?. W takim razie jakim napięciem zasilasz procesor ? Jeśli wyższym niż 5,5V to masz prawdopodobnie już uwalony procek.

    0
  • #16 02 Sty 2012 21:39
    maximus22_kr
    Poziom 18  

    Mam dwa stabilizatory - 78M05 w wersji SMD oraz L1117-3,3V dla karty SD/MMC

    Procesor grzał się jak zasilałem z 8V/2V niż jak zasilam z 7V/0,5A

    Natomiast nie wiem co myśleć o tym scalaku do RS485 ( jakiś zamiennik SN75 ), bo gdy układ był zasilany tylko z programatora to w momencie przełączenia go na nadawanie przygasał wyświetlacz - aż taki pobór prądu jest ?

    0