-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 15

Thema: Probleme mit RS 485 Bus

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    13.05.2007
    Ort
    Pirmasens
    Beiträge
    15

    Probleme mit RS 485 Bus

    Anzeige

    Hallo,

    habe mir eine Schaltung aufgebaut mit 2 x Atmega 16, 2 x Max 485 und einem LCD Display, somit will einen RS 485 Bus realisieren.

    Der erste Atmega soll als Master dienen und der zweite Atmega als Slave. Diese habe ich auf einem Steckbrett aufgebaut mit folgendem Code:

    Master Code:

    $regfile = "m16def.dat"
    $crystal = 10000000
    $baud = 1200
    Config Portd.2 = Output
    Portd.2 = 1


    Dim i As Byte
    Dim wTest As Word

    I = 1
    'wTest = 35000

    Do
    Portd.2 = 1
    Printbin I
    Print "1" ; I
    'waitms 10
    Portd.2 = 0
    Loop
    End



    Slave Code:

    $regfile = "m16def.dat"
    $crystal = 10000000
    $baud = 1200
    Config Portd.2 = Input
    Portd.2 = 0

    Dim I As Byte

    ' - - - Lcd - - -
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.5 , Rs = Porta.4 'Ausgänge zum LCD
    Config Lcdbus = 4
    Config Lcdmode = Port
    Config Serialin = Buffered , Size = 20
    ' - - - - - - - - -

    Do
    If Usr.rxc = 1 Then ' Wenn Byte empfangen...
    I = Udr 'Byte aus UART auslesen
    Select Case I
    Case "1"
    Cls
    Lcd "Hallo AVR Nr.1"
    Case "2"
    Cls
    Lcd "Hallo AVR Nr.2"
    Case Else
    Cls
    Lcd "Nichts"

    End Select
    End If
    Loop

    Leider bekomme ich auf dem LCD am Slave die Meldung Nichts angezeigt. Die Schaltung habe ich auch schon etliche male kontrolliert.

    Würde mich über eine Hilfe freuen.

    Mfg

    Tobias

  2. #2
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    50
    Beiträge
    112
    Ich habe das hier mit zwei ATMega128 aufgebaut:

    Sender:
    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600
    
    Config Pinc.6 = Output
    Config Pine.2 = Output
    Config Graphlcd = 240 * 64 , Dataport = Portd , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6
    
    Dim A(8) As Byte
    Dim B As Byte
    
    Bl Alias Portc.6
    Rs485 Alias Porte.2
    
    Bl = 1
    Rs485 = 1
    Cursor Off
    Cls
    
    Locate 1 , 1
    Lcd "RS485 Sender"
    
    A(1) = 128                              'ID
    A(2) = 254                              'ID
    A(3) = 1                                'Absender
    A(4) = 2                                'Empfaenger
    
    Do
     For B = 0 To 255
      A(5) = B
      A(6) = Crc8(a(1) , 5)                 'Checksumme
      Locate 7 , 1
      Lcd A(6) ; "  "
      Gosub Send_data
      Waitms 250
     Next B
    Loop
    
    End
    
    Send_data:
      Printbin A(1) ; 6
    Return

    Empfaenger:
    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600
    
    Config Pinc.6 = Output
    Config Pine.2 = Output
    Config Graphlcd = 240 * 64 , Dataport = Portd , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6
    Rs485 Alias Porte.2
    Enable Interrupts
    Enable Urxc
    On Urxc Isrlabel
    
    Dim A As Bit
    Dim B As Byte
    Dim Zeiger As Byte
    Dim Db1(6) As Byte
    Dim Db2(6) As Byte
    
    Bl Alias Portc.6
    Bl = 1
    A = 0
    Zeiger = 1
    Rs485 = 0
    
    Cursor Off
    Cls
    Locate 1 , 1
    Lcd "RS485 Empfaenger"
    
    Do
     If A = 1 Then
      Locate 3 , 1
      Lcd "Absender  : " ; Db2(3) ; "  "
      Locate 4 , 1
      Lcd "Empfaenger: " ; Db2(4) ; "  "
      Locate 5 , 1
      Lcd "Datensatz : " ; Db2(5) ; "  "
      Locate 7 , 1
      Lcd "Checksumme: " ; Db2(6) ; "  "
      A = 0
     End If
    Loop
    
    End
    
    Isrlabel:
     Db1(zeiger) = Udr
     If Zeiger = 6 Then
      For B = 1 To 6
       Db2(b) = Db1(b)
       Db1(b) = 0
      Next B
      Zeiger = 1
      A = 1
     End If
     If Db1(1) = 128 Then
      Db2(1) = Db1(1)
      Db1(1) = 0
      Incr Zeiger
     End If
     If Db2(1) = 128 And Db1(2) = 254 Then Incr Zeiger
    Return


    Ich uebertrage in diesem Falle ersteinmal sechs Bytes. Das soll dann spaeter eine Art Protokoll werden. Das ganze laeuft wunderbar stabil. Allerdings habe ich da auch einige Zeit experimentiert bis es einwandfrei lief.
    Der Empfaenger sucht zunaechst nach den zwei ID-Bytes. Wenn diese korrekt angekommen sind, dann werden die 4 nachfolgenden Bytes verarbeitet. Sobald die Uebertragung vollstaendig ist, werden die Daten auf dem LC-Display angezeigt.
    Gerade heute habe ich noch ein paar MAX485 bekommen. Sobald ich den naechsten Bastelflash bekomme, werde ich einen dritten AVR mit Display in den Bus haengen und die Software so umschreiben, dass jeder Senden und Empfangen kann.
    Dafuer hatte ich auch das Empfaenger- und Senderbyte vorgesehen.

    Ein Foto von dem Drahtigel:
    http://www.elektronik-web.de/fotos/rs485.jpg

    Mit freundlichen Gruessen
    Digitali

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    13.05.2007
    Ort
    Pirmasens
    Beiträge
    15
    Hallo Digitali,

    werde mich mal in deinen Code einlesen bin zwar noch nicht so fit mit der Programmierung versuche es aber mal

    Mfg

    Tobias

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    50
    Beiträge
    112
    Ich habe das mal auf das Notwendigste abgespeckt:

    Sender:
    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600
    
    Config Pinc.6 = Output
    Config Pine.2 = Output
    Config Graphlcd = 240 * 64 , Dataport = Portd , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6
    
    Dim A As Byte
    
    Bl Alias Portc.6
    Rs485 Alias Porte.2
    Bl = 1
    
    Rs485 = 1                               'Senden
    
    Cursor Off
    Cls
    Locate 1 , 1
    Lcd "RS485 Sender"
    
    A = 128
    
    Do
     Printbin A
     Waitms 500
    Loop
    
    End
    Empfaenger:
    Code:
    $regfile = "m128def.dat"
    $crystal = 16000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600
    
    Config Pinc.6 = Output
    Config Pine.2 = Output
    Config Graphlcd = 240 * 64 , Dataport = Portd , Controlport = Portc , Ce = 2 , Cd = 3 , Wr = 0 , Rd = 1 , Reset = 4 , Fs = 5 , Mode = 6
    Rs485 Alias Porte.2
    Enable Interrupts
    Enable Urxc
    On Urxc Isrlabel
    
    Dim A As Bit , Db As Byte
    
    Bl Alias Portc.6                        ' Hintergrundbeleuchtung LC-Display
    Bl = 1
    A = 0
    
    Rs485 = 0                               'Empfangen
    
    Cursor Off
    Cls
    Locate 1 , 1
    Lcd "RS485 Empfaenger"
    
    Do
     If A = 1 Then
      Locate 4 , 1
      Lcd Db
      A = 0
     End If
    Loop
    
    End
    
    Isrlabel:
     Db = Udr
     A = 1
    Return
    Es wird nur ein einziges Byte (128) uebertragen. Sobald der UART ein Zeichen empfaengt wird ein Interrupt ausgeloest. In der Urxc-Isr wird dann das Byte ausgelesen (Db=UDR). Und das war's dann auch schon. Eigentlich total simpel.

    Mit freundlichen Gruessen
    Digitali

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    13.05.2007
    Ort
    Pirmasens
    Beiträge
    15
    Hallo Digitali,

    also habe mal den Code etwas angepasst für den Atmega 16 kann sein das ich da noch einen fehler habe.

    Master
    $regfile = "m16def.dat"
    $crystal = 1000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600

    Dim A( As Byte
    Dim B As Byte

    Bl Alias Portd.1 'txd vom atmel verbunden mit max485 pin 4 (DI)
    Rs485 Alias Portd.2 'INT0 vom atmel verbunden mit max485 pin 2,3 (RE,DE)

    Bl = 1
    Rs485 = 1

    A(1) = 128 'ID
    A(2) = 254 'ID
    A(3) = 1 'Absender
    A(4) = 2 'Empfaenger

    Do
    For B = 0 To 255
    A(5) = B
    A(6) = Crc8(a(1) , 5) 'Checksumme
    Gosub Send_data
    Waitms 250
    Next B
    Loop

    End

    Send_data:
    Printbin A(1) ; 6
    Return


    Slave:
    $regfile = "m16def.dat"
    $crystal = 1000000
    $hwstack = 32
    $swstack = 20
    $framesize = 40
    $baud = 9600

    ' - - - Lcd - - -
    Config Lcd = 16 * 2
    Config Lcdpin = Pin , Db4 = Porta.0 , Db5 = Porta.1 , Db6 = Porta.2 , Db7 = Porta.3 , E = Porta.5 , Rs = Porta.4 'Ausgänge zum LCD
    Config Lcdbus = 4
    Config Lcdmode = Port
    ' - - - - - - - - -

    Rs485 Alias Portd.2 'INT0 vom atmel verbunden mit max485 pin 2,3 (RE,DE)
    Enable Interrupts
    Enable Urxc
    On Urxc Isrlabel

    Dim A As Bit
    Dim B As Byte
    Dim Zeiger As Byte
    Dim Db1(6) As Byte
    Dim Db2(6) As Byte

    Bl Alias Portd.0 'RXD vom Atmel zu Max 486 Pin 1 RO
    Bl = 1
    A = 0
    Zeiger = 1
    Rs485 = 0

    Cursor Off
    Cls
    Locate 1 , 1
    Lcd "RS485 Empfaenger"

    Do
    If A = 1 Then
    Locate 2 , 1
    Lcd "Absender : " ; Db2(3) ; " "

    Locate 2 , 1
    Lcd "Empfaenger: " ; Db2(4) ; " "

    Locate 2 , 1
    Lcd "Datensatz : " ; Db2(5) ; " "

    Locate 2 , 1
    Lcd "Checksumme: " ; Db2(6) ; " "
    A = 0
    End If
    Loop

    End

    Isrlabel:
    Db1(zeiger) = Udr
    If Zeiger = 6 Then
    For B = 1 To 6
    Db2(b) = Db1(b)
    Db1(b) = 0
    Next B
    Zeiger = 1
    A = 1
    End If
    If Db1(1) = 128 Then
    Db2(1) = Db1(1)
    Db1(1) = 0
    Incr Zeiger
    End If
    If Db2(1) = 128 And Db1(2) = 254 Then Incr Zeiger
    Return

    Bekomme keine Daten vom Master.

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    50
    Beiträge
    112
    Bl Alias Portd.1 'txd vom atmel verbunden mit max485 pin 4 (DI)
    Bl Alias Portd.0 'RXD vom Atmel zu Max 486 Pin 1 RO

    Ich hatte mein Listing schlecht dokumentiert. Bl steht bei mir fuer Backlight. Damit schalte ich lediglich die Hintergrundbeleuchtung des Displays ein. Das musst Du bei Dir wieder loeschen.

    Mit freundlichen Gruessen
    Digitali

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    13.05.2007
    Ort
    Pirmasens
    Beiträge
    15
    Also brauche ich nur beim Master den Portd.2 ?

    Mfg

    Tobias

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    08.11.2005
    Ort
    QTH: JO43BC
    Alter
    50
    Beiträge
    112
    Pin 2 und 3 vom MAX 485 sind ja zusammengeschaltet. Dort wird zwischen Senden und Empfangen umgeschaltet. Das mache ich beim Sender und Empfaenger jeweils mit dem PortPin E.2.
    RxD vom AVR an Pin1 (RO) vom MAX und TxD vom AVR an Pin4 (DI) vom MAX.

    Mit freundlichen Gruessen
    Digitali

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Vitis
    Registriert seit
    06.01.2005
    Ort
    Südpfalz
    Alter
    44
    Beiträge
    2.240
    jaja, die 485 ... ich hatte mal probleme damit, weil die
    A-undB-Leitung floatete. hab sie dann damit gelöst, dass ich
    Pullup-Pulldown und Abschlusswiderstände einlötete.
    Dann gings auf Anhieb.
    ach so, eins noch, warum verwendest Du nicht einfach den
    PCA82C250? Ist zwar n CAN-Bus Baustein, die Funktion
    ist aber vergleichbar, bis auf den Punkt, dass man sich
    die Umschaltung der Datenflussrichtung schenken kann.
    Vor den Erfolg haben die Götter den Schweiß gesetzt

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    13.05.2007
    Ort
    Pirmasens
    Beiträge
    15
    Hallo Vitis,

    habe die Abschlusswiderstände an den Bus gemacht und siehe da es funzt

    Danke

    Mfg

    Tobias

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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