PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : einfaches Bussystem? (1 Master, x Slaves, nur Master sendet)



goof1980
02.03.2009, 17:00
Hallo,

ich habe jetzt schon einiges gelesen aber so richtig habe ich noch keine lösung.

folgender Ansatz:
ich habe einen mega32. dieser dient als master und muss pakete an mehrere mega8 (slaves) schicken.
versendet werden immer 4 byte. wann die 4 bytes verschickt werden ist zeitlich unterschiedlich.
desweiteren kann nur ein mega8 am bus hängen oder mehrere. es müssen alle mega8 die pakete empfangen, im ersten byte ist dann ne adresse drin (die ich halt selbst festlege) und damit weiß der entsprechende mega8 ob er gemeint ist oder nicht.
die mega8 sollen nur zuhören. müssen nichts zurücksenden oder ähnliches.

jetzt weiß ich nicht wie ich das am besten realisieren kann.
mit uart muss ja wenn mich nicht alles täuscht auch was zurückgeschickt werden. ist schonmal schlecht. zumal ich bei den mega8 die timer-pins brauche, könnte dann also nur software-uart nutzen. das wollte ich eigentlich nicht.

ich hab dann nur noch I2C ins auge gefasst. aber da komm ich nicht ganz klar mit wie das bei dem empfang aussieht. kann man damit einfach "zuhören"?

gibt es vielleicht noch andere möglichkeiten?

danke vorab.

gruss Christian

for_ro
02.03.2009, 17:54
Hallo,
mit uart muss ja wenn mich nicht alles täuscht auch was zurückgeschickt werden.
Du brauchst doch kein handshake zu machen. Sollte mich wundern, wenn da immer was zurück muss.

ist schonmal schlecht. zumal ich bei den mega8 die timer-pins brauche, könnte dann also nur software-uart nutzen.
Was haben die Timer Pins mit dem UART zu tun?

Auf dem sendenden Mega32 printest du die 4 bytes einfach, bei den beliebig vielen anderen empfängst du sie über den RxD Pin. Sollte meiner Meinung nach ohne Probleme funktionieren.

Gruß

Rolf

goof1980
02.03.2009, 20:02
das mit den timer-pins stimmt, hab es mit spi verwechselt.

also müsste das funktionieren wenn ich den txd vom master an alle rxd der slaves anschließe, oder?

reicht das dann schon?

for_ro
02.03.2009, 20:43
das mit den timer-pins stimmt, hab es mit spi verwechselt.

also müsste das funktionieren wenn ich den txd vom master an alle rxd der slaves anschließe, oder?

reicht das dann schon?
Ich denke schon. Klar, GND natürlich auch noch miteinander verbinden.

goof1980
02.03.2009, 21:04
Werde es mal probieren.

Besten Dank.

mat-sche
03.03.2009, 17:02
Hi goof1980,

eins hast Du uns noch nicht mitgeteil: wie weit liegen Deine Slaves auseinander?
Ich habe mir ein Bussystem über TWI aufgebaut. Für weite Strecken habe ich dazu einen Buskopppler gebaut (Bild)
So kann ich auch über weite Strecken überbrücken.
Zur Übertragung habe ich die TWI Multimasterumgebung aus der Wiki genommen und so kann ich auch dem Slave etwas senden lassen.

Gruß MAT

goof1980
03.03.2009, 22:43
Also 100% steht das noch nicht fest. Ich schätze jetzt mal zwischen Master und erstem Slave maximal 10m. Die Slaves sind 2m voneinander entfernt. Vorerst sind 8 Slaves geplant.

Hoffe das ist kein Problem. Hatte gehofft das ich keine Verstärker oder sowas brauche.

Gruss Christian

goof1980
20.05.2009, 22:34
Ich habe mich nun entschlossen den Hardware UART zu nutzen. Ich hab also TXD vom Sender mit dem RXD vom Empfänger verbunden und auch GND.

Allerdings blick ich bei den Sende- und Empfangsroutinen noch nicht so richtig durch. Da gibts ja mehrere Möglichkeiten wie man das machen kann.

Ich möchte 4 Bytes senden.

Der Sender verschickt das so:


Printbin Byte1 ; Byte2 ; Byte3 ; Byte4;

Der Empfänger arbeitet so:


' UART-Empfang
If Usr.rxc = 1 Then
' Byte in Empfangspuffer schreiben
Empfangs_byte(empfangs_byte_anzahl) = Udr
' nächstes Byte
Incr Empfangs_byte_anzahl
' wenn alle 4 empfangen dann Speichern zum Auswerten und Starten der Auswertung
If Empfangs_byte_anzahl > 4 Then
Uart_auswerten = 1
Empfangs_byte_anzahl = 1
End If
End If


Aber irgendwie bin ich der Meinung das das so nicht richtig funktioniert. Scheinbar kommen zwar die Bytes an, aber vielleicht verdreht oder sowas. Hab leider kein LCD am Empfänger deswegen kann ich es schlecht kontrollieren. Wenn ich den PC als Empfänger anschließe sieht das senden grundsätzlich schon ganz gut aus.

Bin ich auf dem richtigen Weg? Gibt es vielleicht schönere Routinen die ich nutzen könnte/sollte?

Es muss halt "nebenbei" arbeiten und darf das laufende Programm nicht unterbrechen.

Vielleicht kann mir ja jemand einen Tip geben.

Vielen Dank vorab.

Gruss Christian

Jaecko
20.05.2009, 23:15
Bei dem Buskoppler-Schaltplan fehlen leider noch ein paar Junctions. Ist nicht klar erkennbar, was wo wie verbunden ist.

Ceos
21.05.2009, 00:46
ich hab in etwa dieselbe konstellation (M128 Master, 8 M8 slaves + 1 M32)und verwende RS485, und 1 handshakeleitung, der rest is ne timingfrage, ausserdem benutz ich für jeden slave nen analogschalter/FET

wenn der master an der strippe zieht, gehen die FETs zu und der slave kann nicht mehr ausversehn senden ... damit der slave weis, wann ne wichtige nachricht kommt und wann nur andere slavebytes übertragen werden, hängt die handshakeleitung für die FETs auch an einem Pin dran

das "nebenbei" erledige ich mit nem kleinen empfangspuffer und ISRs, in der ISR schreib ich in den puffer (sofern es kein slavebyte war, aber UDR muss dennoch ausgelesen werden) und während des hauptprogramm an einer unkritischen stelle ruf ich den puffer auf vorhandene bytes ab und reagiere entsprechend

goof1980
21.05.2009, 17:01
hat jemand evtl. einen beispielcode für sender und empfänger?

Ceos
21.05.2009, 19:58
für was? TWI SPI UART ??

goof1980
21.05.2009, 20:56
für UART.

und gleich noch eine Frage. Wartet der Sender beim verschicken eines Bytes per UART irgendwie auf eine Antwort? Ich frage weil ich nur die Sendeleitung nutzen will und keine Rückleitung (damit mehrere Empfänger auf dasselbe Signal hören).

Ceos
22.05.2009, 01:18
nein, der sendet eine fallende flanke( das startbit), dann 8 datenbits(falls es so eingestellt ist) und ein stopbit(falls so eingestellt)

wenn der empfänger das byte nur zu hälfte empfang merkt der sender davon garnichts

hellraider
23.05.2009, 00:42
Ich habe auch so eine ähnliche Konfiguration.
Bei mir sendet ein Atmega8 an 7 andere Atmega8.

Ich habe einen RS485-Bus verwendet, da dieser am Störunanfällisten ist.
Ich verwende einfachen Klingeldraht über Distanzen bis zu ca. 30m
ohne Probleme.

Und Timing-Probleme gibts auch nicht ; es sendet doch in deinem Fall nur der
Master; und der weiss doch wohl, wenn der Bus benutzt wird. !!!

Als Ankopplung an den Bus verwende ich MAX485 im Halpduplexbetrieb.

Gruß

Ceos
23.05.2009, 15:25
halbrichtig hellraider, woher wissen deine slaves, dass die daten auf dem bus vom master tammen und nicht von nem anderen slave ;) ich hab das wie gesagt mit ner "slave talk enabled" leitung und ein klein wneig timing gelöst, mit 1MBaud und maximaler verzögerung durch programmlogik(empfang ist interruptgesteuert, verarbeitung sequentiell im programm eingebaut) hab cih ne reaktionszeit von ca 15-20 µS

TobiasBlome
31.05.2009, 06:52
Also mein Projekt ist noch nicht ganz fertig aber funktioniert soweit:


Der Sender startet eine Anfrage an den entsprechenden Slave.
Also wenn der MASTER von Slave1 den Strom wissen will sieht das so aus:

Print "#S1,Strom"

__________________________________________________ __________
Der Empfang ist etwas aufwändiger:

zuerst wird nachgesehen ob die empfangene Nachricht auch für diesen slave ist. Als nächstes wird nachgesehen was der Master wisssen will: zb. Strom. Dann wird gesendet: von (Slave1) was (Strom) und natürlich der Wert, der ja die eigentliche Anfrage ist ;-) Da das Programm noch im test ist wird alles auf LCD ausgegeben also nicht verwirren lassen. Zur Reichweite kann ich noch nichts sagen. zur Zeit habe ich fliegnde verdrahtung mit 1m klingeldraht und die µC direkt verbunden also auf 5V Pegel und ein Max232 zur kontrolle am PC.




Main:

'auf Empfang reagieren:
If E_flag = 4 Then 'Empfangsstring komplett
If Slave = "S1" Then 'wenn Daten für Slave1

Select Case Parameter

Case "Strom" : Print "#S1,Strom:" ; Strom
Locate 1 , 1
Lcd "S..." ; Slave ; "," ; Parameter ; ":" ; Strom

Case "Volt" : Print "#S1,Volt:" ; Volt
Locate 1 , 1
Lcd "S..." ; Slave ; "," ; Parameter ; ":" ; Volt

Case Else : Print "Err."

End Select


End If

'Daten auf jedenfall löschen
Slave = "" 'Slave löschen
Parameter = "" 'Parameter löschen
Wert = "" 'Wert löschen
E_flag = 0 'Empfang neu setzen
End If

goto Main

'_________
Onrxd:
E_byte = Udr
Select Case E_byte
Case 35 : E_flag = 1 '"#" = Slave wird gesendet
Case 44 : E_flag = 2 '"," = Parameter kommt
Case 58 : E_flag = 3 '":" =
Case 13 : E_flag = 4 '"ENTER" = Empfang komplett
Case Else : If E_flag = 1 Then Slave = Slave + Chr(e_byte)
If E_flag = 2 Then Parameter = Parameter + Chr(e_byte)
If E_flag = 3 Then Wert = Wert + Chr(e_byte)

End Select




Der Master hat natürlich auch eine so ähnliche Empfangsprogrammierung - logisch sonst könnte er ja die eigene Anfrage an den Slave nicht empfangen.

Das meiste davon kannst du ja weglassen, da du ja nur in eine Richtung senden möchtest

viel Erfolg,
Tobias