- 3D-Druck Einstieg und Tipps         
Ergebnis 1 bis 6 von 6

Thema: RS485 Datenübertragung

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.01.2006
    Ort
    Nidda
    Alter
    51
    Beiträge
    180

    RS485 Datenübertragung

    Anzeige

    E-Bike
    Hallo,

    habe mal wieder eine Frage an die RS485 Experten.
    Ich habe mir einen kleinen Bus aufgebaut und steuere damit 4 Module (je 5 Relais) an.
    Parallel dazu habe ich die Möglichkeit, an jedem Modul per Taster die Relais zu schalten.

    Jetzt habe ich festgestellt, dass ich über Rs485 ein Relai z.B. im Modul 1 ansteuern und umschalten kann.
    Wenn allerdings im Modul 2 eine örtliche Bedienung stattfindet, reagiert Modul 1 bei einer RS485 ansteuerung nicht mehr.
    Ich muss zunächst wieder Modul 1 örtlich bedienen um die RS485 bedienung zu ermöglichen.

    Woran kann das liegen?
    Meine Busabfrage mache ich über einen Interrupt und folgenden Code

    Code:
    '---------- Einlesen ----------
    Onrxd:
       Disable Interrupts
    
       Incr N
       B(n) = Udr
    
       If N > 9 Then
        Preamble = B(1) : Sync = B(2) : Hdb2 = B(3)
        Hdb1 = B(4) : Dab1 = B(5)
        Sab1 = B(6)
        Db1 = B(7)
        Db2 = B(8)
        Crc2 = B(9)
        Crc1 = B(10)
        N = 0
    
        Gosub Pruefung
        Else
    
        End If
    Return
    [/code]

  2. #2
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    17.09.2005
    Beiträge
    276
    Dein Code ist so Aussagekräftig wie die Variablennamen x1,x2,x3,x4,x5,x6,x7,x8

    Gento

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    tja, du disablest die interrupts und wo enablest du die wieder?
    Nach dem Disable geht der URXD nämlich nicht mehr
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    22.01.2006
    Ort
    Nidda
    Alter
    51
    Beiträge
    180
    Hallo,

    ich habe jetzt versucht, die Interrupts zu enablen.
    Leider nicht mit dem gewünschten Erfolg.

    Jetzt habe ich meinen gesamten Code angehängt, da sich zwischenzeitlich einige bei mir gemeldet haben, die gerne etwas mehr über die RS485 Steuerung erfahren möchten.
    Da das Programm weitestgehend ohne Probleme läuft, kann sich hier jeder etwas abkugen.
    Verbesserungsvorschläge nehme ich gerne entgegen!

    Vielleicht findet ja auch jemand den oben beschriebenen Fehler im Programm?!

    Tobias

    Code:
    '***** RS-485 *************************
    ' RS485 Ansteuerung von 5 Relais mit Zeitschaltfunktion und manueller vor Ort Bedienung mit Tastern
    ' Erstellt von Tobias Riesbeck, Dezember 2006
    '**************************************
    
    $regfile = "m8def.dat"
    $crystal = 7372800
    $baud = 4800
    
    '------------------------------------
    
    Config Pind.4 = Input                                       '1 Dil Schalter für Adresse
    Config Pind.3 = Input                                       '2 Dieser muss beim programmieren
    Config Pinb.4 = Input                                       '3 auf allen Positionen auf 0 stehen
    Config Pinb.3 = Input                                       '4
    
    Config Pinc.0 = Input                                       ' Schaltport
    Config Pinc.1 = Input
    Config Pinc.2 = Input
    Config Pinc.3 = Input
    Config Pinc.4 = Input
    Config Pinc.5 = Input                                       ' N.N.
    
    Config Portb.0 = Output                                     ' Schaltport's
    Config Portb.1 = Output
    Config Portb.2 = Output
    Config Portd.7 = Output
    Config Portd.6 = Output
    
    Config Portb.5 = Output                                     ' Kontrollport
    
    Dim T1 As Long
    Dim T2 As Long
    Dim T3 As Long
    Dim T4 As Long
    Dim T5 As Long
    
    
    Dim Zeit1 As Long
    Dim Zeit2 As Long
    Dim Zeit3 As Long
    Dim Zeit4 As Long
    Dim Zeit5 As Long
    Dim Sz As Long                                              'Sendezeit
    
    Zeit1 = 20000000                                            'Flur EG
    Zeit2 = 20000000                                            'Schlafzimmer
    Zeit3 = 20000000                                            'Keller
    Zeit4 = 10000000                                            'Gang
    Zeit5 = 20000000                                            'Flur OG
    
    
    Dim Myadress As Byte                                        'Variable Myadress wird für Adresse über Dip Schalter festgelegt
                                                                '"Hex(myadress)" gibt die Adresse in Hex-Format aus
    Myadress.0 = Pind.4
    Myadress.1 = Pind.3
    Myadress.2 = Pinb.4
    Myadress.3 = Pinb.3
    
    
    Dim Db1_ As Byte                                            ' db1 zur Aufnahme des Modulzustandes in Hex
    
    
    T1 = 0
    T2 = 0
    T3 = 0
    T4 = 0
    T5 = 0
    Sz = 0
    
    
    Config Portd.2 = Output                                     ' RS485
    
    
    Config Debounce = 50
    
    Dim I As Byte
    Dim Key As Byte
    
    
    Dim S As String * 10
    Dim B(10) As Byte                                           'At S Overlay
    Dim N As Byte
    
    
    ' Adresse festlegen -------------------------------------------------
    
    Dim Preamble_ As Byte                                       'Preamble-Byte
    Dim Sync_ As Byte                                           'Syncronisation-Byte
    Dim Hdb2_ As Byte                                           'Kopf-Byte 1
    Dim Hdb1_ As Byte                                           'Kopf-Byte 2
    Dim Dab1_ As Byte
    Dim Crc2_ As Byte                                           'CRC2
    
    
    Preamble_ = &H55                                            'H55
    Sync_ = &H54                                                'H54
    Hdb2_ = &H51                                                'H51
    Hdb1_ = &H42                                                'H42
    Dab1_ = &H00
    
    
    ' Protokoll ---------------------------------------------------------
    
    Dim Preamble As Byte                                        'Preamble-Byte
    Dim Sync As Byte                                            'Syncronisation-Byte
    Dim Hdb2 As Byte                                            'Kopf-Byte 1
    Dim Hdb1 As Byte                                            'Kopf-Byte 2
    Dim Dab1 As Byte                                            'Empfänger-Byte 1
    Dim Sab1 As Byte                                            'Sender-Byte 1 Adresse
    Dim Db1 As Byte                                             'Daten-Byte 1 (in diesem Modul als Hex)
    Dim Db2 As Byte                                             'Date-Byte 2 fals erforderlich
    Dim Crc2 As Byte                                            'CRC2
    Dim Crc1 As Byte                                            'CRC1
    
    
    
    Dim Aktion As Byte                                          'CRC1 als Sender
    
    
    Const Keys = 5
    
    On Urxc Onrxd
    Enable Urxc
    Enable Interrupts
    
    Portd.2 = 0                                                 ' R/W für RS485
    
     '---------- Programm ----------
    
    Gosub Zustand
    
    Prog_start:
    
     N = 0
    
    
    
    Do
    
       If Sz > 0 Then Sz = Sz + 1
       If Sz > 10000 Then Gosub Zustand
    
    
    'Zeitschalter (Zähler)
    
     If T1 > 0 Then T1 = T1 + 1
    
     If T1 > Zeit1 Then
     Portd.6 = 0
     T1 = 0
     Aktion = &H00
     Sz = 1
     Else
     End If
    
    
     If T2 > 0 Then T2 = T2 + 1
    
     If T2 > Zeit2 Then
     Portb.0 = 0
     T2 = 0
     Aktion = &H00
     Sz = 1
     Else
     End If
    
    
     If T3 > 0 Then T3 = T3 + 1
    
     If T3 > Zeit3 Then
     Portb.2 = 0
     T3 = 0
     Aktion = &H00
     Sz = 1
     Else
     End If
    
    
     If T4 > 0 Then T4 = T4 + 1
    
     If T4 > Zeit4 Then
     Portd.7 = 0
     T4 = 0
     Aktion = &H00
     Sz = 1
     Else
     End If
    
    
     If T5 > 0 Then T5 = T5 + 1
    
     If T5 > Zeit5 Then
     Portb.1 = 0
     T5 = 0
     Aktion = &H00
     Sz = 1
     Else
     End If
    
    
    
    
     For I = 1 To Keys
     Key = I
     Select Case Key
     Case 1 : Debounce Pinc.0 , 0 , Key_o1 , Sub                'Port 1.
     Case 2 : Debounce Pinc.1 , 0 , Key_o2 , Sub                'Port 2
     Case 3 : Debounce Pinc.2 , 0 , Key_o3 , Sub                'Port 3
     Case 4 : Debounce Pinc.3 , 0 , Key_o4 , Sub                'Port 4
     Case 5 : Debounce Pinc.4 , 0 , Key_o5 , Sub                'Port 5
    
     End Select
    Next
    
    Loop
    
    End
    
    
       Key_o1:
       Toggle Portb.0                                           'Buchse 1
       Aktion = &HFF
       Sz = 1
       If T2 = 0 Then
       T2 = 1
       Else
       T2 = 0
       End If
       Return
    
    
    
       Key_o3:
       Toggle Portb.2                                           'Buchse 3
       Aktion = &HFF
       Sz = 1
       If T3 = 0 Then
       T3 = 1
       Else
       T3 = 0
       End If
       Return
    
    
       Key_o5:
    
       Toggle Portd.6                                           'Buchse 4
       Aktion = &HFF
       Sz = 1
       If T1 = 0 Then
       T1 = 1
       Else
       T1 = 0
       End If
       Return
    
    
       Key_o4:
       Toggle Portd.7                                           'Buchse 5
       Aktion = &HFF
       Sz = 1
       If T4 = 0 Then
       T4 = 1
       Else
       T4 = 0
       End If
       Return
    
    
       Key_o2:
       Toggle Portb.1                                           'Buchse 2
       Aktion = &HFF
       Sz = 1
       If T5 = 0 Then
       T5 = 1
       Else
       T5 = 0
       End If
       Return
    
    
    
    '---------- Einlesen ----------
    Onrxd:
       Disable Interrupts
    
       Incr N
       B(n) = Udr
    
       If N > 9 Then
        Preamble = B(1) : Sync = B(2) : Hdb2 = B(3)
        Hdb1 = B(4) : Dab1 = B(5)
        Sab1 = B(6)
        Db1 = B(7)
        Db2 = B(8)
        Crc2 = B(9)
        Crc1 = B(10)
        N = 0
    
        Enable Urxc
        Enable Interrupts
    
        Gosub Pruefung
        Else
    
    
        End If
    Return
    
    
    
    '---------- Prüfung ----------
    Pruefung:                                                   'SNAP Prüfung der eingehenden Byte
    
       If Sync <> Sync_ Then : Goto Prog_start
       Elseif Hdb2 <> Hdb2_ Then : Goto Prog_start
       Elseif Hdb1 <> Hdb1_ Then : Goto Prog_start
       Elseif Dab1 <> Myadress Then : Goto Prog_start
       End If
    
       Gosub Steuerung
    
       Return
    
    '---------- Fernsteuerung Steuerung ----------
    Steuerung:
    
        Sz = 1
        If Db1 = &H01 Then : Gosub Key_o1 : End If
        If Db1 = &H02 Then : Gosub Key_o2 : End If
        If Db1 = &H03 Then : Gosub Key_o3 : End If
        If Db1 = &H04 Then : Gosub Key_o4 : End If
        If Db1 = &H05 Then : Gosub Key_o5 : End If
        If Db1 = &H06 Then : Sz = 1 : End If
        Db1 = 0
    
    Return
    
    '---------- Übertragung des Zustandes --------
    
    Zustand:
    
    Db1_.0 = Portb.0                                            'Auswertung der Portzustände
    Db1_.1 = Portb.1
    Db1_.2 = Portb.2
    Db1_.3 = Portd.7
    Db1_.4 = Portd.6
    
    
    
       Portb.5 = 1                                              ' Übertragungs LED an
    
       Disable Urxc
       Disable Interrupts
    
    
       Portd.2 = 1 : Waitms 20                                  'RS485 PIN auf Senden
    
       Print Chr(preamble_) ; Chr(sync_) ;
       Print Chr(hdb2_) ; Chr(hdb1_) ;
       Print Chr(dab1_) ; Chr(myadress);
       Print Chr(db1_) ; Chr(db2);
       Print Chr(crc2) ; Chr(aktion) ;
       Waitms 100
    
       Do
       Loop Until Ucsra.txc = 1
       Reset Ucsra.txc
    
       Waitms 10 : Portd.2 = 0                                  'RS485 PIN auf Enpfang
    
       Enable Urxc
       Enable Interrupts
    
    
       Aktion = ""
    
       Sz = 0
       Portb.5 = 0                                              ' Übertragungs LED aus
       N = 0
    
    
      Return
    
    End

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    28.02.2005
    Ort
    Salzburg
    Alter
    44
    Beiträge
    464
    Also ich machs mit gepufferten USART ala config serialin
    funktioniert prima.

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    50
    Beiträge
    2.253
    hab noch kosmetische Vorschläge.

    die print cht(xy) gefallen mir nicht so recht, find printbin oder
    die interruptbasierende Ringpuffervariante mit schreiben
    ind UDR-Register schöner, aber das ist Geschmackssache.
    Brintbin wär etwas übersichtlicher denk ich.
    hinter dem letzten Print die 100ms brauchste eigentlich
    nicht, du hast ja den loop dahinter.
    ich verwende in Programmen gern die Alias Funktion,
    da kann man schön bei jeder Aktion sehen was da
    bewirkt werden soll, das macht die Programme schöner
    lesbar fürs Debuggen im nachhinein.
    Du belegst für mindestens 120ms nach dem senden des letzten
    Steuerzeichens den Bus, das könnte etwas zu lang sein,
    weil für n µC ist das ne Ewigkeit. versuch mal kürzere Zeiten,
    bzw. mach die 100ms mal raus.
    In der Mainloop versteh ich den Sinn der For - Next Schleife nicht
    für die Debounce-Pinabfrage
    Vor den Erfolg haben die Götter den Schweiß gesetzt

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen