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