Forum: Haus & Smart Home Master und Slave am RS485


von Klaus (Gast)


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

von Ralf (Gast)


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.

von Klaus (Gast)


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?

von Ralf (Gast)


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

von Klaus (Gast)


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

von Karlheinz Druschel (Gast)


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

von Dirk F. (dirk-frerichs)


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

von Verri (Gast)


Lesenswert?

da diese Frage immer wieder auftaucht hier ein kleines Codebespiel :
1
$regfile = "m16def.DAT"
2
$crystal = 8000000
3
$baud = 9600
4
$loadersize = 512
5
$hwstack = 64
6
$swstack = 48
7
$framesize = 60
8
9
'--------[Serial Output]----------
10
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)
11
   Linebusy = 1
12
   Txcomplete = 0
13
   Crcbyte_w = Crc(byte1_w , Byte2_w , Byte3_w , Byte4_w , Byte5_w , Byte6_w , Byte7_w)       ' make send Checksum
14
   Waitms 2
15
   Portc.7 = 1                                                                  'set RS485 to Send Mode
16
   Waitus 7                                                                     'wait for tranceiver switched to send mode
17
   Ucsrb.0 = 1                                                                  ' mark next Byte in UDR as Adress
18
   Udr = Byte1_w                                                                ' Set Byte in UDR (Recipient)
19
   Ucsrb.0 = 0                                                                  ' mark next Byte in UDR as Data
20
   Printbin Byte2_w ; Byte3_w ; Byte4_w ; Byte5_w ; Byte6_w ; Byte6_w ; Crcbyte_w ;       'Sending without line feed
21
   While Txcomplete = 0
22
   nop
23
   Wend
24
   '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
25
   'Linebusy = 0
26
   Return
27
End Sub
28
'^^^^^^^^[END of Serial Output]^^^^^^^^^^
29
30
'--------<<Serial input IRQ>>------------
31
Receive:
32
Linebusy = 1
33
Adressflag = Ucsrb.1                                                            'Read UCSRB Register Bit 1 (RXB8) for determing the 9th Bit
34
Inbyte = Udr                                                                    'Read UDR into Byte VAR
35
If Inbyte = Unitid And Rxactive = 0 Then                                        'compare received Unitid
36
   Ucsra.0 = 0                                                                  'Reset UCSRA.0 (MPCM) to get Data Frames
37
   Ucsrb.1 = 0                                                                  'Reset UCSRB.1 (RXB8) to be ready for a other 9th Bit
38
   Rxactive = 1                                                                 'Set RXactive Flag
39
   Broadcast_flag = 0                                                           'Set Broadcast Flag
40
End If
41
'Determ If Broadcast Is Send
42
If Inbyte = 0 And Rxactive = 0 Then                                             'compare received Unitid
43
   Ucsra.0 = 0                                                                  'Reset UCSRA.0 (MPCM) to get Data Frames
44
   Ucsrb.1 = 0                                                                  'Reset UCSRB.1 (RXB8) to be ready for a other 9th Bit
45
   Rxactive = 1                                                                 'Set RXactive Flag
46
   Broadcast_flag = 1                                                           'Set Broadcast Flag
47
End If
48
49
50
If Rxactive = 1 Then
51
   Incr Arraycounter                                                            'count up Array
52
   Datastring_r(arraycounter) = Inbyte                                          ' Fill Array with received Data
53
End If
54
55
If Arraycounter = 8 Then
56
         Ucsra.0 = 1                                                            ' set Ucsra MPCM Mode on if last Byte is Transmitted
57
         Stringcomplete = 1                                                     ' Set Flag for complete transmission
58
         Arraycounter = 0                                                       ' Reset Arraycounter
59
         Rxactive = 0                                                           ' Reset RXactive
60
         Linebusy = 0
61
         Adressflag = 0                                                         'Reset Adressflag
62
         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
63
         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)
64
65
End If
66
Return
67
'^^^^^^^^[END of serial input]^^^^^^^^^^^^
68
69
'-------<<IRQ for sending complete>>------
70
Send_complete:
71
Waitus 14
72
Portc.7 = 0
73
Txcomplete = 1
74
Return
75
'^^^^^<<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

von Mr. K. (kaktus-)


Lesenswert?

abo

von gast (Gast)


Lesenswert?

hier eine interessante Protokol für so ein Netzwerk:

www.hth.com/snap/

von Marko (Gast)


Lesenswert?

Zum Empfang einfach die

URXC Interruptroutine setzen
und dort das UDR-Register auslesen,

Senden durch schreiben des UDR-Registers

von Verri (Gast)


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

von Jörg H. (idc-dragon)


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.

von Frank B. (frankman)


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.

von Frank B. (frankman)


Lesenswert?

abo
abo

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.