Hallo Ihr, ich habe ein wunderbares Netzwerk mit einem Master und diversen Slaves, die über TWI kommunizieren. Um das ganze etwas zu vereinfachen würde ich gerne die Slaves über Broadcast ansprechen, leider funktioniert das Ganze nicht. Als Master arbeitet eine Arduinio, hier ist Broadcast gestestet und läuft. Probleme machen die Slaves, ATMega8 mit 16 MHz, AVR-Studio und C. Ich hatte gehofft, dass ich nur die Zeile für die Slave Adresse von: TWAR = (Address << 1); in: TWAR = (Address << 1) | 1; ändern muß, leider klappt das nicht. Kann mir jemand helfen? Gruß Marc
Hallo Du,
ein Broadcast nennt sich in der I2C/TWI-Terminologie "General Call".
Dazu wird die TWI-Adresse "0" benutzt.
Aber:
Die Slaves müssen dafür konfiguriert sein, dass sie nicht nur auf ihre
TWI-Adresse sondern auch auf einen General-Call reagieren.
Und dem Programm im Hintergrund auch mitteilen können, dass sie via
General-Call angefunkt wurden.
Wie das bei den Arduinos "handwerklich" gelöst ist, dass kann ich Dir
nicht sagen.
Übrigens:
> TWAR = (Address << 1) | 1;
führt einen Lesezugriff auf dem TWI-Slave mit der Adresse "Address" aus.
mfg
Michael S.
Hallo Marc, die TWI-Bearbeitung in den Slaves erfolgt üblicherweise über eine Abfrage des Status-Registers. Bei General Calls treten im Slave andere Statuscodes auf als bei direkter Adressierung des jeweiligen Slaves - siehe die entsprechenden Datenblätter von ATMEL (Status Codes im Slave Receiver Mode bzw. im Slave Send Mode). Deine Slaves reagieren vermutlich nicht auf die entsprechenden Status-Codes von General Calls des Master. Hier ist also zusätzliche Programmierung erforderlich. Bernhard
Neuere AVRS (z.B. ATmega88) haben das TWAMR – TWI (Slave) Address Mask Register. Damit kann der Slave auf mehreren Adressen empfangen. Peter
Hallo Ihr, ich bedanke mich für Eure Antworten. Leider sind meine Programmierfähigkeiten (noch) nicht so weit fortgeschritten, dass ich ich die Tipps direkt umsetzen kann, da muß ich noch etwas Zeit mit dem Studium der Datenblätter und Grundlagen investieren. Wenn jemand einen funktionierenden Codeschnipsel in C hätte, den ich dann nur anpassen müsste, wäre das echt super. Ich möchte mich aber trotzdem bedanken, das Forum ist ja kein Selbstbedienungsladen, es soll ja nur Hilfestellung geben und dem Erfahrungsaustausch dienen. Ohne Eigeninitiative geht es halt nicht. Gruß Marc
Hallo Ihr, Michael S. schrieb: > Übrigens: > >> TWAR = (Address << 1) | 1; > > führt einen Lesezugriff auf dem TWI-Slave mit der Adresse "Address" aus. > > > mfg das verstehe ich nicht, eigentlich müsste damit doch das TWAR-Register von links mit der Adresse gefüllt werden und das LSB (TWGCE) gesetzt werden, um Generall Call einzuschalten. Gruß Marc
Hallo Marc, Uralter Beitrag, habe ihn aber per Google gefunden also trage ich mal fix ne Lösung nach:
1 | void i2c_idleGC(){ |
2 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); |
3 | while(TWSR != TW_SR_GCALL_ACK); |
4 | }
|
5 | i2c_recognizeSync(){ |
6 | TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWEA); |
7 | while(!(TWCR & (1 << TWINT))); |
8 | while(TWSR != TW_SR_GCALL_DATA_ACK); |
9 | //test if command is truly SEND_START ? ..
|
10 | }
|
das sind zwei wichtige Funktionen für deine Slaves, du hast richtig gedacht, du setzt via TWAR die Addresse der Slaves + 1. Wichtig ist vorallem, was auch schon erwähnt wurde, dass der Statuscode bei den Slaves anders ist... und master sowas:
1 | i2c_start(); |
2 | i2c_sendAdd(0x00); |
3 | if(i2c_awaitStatus(TW_MT_SLA_ACK)) println("Someone was not rdy, hmm dont care."); |
4 | println("Sending start!"); |
5 | i2c_send(SEND_START); |
6 | _delay_ms(1); |
7 | i2c_stop(); |
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.