Hallo, Mal eine Frage: Ich will mehrere Atmels miteinander verbinden und suche nach dem richtigen Bus. Ich weiß, dass es SPI, TWI, seriellen usw. gibt. Nur würde ich eine dynamische Adressvergabe benötigen. D.h. wenn ich einen Atmel an den Master anschließe, soll dieser automatisch eine Adresse an den neu angeschlossen AVR vergeben. Funktioniert das mit SPI oder TWI? Außerdem, kann ich an die serielle Schnittstelle des Masters mehrere AVRs anschließen? Dann könnte ich an die uCs gleichzeitig senden, oder? Bin schon gespannt auf eure Antworten! Vielen Dank!! mfg Andy
Hallo nochmals, Hab mich nun ein bisschen "rumgelesen". Ich werde den TWI-Bus nehmen - ist für meine Anwendung der sinnvollste. Nur hab ich noch nicht rausgefunden, wie ich das mit dem dynamischen Adressieren machen könnte. Gibt es beim TWI eine Lösung für so ein Problem, oder muss die Adresse schon beim Flashen bekannt sein? THX... Andy
@ Andreas Posch (andyp17) >Nur würde ich eine dynamische Adressvergabe benötigen. D.h. wenn ich Wirklich? >Adresse an den neu angeschlossen AVR vergeben. Funktioniert das mit SPI >oder TWI? Nein. >Außerdem, kann ich an die serielle Schnittstelle des Masters mehrere >AVRs anschließen? Dann könnte ich an die uCs gleichzeitig senden, oder? Kommt darauf an. - wieviele Slave sind max. am Bus? - Sind diese auf einer Platine/Rack oder weiter entfernt auf verteilten Platinen. >Bin schon gespannt auf eure Antworten! Vielen Dank!! Dynamische Adressvergabe könnte so laufen. Ein neuer Slave wird an den Bus gekopplet. Der bekommt erstmal immer Adress 255. Der Master pollt zyklisch immer, ob auf Adress 255 jemand antwortet. Wenn ja, bekommt er eine eindeutige Adresse. Das klappt aber nur, wenn immer nur ein Slave neu hinzukommt. MFG Falk
Hallo, Das wäre schon mal eine gute Idee. Nur hab ich mich nun schon für den TWI entschieden. Kann ich da nach dem Initialisieren noch die Slave-Adresse ändern? Wie könnte es laufen, wenn neue Slaves auf einmal hinzugefügt werden? Bei mir ist nämlich das Problem, dass ich zuerste alle neuen Slaves installieren muss, und dann erst die Stromzufuhr einschalten kann. D.h. nix mit einzeln hinzufügen... Danke... Andy
>Bin schon gespannt auf eure Antworten! >Nur hab ich mich nun schon für den TWI entschieden. Dann erübrigt sich meine Atnwort. Viel Erfolg!
@Gast, Warum, wäre das mit einem anderen Bus denkbar? Wenn es mit TWI überhaupt nicht geht, könnte ich noch umsteigen :)
@ Andreas Posch (andyp17) >Das wäre schon mal eine gute Idee. Nur hab ich mich nun schon für den >TWI entschieden. Kann ich da nach dem Initialisieren noch die >Slave-Adresse ändern? Theoretisch ja. >Bei mir ist nämlich das Problem, dass ich zuerste alle neuen Slaves >installieren muss, und dann erst die Stromzufuhr einschalten kann. D.h. >nix mit einzeln hinzufügen... Dann wird es sehr kniffelig, vor allem im Zusammenspiel mit I2C. MFG Falk
I2C (das ist das, was Atmel als TWI bezeichnet) besitzt Möglichkeiten zur Initialisierung - via General Call. Die Philips-Dokumentation zu diesem Thema ist m.E. lesenswert. Und Vorsicht mit Adresse 254 u.ä., dieser Adress-Bereich ist für 10-Bit-Adressen reserviert. Bernhard
Könntest auch einen Ring basteln mittels UART (jeweils Tx von einer Station am Rx von der nächsten und so weiter). Klappt wunderbar mit der automatischen adressvergabe ;)
Schau dir mal das SMB protokol an, ab 2.1, dort ist die dynamisch Addressvergabe genau spezifiziert, für i2c (twi) gibt es meines Wissens keine solche Dokumentation, auch wenn es da Angedacht war.
Hallo, Die Idee mit dem Ring gefällt mir. Könnte ich dazu bitte nähere Informationen haben? Wie sieht es dann mit der Leitungslänge aus, wenn ich dann von der letzten Station zu meinem "Master" gehe. Da hätte ich dann u.U. schon 3m. Wäre das noch OK? Besten Dank! mfg Andy
Noch eine Frage dazu: Wie würde es bei der Ring-Lösung mit der Zeit aussehen, die das System für einen Durchlauf brauchen würde. Ich habe eine Anwendung, bei der man so gut wie keinen Verstatz spüren sollte (ich steuere damit LEDs an). Ich weiß, das hängt von der Baudrate ab, aber vielleicht hat jemand Erfahrungen damit. mfg Andy
Die automatische AdressvergABE in einem Ring ist ziemlich simpel. Nach dem Einschalten (oder Reset) hat der Master Adresse 0, alle anderen = undefiniert. Jetzt sendet der Master ein Telegramm nach dem anderen in den Ring. In jedem Telegramm ist eine Adresse enthalten. Nun nimmt der erste Knoten im Ring die Adresse im ersten Telegramm an. Das nächste Telegramm leitet er weiter, da er schon eine Adresse hat -> der zweite Knoten bekommt das Telegramm und nimmt diese Adresse an. Der Master muss nun so lange Adressen vergeben, bis die letzte Adresse, die er gesendet hat, wieder bei ihm ankommt. Nun weiss er, dass alle Knoten adressiert sind und wie viele Teilnehmer es gibt. Die automatische Neu-Nummerierung könntest du so realisieren, dass du in regelmässigen Abständen ein Test-Telegramm schickst. Dieses wird z.B. von allen Teilnehmern unverändert weitergeleitet, ein neuer Knoten könnte aber z.B. dort drin ein Bit setzen o.ä. Wenn das Telegramm dann verändert beim Master ankommt, weiss der, dass es einen neuen Knoten gibt, und vergibt die nächsthöhere Adresse. Wenn das Telegramm unverändert war, gibts keine neuen Knoten. Das mit dem Versatz erachte ich als vernachlässigbar. Sofern du deine Baudrate entsprechend hoch ansetzt. Du musst halt darauf achten, dass die Telegramme immer schnellstmöglich weitergeleitet werden. Wenn du dazu noch eine entsprechende Baudrate hast, wird der zeitliche Versatz minimal sein. Im wesentlichen wird er halt von der Geschwindigkeit bestimmt, mit der dein Programm arbeitet.
Danke für deine ausführliche Antwort - werd das mal probieren. mfg Andy
Nochwas: Wie ist das mit der Leitungslänge?? Wie lang darf die Leitung von TX nach zur nächsten Station (RX) sein? Werde wahrscheinlich 38,4KBaud nehmen. mfg Andy
Hallo, warum weist du nicht einfach dem jeweiligen Steckplatz eine feste Adresse zu und wenn dort ein avr draufgesteckt wird, dann hat der halt diese Adresse? Nun muss nur nach geprüft werden, ob da ein avr gesteckt ist.
@Andreas: Die maximal mögliche Leitungslänge hängt im wesentlichen von deiner Bitrate und den Signalpegeln bzw. dem Treiber ab. Je höher die Bitrate, desto kleiner wird die überbrückbare Strecke. Hier musst du u.U. einen Kompromiss finden zwischen maximal ertragbarem zeitlichen Versatz und der Bitrate. Dann hängt es halt noch vom Treiber und vom Signalstandard ab - mit einem 20 mA Current Loop kannst du sicher eine grössere Strecke überbrücken, als wenn du einen TTL-Pegel überträgst. Aber so wie ich das einschätze, klappt das schon mit einem ordentlichen RS-232. 38,4 kBit ist noch nicht so abartig viel. Vielleicht wäre es hier auch sinnvoll, mal einen Testaufbau zu machen - zwei MAX232 über ein paar Meter Kabelrolle miteinander verbinden und schauen, wie gross die höchste Bitrate ist, die du noch durchkriegst. Zum testen kannst du ja einen simplen Rechteckgenerator an den einen MAX232 hängen, und beim Empfänger schauen, wie das Rechtecksignal dann dort aussieht. Wenns mit dem MAX232 nicht geht, könnte man evtl noch einen MAX487 versuchen, der macht RS-485. Übrigens meine ich mich schwach zu erinnern, mal gelesen zu haben dass man mit 9600 Bit/s bei RS-232 ca. mit 50 m Übertragungsdistanz rechnen darf. Wenn man das linear umrechnet, könnten mit 38.4 kBit/s immer noch 12.5 m möglich sein - wenn denn die 50 m stimmen.
Guten Morgen, Also, meine Anordnung der uC sind wie in der angehängten Skizze. Der Master versorgt alle Slaves mit 3,3V. Die Abstände von Slave zu Slave sind ca 20cm. Es kommen so zwischen 15 und 20 Slaves an den Master (deshalb die individuelle Adressierung). D.h. die Datenleitung vom letzten Slave bis zum Master zurück kann leicht bis zu 4m betragen. Da ich die individuelle Adressierung brauche, will ich es mit der UART machen, weil das glaub ich am einfachsten ist, oder irre ich mich da? Das Ding sollte einmal in großen Stückzahlen produziert werden, deshalb sollte auf jedem Slave das gleiche Programm laufen --> es kann keine Adresse in den Slave reinprogrammiert werden. So, ich hoffe, ich konnte mich deutlich ausdrücken. Besten Dank für eure Hilfe!! mfg Andy
>D.h. die Datenleitung vom letzten Slave bis zum Master zurück kann >leicht bis zu 4m betragen. Wenn du die Rückleitung eh durch die Module durchschleifst, warum nicht ein Puffer andenken? So ist die Rückleitung auch nur 20cm lang. Vielleicht kannst du jedem Slave eine Logik verpassen, die erkennt, ob hinter ihm noch ein Slave folgt. Wenn nicht, kann er die Schleife automatisch schließen..?
Naja, die Rückleitung geht eigentlich nicht durch den uC, sondern verläuft als Leiterbahn auf den einzelnen Slave-Platinen. Also nur Kupferleitungen vom letzten Tx bis zum Rx des Masters... lg Andy
>die Rückleitung geht eigentlich nicht durch den uC Das ist schon klar, aber man könnte einen Treiber reinbauen. ------------- | | ------>---|Rx Tx|--------->------ ... | | ------<---|Rout Rin|---------<------ ... Rin und Rout nicht einfach verbinden, sondern über ein Leitungstreiber zB. Bei RS232 kannst du die beiden unbenutzten Sender/Empf. im MAX232 nutzen. So meinte ich das. Und wenn erkannt wird, dass nix mehr dahinter folgt, wird der TXD Ausgang des µC nicht mit Tx, sondern mit Rout verbunden..
Ach so war das gemeint. Ich kann aber leider keinen Treiber verbauen (Platz- und Kostengründen). Meint ihr, dass ich ohne Treiber Probleme bekomme? lg Andy
>leider keinen Treiber verbauen
Also die µC-Pins würde ich unter keinen Umständen aus der Platine heraus
führen. Wenn die übertragung der UART nicht mit RS232-PEgeln, sondern
mit TTL Pegel erfolgen soll, dann würde ich zumindest ein
(Standart)Logikgatter dazwischen setzen. Und diesen könnte man dann im
meinem obigen Post als Treiber bezeichnen.
> Also die µC-Pins würde ich unter keinen Umständen aus der Platine heraus > führen Was meinst du damit?? Welche Pins soll ich nicht herausführen - und warum? Das mit dem Logikgatter ist gut. D.h. ich sollte auf jeder Slave-Platine beim Rückkanal ein zB ODER-Gatter einbauen?
so wie ich dich verstanden habe, möchtest du auf die MAX232-Pegelwandler aus Platz und Kostengründen verzichten. OK. ist möglich. Das bedeutet, dass du auf den Leutungen TTL Pegel von TXD und RXD hast (nicht +/-10V wie mit Pegelwandler). Du könntest somit DIREKT den TXD-Pin des µC mit dem RXD-Pin des µC auf der hintersitzenden Platine per Kabel verbinden. Das meine ich, das würde ich nicht tun. Ich würde mindestens ebenfalls ein (ODER)Gatter einfügen. Zur Sicherheit, damit dem µC nichts passiert. Man weiß ja nicht, was auf den Leitungen los ist (Kurzschluss, etc..) --------------------------------------------- | | | -------------- | --->----|Rx--[DRV]----|RxD µC TxD|----o--[DRV]--Tx|----->---- | -------------- | | zum Nächsten | | | vom Nächsten ---<----|Rout----------[DRV]-----------XXX-------Rin|-----<---- | | --------------------------------------------- So in etwa: DRV : Treiber zB. ein 74HC573 (Leitungstreiber) XXX : Umschalter, entweder Rin oder TxD auf DRV, je nachdem, ob dahinter noch einer da ist. SO kannst dir die Brücke am Ende sparen.
OK, das klingt vernünftig. Nur brauche ich entweder vor RxD oder nach TxD einen Treiber, nicht auf beiden Seiten, oder? Sonst hätte ich ja immer zwei Treiber hintereinander, oder? Den 74HC573 soll ich anstatt des ODER-Gatters nehmen, oder? Danke für deine Bemühungen...
Mit CAN-Bus kann man sowas schön machen. Einfach einen CAN Controler mit SPI Schnittstelle und die Slaves mit dominantem Identifier auf dem Bus rumbrüllen lassen bis die letzte Atmel seine ID bekommen hat.
@Gast: Danke für deinen Tip. Ich möchte aber die Sache nicht so komliziert machen und es eher einfach gestalten. Außerdem habe ich in diesem Projekt keine Zeit mir den CAN-Bus anzulernen. Trotzdem Danke. mfg Andy
>Nur brauche ich entweder vor RxD oder nach >TxD einen Treiber, nicht auf beiden Seiten, oder? Sonst hätte ich ja >immer zwei Treiber hintereinander, oder? Ja, wären zwei Treiber hintereinander. Halte ich aber für Sinnvoll, sonst hast du ja wieder ein Pin des µC herausgezogen. Dazwischen ist ja die Leitung. Kannst ja noch ein R-C-Netzwerk an den Eingang/Ausgang als Busterminierung machen. Ist sicher nicht unbedingt nötig bei der Baudrate, aber man kann es ja richtig machen. (muss ja zur Not nicht bestückt werden) >74HC573 soll.. Das ist zumindest ein Leitungstreiber. Evtl sollte aber auch der 74xx125 reichen. Da hast du vier Stück drin, sogar schaltbar für XXX in obiger Darstellung.
OK, ist alles schlüssig. RC-Glied meinst du vor bzw. nach dem Treiber, also direkt am Ein-, Ausgang? Gibt es für RC-Glieder irgendwelche Standard-Dimensionierungen (für diesen Fall), oder ist das von Fall zu Fall unterschiedlich? Werd mich da mal erkundigen. Jetzt muss ich mir nur noch Kriterien für das Schalten von XXX überlegen... mfg Andy
>Jetzt muss ich mir nur noch Kriterien für das Schalten von XXX >überlegen... Eine Drahtbrücke, die der nächste Slave schließt?? >Gibt es für RC-Glieder irgendwelche 120Ohm, oder so. (Impedanz der verwendeten Leitung) und nen C, damit der Widerstand nur bei den Flanken wirkt. (keine statischen Verluste) Aber mal was anderes: Warum nimmst du nicht SPI. --------------------------------------------- --->----|SCKin-[DRV]---.. | (CLK wie SS) --->----|\SSin-[DRV]-------o-------------[DRV]-SSout|----->---- | |SS (oder INT) | | -------------- | --->----|IN--[DRV]----|MISO µC MOSI|----o--[DRV]-OUT|----->---- | -------------- | | zum Nächsten | | | vom Nächsten ---<----|Rout----------[DRV]-----------XXX-------Rin|-----<---- | | --------------------------------------------- Da könntest du dir das gesamte Adressieren sparen: Beim Init sendet der Master solange folgende Zahlenfolge per SPI: 0x00,0x01,0x02,0x03,.. bis die 0x00 wieder zurückgekommen ist. Dann wird SS eine pos.Flanke erzeugt. Dadurch (SS oder INT!) übernehmen alle Slaves die Zahl als Adresse. Der entfernteste hat dadurch die 0x01. Der Master weiß auch wie weit er gezählt hat => Anzahl Teilnehmer. Jetzt kannst du Daten an alle Senden. Diese müssen nur in der richtigen Reihenfolge herausgeschoben werden. Das Durchschieben durch die Slaves erfolgt bei SPI OHNE Softwarezutun ;-) (gegenüber deiner jetzigen Idee). Würden #AnzahlTLN_Daten gesendet, wird SS auf HIGH gelegt, Dadurch übernimmt jeder seine Daten. SS auf LOW: Daten werden gesendet. SS GEHT auf HIGH: löst SPI-ready INT aus und übernimmt die Daten. Ergibt: SCK,MISO,MOSI,SS,Rück,Brücke+Supply. mögliche Stecker, Flachkabelbelegung: SCK ----1 2---- GND MISO ----3 4---- GND MOSI ----5 6---- Brücke SS ----7 8---- 5V Rück ----9 10-----5V
@Andreas Posch: die 20cm Distanz zwischen den Teilnehmern sind unkritisch. Allerdings rate ich dir, wie einige andere hier auch, nicht die "nackten" uC-Pins nach aussen zu führen. Durch den Draht hast du ansonsten an jedem uC-Eingang eine hübsche Antenne... Auch rate ich dir ab, mit 3.3V-Pegeln zu arbeiten. Es funktioniert sicher, aber wenn du das ganze später mal ausbauen willst, was ja der Fall sein könnte, so wirst du vielleicht mal noch froh sein wenn du einen etwas dickeren Treiber hast, der dann auch problemlos eine Strecke >20cm überbrcken kann. Wie Lippy bemerkt kannst du als billigen Treiber irgend ein Logik-Gatter nehmen. Ich rate dir zu einem 74xx14 (Hex Schmitt Trigger). Der macht dir dann sicher saubere Pegel und lässt sich von irgendwelchen Störsignalen, die von der Leitung u.U. aufgefangen werden nicht so leicht verwirren. Ausserdem macht er wieder schöne Flanken in dein Signal, das nach einer gewissen Übertragungsstrecke sicherlich nicht mehr ganz optimal ist.
Erstmal danke für deine Idee mit der Drahtbrücke - ist mir auch gerade eingefallen. Ich kann das leider nicht mit spi machen - bin mit den Polen am Stecker beschränkt. Ich werd das jetzt so mit der UART umsetzen - ich glaube, das wird funktionieren. Die Adressierung hab ich auch schon durch. Ich schicke einfach ein Byte durch, das in jedem Slave inkrementiert wird (=Adresse). Somit sendet der letzte Slave seine Adresse an den Master und das ist dann gleich die Anzahl der Slaves. Nur das mit der Busterminierung würde mich noch interessieren - damit ich alles richtig mache. lg Andy
>Busterminierung würde mich noch interessieren
kann es doch. Also direkt an jeden Eingang und Ausgang ein R-C Netzwerk
nach Masse legen.
PS: Und denk an die Abblockelkos direkt an den Eingängen
Hallo nochmal, Ich habe wirklich wenig Platz auf der Platine, deshalb wollte ich fragen, ob es klug ist, wenn ich auf den externen Quarz verzichte und ich den interen 8Mhz Oszillator nehme und ich dafür die Baudrate auf 9600Baud runterschraube. Ginge das OK, oder hat da jemand Zweifel daran, dass das funktioniert?? mfg Andy
Warum bleibst Du nicht bei TWI? Die Taktfrequenz ist unkritisch und die Übertragung viel schneller. Und wenn es besonders langsam sein soll, geht TWI auch mit 0Hz. Spötter sagen dazu: der Bus hängt. Außerdem reichen keramische Cs zum Abblocken an Ein- und Ausgängen. Die dicken Elkos können entfallen.
@Gast: Geht nicht wegen meines Adressierungsproblems!
OK, hab ein bisschen rumgelesen - ich nehm einen Quarz. Sollte doch stabil laufen. Nur noch ein: Glaubt ihr, bekomme ich Probleme, wenn ich die 3.3V vom Master bis zum letzten Slave durchschleife und damit auf jedem Slave einen Mega88, einen 74HC125, ein Single OR-Gate und einen NTC mit Spannugssteiler fürn ADC betreibe. Könnten doch 3m (ca. 15 Slaves) werden. THX Andy
Was glaubt ihr bezüglich der 3,3Volt auf mehrere Meter? Problematisch?
Ich würde es nicht tun. aus demselben Grund wie die Treiber vor hinter den TxD & RxD Pins.
@Falk: Worauf?? @Matthias: Ja, aber auf den 3.3V übertrage ich keine Daten. Ist nur Versorgungsspannung.
@ Andreas Posch (andyp17) Auf die Randbedingungen. - Welche Ströme fliessen über die Masseverbindungen? - Welche Störquellen gibt es im Umfeld? MfG Falk
@Falk: Also, pro Slave einen Mega88, ein Single OR, einen 74HC125, einen NTC im Spannungsteiler und bisschen externe Beschaltung (R und C). Ich schätze so ca. 50mA - 70mA pro Slave. Es werden zwischen 15 und 20 Slaves angeschlossen --> so ca. 1A gehen schon drüber. Störquellen: Ich erzeuge PWM-Signale mit 250Hz, die LED-Stromquellen dimmen. Diese Stromquellen erzeugen mit gleicher Frequenz Ausgangsspannungen bis 24V und einigen Ampere. Außerdem wird in unmittelbarer Nähe ein ZigBee-Modul betrieben. Was meinst du?
@ Andreas Posch (andyp17) >so ca. 50mA - 70mA pro Slave. Es werden zwischen 15 und 20 Slaves >angeschlossen --> so ca. 1A gehen schon drüber. Über welche Leitungslänge? >Störquellen: Ich erzeuge PWM-Signale mit 250Hz, die LED-Stromquellen >dimmen. Diese Stromquellen erzeugen mit gleicher Frequenz >Ausgangsspannungen bis 24V und einigen Ampere. >Außerdem wird in unmittelbarer Nähe ein ZigBee-Modul betrieben. >Was meinst du? Das wird eher knapp. Nimm RS485 und gut. Das ist auch ein solider Busstandard. MFG Falk
OK, hab gerade mit meinem Kollegen gesprochen. Ich muss mir eine Alternative einfallen lassen. Mit den 3.3V hab ich auf 3-4m einen zu hohen Spannungsabfall. Da ich aber auf jeder Platine sowieso 24V zur Verfügung habe, muss ich diese auf 3.3V bringen. Das Problem ist aber, dass diese "Transformation" extrem effizient sein muss, d.h. nix mit Konstantpannungsregler á la 7805... Ich brauche einen DC/DC-Wandler oder so was ähnliches. Irgendwelche Ideen??
Bau nen kleinen Schaltregler auf. zB mit nem SG3524D. Bei Ausgängsstromen vom <100mA kannst du beide internen Transistoren parallel schalten. Dazu ne Drossel+Diode+Elko+Hühnerfutter. Bei 110kHz sollte die Drossel auch ziemlich klein bleiben.. PS: Ja, etwas Platz braucht das schon, aber von nix kommt nix...
@ Andreas Posch (andyp17) >Ich brauche einen DC/DC-Wandler oder so was ähnliches. Irgendwelche >Ideen?? MC34063. Klein (SO-8) und billig (24 Cent). Dazu noch ein paar Widerstände und ne SMD-Drossel, fertig. Siehe Konstantstromquelle, dort gibts auch Links zum IC. MfG Falk
OK, hab den Artikel angesehen. Was mir aber noch nicht klar ist: Wie stelle ich die 3.3V ein, wenn ich 24V eingangsseitig anlege? Sorry, für die "dummen" Fragen, aber ich kenn mich bei diesem Gebiet nicht aus. mfg
@ Andreas Posch (andyp17) >OK, hab den Artikel angesehen. Was mir aber noch nicht klar ist: Wie >stelle ich die 3.3V ein, wenn ich 24V eingangsseitig anlege? Über einen Spannungsteiler. Das Datenblatt und der Onlinecalculator sind deine Freunde. MFG Falk
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.