Forum: Mikrocontroller und Digitale Elektronik TWI - Wie lege ich die Adresse von einem Slave fest?


von Twinky (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Horst (Gast)


Lesenswert?

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

von Justus S. (jussa)


Lesenswert?

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?

von Twinky (Gast)


Lesenswert?

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

von Twinky (Gast)


Angehängte Dateien:

Lesenswert?

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.

von Josef D. (jogedua)


Lesenswert?

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.

von Twinky (Gast)


Angehängte Dateien:

Lesenswert?

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 :).

von Twinky (Gast)


Angehängte Dateien:

Lesenswert?

Ohje bin ich besoffen?! Das sind ja beides die gleiches Programme.
Slave war falsch. Hier also der richtige

von Josef D. (jogedua)


Lesenswert?

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.

von Wusel D. (stefanfrings_de)


Lesenswert?

> 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.

von Twinky (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.