TWI - Wie lege ich die Adresse eines Slaves fest? Ich möchte 2 Mikrocontroller mit dem TW - Interface verbinden. Einer soll duaerhaft nur empfangen, der andere senden. Ich habe diese Frage dazu: Wie lege ich die Adresse des empfangenden Mikrocontrollers fest? In einem Buch habe ich gelesen, dass die Slaves normalerweise eine feste Adresse besitzen oder diese durch Konfigurationspins eingestellt werden kann. Ich denke aber, dass dies (nur) vor allem für Speicherbausteine, Sensoren,... so ist. Und nur mal angenommen, dass die Adresse am Anfang programmiert wird. Wenn ich 10 Mikrocontroller verbunden hätte - müssten alle einzelnd an den Master angeschlossen werden, um die Adresse zu erhalten?! Tut mir leid, falls es eine dumme Frage ist. Bin über jede Hilfe sehr dankbar
Twinky schrieb: > In einem Buch habe ich gelesen, dass die Slaves normalerweise eine feste > Adresse besitzen oder diese durch Konfigurationspins eingestellt werden > kann. > Ich denke aber, dass dies (nur) vor allem für Speicherbausteine, > Sensoren,... so ist. Es spricht nichts dagegen, mit einem µC (wir reden doch hier von AVR?) genau dasselbe zu machen. Die AVR haben ein Register, TWAR, und was immer der Slave beim Hochfahren des Programms dort hineinschreibt, das ist seine Adresse. Wie der Slave zu seiner Adresse kommt, das entscheidet das Programm, welches auf ihm läuft. > Und nur mal angenommen, dass die Adresse am Anfang programmiert wird. > Wenn ich 10 Mikrocontroller verbunden hätte - müssten alle einzelnd an > den Master angeschlossen werden, um die Adresse zu erhalten?! Das kann man so nicht sagen. Das kommt ganz drauf an, wie das Programm aussieht, welches im Slave läuft. Das entscheidet, wie sich das abspielt. Also: Du darfst hier ruhig kreativ sein und Gott spielen. Was auch immer dir gefällt, wie der Slave zu seiner Adresse kommt, das ist Gesetz. Wenn das ein kleines Mäuseklavier ist, mit dem der Endanwender die 7 Bit der Adresse festlegt, dann ist es eben das. Das Programm welches am Slave läuft holt sich die 7 Bit vom Mäuseklavier und schreibt sie ins TWAR Register. Und fortan hört dieser AVR auf diese TWI Adresse. Wenn dir was anderes einfällt und das anders machen möchtest und es auch programmieren kannst, dann geht der Mechanismus eben anders. Aber alles endet damit, dass das Programm mal einen Wert ins TWAR schreibt.
Im Allgemeinen legt im Falle uC Dein Programm zur Laufzeit die Slaveadresse fest - dadurch daß es in die entsprechenden Register (Datenblatt!) des TWI Moduls die passenden Werte schreibt. Hilft Dir das weiter? -Horsi
solange du ein Geheimnis daraus machst, um welche µCs es geht, wird dir niemand wirklich helfen können... Twinky schrieb: > Und nur mal angenommen, dass die Adresse am Anfang programmiert wird. > Wenn ich 10 Mikrocontroller verbunden hätte - müssten alle einzelnd an > den Master angeschlossen werden, um die Adresse zu erhalten?! und das eigentliche Programm beamt sich selbst in die Slaves oder was?
Danke an Karl Heinz Buchegger und Horst :), hat mir sehr geholfen und alles auf den Punkt gebracht. Ps: ja wir reden von einem AVR wünsche noch einen schönen Tag
Nun habe ich die Adresse des Slaves folgendermaßen zugeordnet: TWAR |=0x40; // Adresse, die der Master anspricht und versucht ein Programm mit Hilfe des Datenblatts zu schreiben. Leider funktioniert es nicht, der Master gibt keinen Messbaren SCL Takt aus und das Programm hängt in der ersten while schleife: void twi_senden(uint8_t data) { TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); // TWINT reseten, Startbedingung, PINS SCL und SDA verwenden while (!(TWCR &= (1<<TWINT))) // Warten bis dies durchgeführt wurde. { ; } Mein Aufbau beinhaltet 2 Controller (Atmega 168P, Atmega 168), die jeweils beide mit SCL bzw. SDA verbunden sind. An beiden Leitungen wurden Pullup Widerstände 5k zu 5 Volt eingesetzt. Als "data" habe ich zum Testen einen konstanten Wert verwendet. anbei habe ich die beiden Codeteile, die eigentlich dafür verantwortlich sein sollten (denke ich), beigefügt.
Twinky schrieb: > anbei habe ich die beiden Codeteile, die eigentlich dafür verantwortlich > sein sollten (denke ich), beigefügt. leider liegen Fehler oft nicht dort, wo man sie vermutet. Anscheinend hast du noch nicht sehr ausgiebig hier im Forum gestöbert, sonst wäre dir aufgefallen, dass sehr häufig bemängelt wird, dass - c-Dateien nicht auf .c enden (damit sie besser lesbar sind) - Programm-Texte nicht entsprechend formatiert sind (gleicher Grund) - Programm-Auszüge unvollständig sind (Fehler sind vielleicht in den nicht dargestellten Teilen) - Programm-Auszüge gar nicht kompilierbar sind (man kann es nicht mal eben ausprobieren) Vieleicht alles Gründe, warum so lange keiner geantwortet hat. Es scheint mir, als sei dieses dein erstes TWI-Projekt. Da ist es ungünstig, sich gleich zwei Baustellen auf einmal einzurichten (Master UND Slave). Wann immer ich an der Master-Sofware herumbastle, benutze ich zuerste einen fertigen Slave (Port-Expander PCF8574, oder RTC). Über den Port-Expander kann man dann auch leicht ein LCD-Display für Debug-Zwecke anschließen. Auch als sehr sinnvoll zur Fehlersuche hat sich der TWI-Sniffer Beitrag "I2C (TWI) Sniffer mit AVR" erwiesen. Wenn der Master dann läuft, geht's an den Slave. Noch ein paar Kleinigkeiten:
1 | TWBR |=0x08; // Bit rate Register auf 2 gesetzt. berechnet um SCL von 250000 Hz zu erhalten |
2 | // wer soll/kann prüfen, ob das richtig ist?
|
3 | // bei mir sieht das so aus (aus einem Beispiel abgeschrieben):
|
4 | TWBR= (((F_CPU/TWI_CLOCK)-16)/2); |
5 | |
6 | // oder das:
|
7 | SREG |=0b10000000; // globale Interrupte erlauben |
8 | |
9 | // ist das das richtige Bit? dafür gibt es doch
|
10 | sei(); |
11 | |
12 | |
13 | if((TWSR & 0xf8) == 0x60) //Der Slave erkennt seine Adresse und erhält die SLA+W Anweisung des Masters |
14 | |
15 | //für die Konstanten gibt es in einem der Beiträge hier im Forum eine Header-Datei, wo die alle definiert sind, z.B.
|
16 | // TWI Slave Receiver status codes
|
17 | #define TWI_SRX_ADR_ACK 0x60 // Own SLA+W has been received ACK has been returned
|
18 | // ...
|
man muss nicht alle Räder neu erfinden. Es bleibt auch sonst noch genug zu tun. Viel Spaß und Erfolg.
Ich hoffe es sind nun die richtigen Formate. In dem beiden Programmen befinden sich noch alle Variabeln (Master+Slave), da das Programm früher ein zusammenhängendes war. Da aber die Ausführung zu lange gedauert hat habe ich mir das mit den beiden Controllern überlegt. Tut mir leid für diese ganzen Anfängerfehler :/ Und schonmal vielen Dank für deine Hilfe. Finde ich wirklich klasse, dass du dir dafür zeit genommen hast :).
Ohje bin ich besoffen?! Das sind ja beides die gleiches Programme. Slave war falsch. Hier also der richtige
habe mal kurz mit meiner SW, die auch irgendwo in diesem Formum ihren Ursprung hat, verglichen:
1 | while (!(TWCR &= (1 << TWINT))) // Warten bis dies durchgeführt wurde. |
2 | // ^ das gehört da nicht hin.
|
Weiter habe ich noch nicht geschaut. Ich kann nur empfehlen, zunächst nach einer fertige SW zu suchen und die dann nach und nach den eigenen Bedürfnissen anzupasssen. Das ist nicht so frustrierend, und man kann auch eine Menge dabei lernen.
> TWAR |=0x40; // Adresse, die der Master anspricht
Danach ist die Adresse nicht 0x40, sondern ein Mischmasch auf 0x40 und
dem Wert, der vorher in dem Register stand. Ich bezweifle, dass Du hier
eine ODER Operation durchführen wolltest.
Danke für die Berichtigungen. Habe heute das ganze mit einem frischen Kopf angeschaut und einiges verändert. Werde es später dann ausprobieren. Ich habe nur den Beruf des Industriemechanikers gelernt :/ und habe noch eine Frage an Stefan. Warum kann ich das nicht mit dem Oder verknüpfen, das wird doch nicht mehr verändert? Habe bestimmt wieder irgendwas vergessen :/
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.