www.mikrocontroller.net

Forum: Haus & Smart Home Master und Slave am RS485


Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich versuche über Bsacom ein Programm zu schreiben mit dem ich 5 AVR
(Mega8) über eine RS485 Schnittstelle vernetzen kann.

Geplant ist, dass der Master eine Abfrage auf den Bus gibt und ein
angesprochender Slave antwortet.

Mein Problem dabei ist, wie können die Slave's in den Bus hinein hören
um denn die ankommenden Abfragen aus zu werten?
Gibt es da unter Bascom Basic einen speziellen Befehl?

Vielen Dank für eure Unterstützung
Klaus

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn du RS485 in der 2-Draht-Variante verwendest:

Die Richtung des RS485-Treibers wird über einen Portpin umgeschaltet.
Alle Slaves lauschen gleichzeitig. Wird ein Slave angesprochen, stellt
er die Daten bereit und schaltet die Richtung um, genauso wie der
Master.

Also kein "spezieller" Befehl, sondern blos Port toggeln.

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Ralf,

so weit habe ich es auch schon geschafft.
Sowohl vom Master als auch Slave kann ich Daten auf den Bus geben.

Nur:

Wie sieht der Code aus mit dem der Slave (oder Master) den Bus
abliest?
Kann man über deb Porpin vielleicht einen Interrupt auslösen? Wenn ja
wie?

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, jetzt wird mir dein Problem klarer...
Verwendest du die serielle Schnittstelle der AVRs für irgendwelche
speziellen Sachen? Wenn nicht, dann kannst du die serielle an die
MAX485-Treiber anschliessen... brauchst aber evtl. noch zusätzliche
Bauteile.

Wenn du es über normale Portpins machst, dann solltest du es wohl am
besten wissen, ob der Portpin einen Interrupt unterstützt... :-)
Und WIE die Daten übertragen werden, das definiert der Entwickler, also
DU!!!
Du kannst das serielle Protokoll oder auch das I2C-Protokoll verwenden,
alles was du möchtest, aber du musst es dann in Software implementieren,
was bei Verwendung der seriellen Schnittstelle entfallen würde.
Ich habe noch keine RS485-Schnittstelle gesehen, die ein anderes
Protokoll als das normale serielle verwendet. Der Unterschied zwischen
RS232 und RS485 liegt soweit ich weiss nur in den unterschiedlichen
elektrischen Eigenschaften...

Ralf

Ralf

Autor: Klaus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, ich hab emir eine (zwei) kleine Schaltungen zusammen gesteckt und
über RS485 verbunden.
Über eine RS485/RS232 Schnittstelle kann ich den Datenverkehr auf dem
PC Terminal beobachten.
Sowohl der Master als auch der Slave senden Daten.

Was mir fehlt ist jetzt der Code, und zwar in Bascom basic den ich
einspielen müsste um dem Slave das lesen bei zu bringen.

Da ich Einsteiger bin fehlt mir hier einfach das Wissen. Für einen
Programmierer sicher gar kein Problem

Autor: Karlheinz Druschel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,
da auch ich ein RS485 Netzwerk mit AVR plane, folgende Frage:
Mit welchem Adapter und welcher Software beobachtest Du den Datenverkehr 
?
Einem einfachen Terminalprogramm (Hyperterm)?


Greets
Karlheinz

Autor: Dirk Frerichs (dirk-frerichs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
die slaves haben alle eine andere adresse

die slaves sind standard auf lauschen eingestellt
also senden nie bis sie aufgefordert werden
( so der sinn eines slaves )

in deinem datanpaket must du nun sagen welcher slave dir was liefern 
soll

also sendest du in deinem protokoll
z.B.  [ die adresse des slaves   ; daten ; chksumme ]

dieses empfangen erstmal alle slaves
nur der slave der antworten soll . also die entsprechnde adresse 
besitzt...

der master lauscht also auch .. wenn nix zu tun ist
wenn er sendet , schaltet der den TX_EN am MAX485
sendet das paket , und schaltet wieder auf empfang

der slave der sich angesprochen fühlt , schaltet auf senden und 
übermittelt die daten
sobald die weg sind wieder auf empfang

Autor: Verri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
da diese Frage immer wieder auftaucht hier ein kleines Codebespiel :

$regfile = "m16def.DAT"
$crystal = 8000000
$baud = 9600
$loadersize = 512
$hwstack = 64
$swstack = 48
$framesize = 60

'--------[Serial Output]----------
Sub Send_data(byval Byte1_w As Byte , Byval Byte2_w As Byte , Byval Byte3_w As Byte , Byval Byte4_w As Byte , Byval Byte5_w As Byte , Byval Byte6_w As Byte , Byval Byte7_w As Byte)
   Linebusy = 1
   Txcomplete = 0
   Crcbyte_w = Crc(byte1_w , Byte2_w , Byte3_w , Byte4_w , Byte5_w , Byte6_w , Byte7_w)       ' make send Checksum
   Waitms 2
   Portc.7 = 1                                                                  'set RS485 to Send Mode
   Waitus 7                                                                     'wait for tranceiver switched to send mode
   Ucsrb.0 = 1                                                                  ' mark next Byte in UDR as Adress
   Udr = Byte1_w                                                                ' Set Byte in UDR (Recipient)
   Ucsrb.0 = 0                                                                  ' mark next Byte in UDR as Data
   Printbin Byte2_w ; Byte3_w ; Byte4_w ; Byte5_w ; Byte6_w ; Byte6_w ; Crcbyte_w ;       'Sending without line feed
   While Txcomplete = 0
   nop
   Wend
   'Print #2 , "Sended--->" ; "To:" ; Byte1_w ; " From:" ; Byte2_w ; " Command:" ; Byte3_w ; " D1:" ; Byte4_w ; " D2:" ; Byte5_w ; " D3:" ; Byte6_w ; " D4:" ; Byte7_w ; " CRC:" ; Crcbyte_w       'set RS485 to receive mode
   'Linebusy = 0
   Return
End Sub
'^^^^^^^^[END of Serial Output]^^^^^^^^^^

'--------<<Serial input IRQ>>------------
Receive:
Linebusy = 1
Adressflag = Ucsrb.1                                                            'Read UCSRB Register Bit 1 (RXB8) for determing the 9th Bit
Inbyte = Udr                                                                    'Read UDR into Byte VAR
If Inbyte = Unitid And Rxactive = 0 Then                                        'compare received Unitid
   Ucsra.0 = 0                                                                  'Reset UCSRA.0 (MPCM) to get Data Frames
   Ucsrb.1 = 0                                                                  'Reset UCSRB.1 (RXB8) to be ready for a other 9th Bit
   Rxactive = 1                                                                 'Set RXactive Flag
   Broadcast_flag = 0                                                           'Set Broadcast Flag
End If
'Determ If Broadcast Is Send
If Inbyte = 0 And Rxactive = 0 Then                                             'compare received Unitid
   Ucsra.0 = 0                                                                  'Reset UCSRA.0 (MPCM) to get Data Frames
   Ucsrb.1 = 0                                                                  'Reset UCSRB.1 (RXB8) to be ready for a other 9th Bit
   Rxactive = 1                                                                 'Set RXactive Flag
   Broadcast_flag = 1                                                           'Set Broadcast Flag
End If


If Rxactive = 1 Then
   Incr Arraycounter                                                            'count up Array
   Datastring_r(arraycounter) = Inbyte                                          ' Fill Array with received Data
End If

If Arraycounter = 8 Then
         Ucsra.0 = 1                                                            ' set Ucsra MPCM Mode on if last Byte is Transmitted
         Stringcomplete = 1                                                     ' Set Flag for complete transmission
         Arraycounter = 0                                                       ' Reset Arraycounter
         Rxactive = 0                                                           ' Reset RXactive
         Linebusy = 0
         Adressflag = 0                                                         'Reset Adressflag
         Crc_check = Crc(datastring_r(1) , Datastring_r(2) , Datastring_r(3) , Datastring_r(4) , Datastring_r(5) , Datastring_r(6) , Datastring_r(7))       ' Make Checksum of Received Data
         Print #2 , "received-> " ; "From:" ; Datastring_r(2) ; " To:" ; Datastring_r(1) ; " Command:" ; Datastring_r(3) ; " D1:" ; Datastring_r(4) ; " D2:" ; Datastring_r(5) ; " D3:" ; Datastring_r(6) ; " D4:" ; Datastring_r(7) ; " CRC:" ; Datastring_r(8)

End If
Return
'^^^^^^^^[END of serial input]^^^^^^^^^^^^

'-------<<IRQ for sending complete>>------
Send_complete:
Waitus 14
Portc.7 = 0
Txcomplete = 1
Return
'^^^^^<<END IRQ sending complete>>^^^^^^^^


so in etwa funktioniert das Senden / Empfangen mit 9Bit.

Bitte nicht irritieren lassen. Die Auszüge sind aus einem laufendem 
Projekt für einen MultiMaster Bus mit Token-Passing. Daher kann ich 
leider nicht alles Posten. Aber mit etwas Googeln und nachdenken lässt 
sich bestimmt das wichtigste extrahieren. Der Rest steht im Datasheet.

Wichtig ist das das ganze nur mit einem Hardware USART des At-Mega läuft 
da die Register und Interrupts zwingen gebraucht werden.

Bei der Übertragung der Daten mit 9-Bit wird der Überwachungsaufwand der 
Slaves deutlich verringert da nur die der richtigen Adresse folgenden 
Daten beachtet werden. Alle anderen Daten werden direkt verworfen.

Nachteilig ist, das man den Bus nicht ganz so einfach mithören kann. Ich 
löse das über einen RS485->Rs232 Wandler um mit einem Terminal Programm 
die Daten mit zu lesen.

Bei der Master Slave Variante wird (kleiner Tip) ein Empfangstimeout 
irgandwann wichtig. Da unter umständen der Master sonst endlos auf die 
Antwort von einem inzwischen "verstorbenen" Slave wartet. Ein 
gleichzeitiges Senden beider (Master und SLave) muss natürlich wirksam 
unterbunden werden um Kollisionen zu vermeiden. Dies ist aber bei Master 
Slave Betrieb recht leicht durch ein simples Protokoll (ACK ö.Ä) zu 
lösen.

Gruß

Verri

Autor: Mr. Kaktus (kaktus-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
abo

Autor: gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier eine interessante Protokol für so ein Netzwerk:

www.hth.com/snap/

Autor: Marko (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Empfang einfach die

URXC Interruptroutine setzen
und dort das UDR-Register auslesen,

Senden durch schreiben des UDR-Registers

Autor: Verri (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist genau das was im Programauszug passiert. Gut ohne das direkte 
schreiben in UDR . Aber Print macht auch nix anderes, ganz im Gegenteil. 
Print wartet noch so lange bis alle Daten raus sind.

Als denn

Verri

Autor: Jörg H. (idc-dragon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ihr könnt auch in meinem OpenHC-Projekt abgucken. Das ist RS485 
Multimaster, mit CRC und einem Toggle-Bit in den Paketen. Läuft auf AVR 
Mega8, funktioniert zuverlässig.

Autor: Frank B. (frankman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab mir ein Kabel von FTDI gekauft, das hat einen 
USB-zu-seriell-Konverter .Daran habe ich einen LTC485 angeschlossen. Die 
5V kannst Du direkt aus dem Kabel verwenden. So brauchst Du nur GND, 
VCC, TX und RX vom LTC 485 zum Adapterkabel verbinden. Das Kabel kostest 
zwar etwas mehr (so etwa 20€) aber das hat schon eine Stiftleiste, mit 
der es sehr flexibel einsetzbar bleibt. Der LTC485 kostet etwa 5 Euro.

Autor: Frank B. (frankman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
abo
abo

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.