Hallo, ich hoffe, die Frage wurde nicht schon tausend mal gestellt und ich habs nur nicht gefunden, aber ich habe folgendes Problem. Ich möchte zwei Controller per TWI miteinander kommunizieren lassen. Dabei sollen die zu übertragenden Daten jedoch variabel lang sein. Auf Empfängerseite weiß ich jedoch erst beim Empfang des letzten Bytes, dass es das letzte war. Also eigentlich schon zu spät, um ein NACK zu senden. Wenn ich TWCR erst jetzt so setze, dass er ein NACK sendet, wird das nächste Start byte vom Master 'abgelehnt', und die zweite Übertragung schlägt dadurch fehl. Wie wird sowas elegant gelöst? Mir fallen spontan folgende Wege ein: - keine Variable Länge - nach dem Senden des letzten Bytes (auf Senderseite) einfach noch ein 'Füllbyte' senden - Längenangabe als erstes Byte Oder habe ich vielleicht ein prinzipielles Rangehensproblem? Danke Dirk
Tach Dirk, ein Herangehensproblem ist das sicherlich nicht. Allerdings lässt du viele Fragen offen. Ich stückle mir das mal zusammen: Du benutzt AVRs? Der Master empfängt eine undefinierte Zahl bytes? Ich gehe mal davon aus. Die eleganteste Variante ist den slave die Framelänge bekannt geben zu lassen. Sprich das erste byte vom slave zum master ist das längen byte. Die unelegantere Variante ist ein Stopzeichen zu definieren. ZB eine 0 oder 255 oder sonst was. Unschön ist natürlich, dass dieses Zeichen dann nicht mehr in den Nutzdaten auftauchen darf. Man muss also auch noch ein Ersatzzeichen definieren, das das Stopzeichen gegebenfalls maskiert. Es ist eigentlich wieder eine uhralte Glaubensfrage: Pascal arbeitet mit Längenbyte und C mit Stopzeichen. Thor
Alex S. schrieb: > Es ist eigentlich wieder eine uhralte Glaubensfrage: Pascal arbeitet mit > Längenbyte und C mit Stopzeichen. Der Unterschied ist nur, dass Pascal beliebige Zeichen übertragen kann, C nicht. Bei jedem 0x00 geht C von einem Stringende aus.
Hi Das ist doch eindeutig geregelt. Wenn der Master sendet beendet er die Übertragung mit STOP. Und wenn er empfängt beendet er das mit NACK+STOP. MfG Spess
Wolfgang schrieb: > Alex S. schrieb: >> Es ist eigentlich wieder eine uhralte Glaubensfrage: Pascal arbeitet mit >> Längenbyte und C mit Stopzeichen. > > Der Unterschied ist nur, dass Pascal beliebige Zeichen übertragen kann, > C nicht. Bei jedem 0x00 geht C von einem Stringende aus. Also String sind in C keine beliebigen Daten, sondern Text. Und in einem Text kommen selten 0x00 Bytes vor. Wieso sollte man Nullbytes als Nutzdaten in einen String packen wollen? Das macht überhaupt keinen Sinn. gruß cyblord
Tach allerseits, : Der Unterschied ist nur, dass Pascal beliebige Zeichen übertragen : kann, C nicht. Bei jedem 0x00 geht C von einem Stringende aus. so sieht's aus. Bei den ANSI strings wurde kein Maskierungszeichen definiert. Hätte man das gäbe es keinen praktischen Unterschied zwischen den beiden Varianten. Außer, dass the pascal side of the force halt eine Ecke eleganter ist. : Das ist doch eindeutig geregelt. Wenn der Master sendet beendet er die : Übertragung mit STOP. Und wenn er empfängt beendet er das mit : NACK+STOP. Mhh, und was ist, wenn der master nicht weiß wie lang der frame ist? Thor
Tach : Also String sind in C keine beliebigen Daten, sondern Text. Und in einem Text kommen selten 0x00 Bytes vor. Wieso sollte man Nullbytes als Nutzdaten in einen String packen wollen? Das macht überhaupt keinen Sinn. Schon mal die API comport Funktionen benutzt? Die sind nun mal stringbasiert. Und da kann es schon mal vorkommen, dass man eine binäre null senden/empfangen möchte. Ich stimme dir ja auch zu, dass strings nicht geeignet sind binäre Daten aufzunehmen. Trotzdem sind sie einfach so verdammt einfach als dynamische Arrays zu misbrauchen und finden desshalb auch nicht nur als Textspeicher Anwendung. Thor
cyblord ---- schrieb: > Also String sind in C keine beliebigen Daten, sondern Text. Das ist schon eine "tolle" Kodierung, bei der man nicht alle möglichen Codes verwenden darf, sondern auf einen Sub-Set beschränkt ist.
Pascal- gegen C-Strings für die Eignung zur TWI-Übertragung abwägen? - Setzen, SECHS! Würde auch der beste Lehrer sagen. Wer was missbraucht, muss wissen, was er tut. Wenn was "Merkwürdiges" dabei rauskommt, wusste er/sie das wohl eindeutig nicht! ;-)
Hi Macht euch doch keinen Kopf. Der TO hat lediglich ein Verständnisproblem. Und ihr wahrscheinlich auch. MfG Spess
Hätte ich geahnt, dass das so ausartet... :D Ich wollte lediglich ein Best-Practice o.ä. wissen order einfach eine zweite Meinung (danke an die erste Antwort ;) ) Aber zur Klärung: Da sollen beliebige Binärdaten rübergehen, u.a. Strings. Da ich jedoch die Länge der Daten benötige, um zum richtigen Zeitpunkt mit NACK zu antworten, gebe ich die Länge der Daten als erstes Byte mit. Da wäre es sinnlos mit speziellen Start und Stop Bytes zu arbeiten, da diese dann im Payload escaped werden müssten. Das setzt natürlich voraus, dass der Master beim absenden schon weiß, wieviele Daten es sind. Weiß selbst er das nicht und es entscheidet sich einfach im Laufe der Übertragung, wann schluss ist, müsste man natürlich zusätzlichen Stop Markierungen arbeiten. So...jetzt sollten alle glücklich sein! Ich bin es :) Gute nacht!
Hi >Da ich jedoch die Länge der Daten benötige, um zum richtigen Zeitpunkt >mit NACK zu antworten, gebe ich die Länge der Daten als erstes Byte mit. >Da wäre es sinnlos mit speziellen Start und Stop Bytes zu arbeiten, da >diese dann im Payload escaped werden müssten. Das setzt natürlich >voraus, dass der Master beim absenden schon weiß, wieviele Daten es >sind. Sieh dir bitte mal die I2C-Spezifikation in Ruhe an. Der Slave sendet kein NACK. MfG Spess
Ich hab mich an das Atmega64 Datenblatt gehalten, welches sagt: "When the Receiver has received the last byte, or for some reason cannot receive any more bytes, it should inform the Transmitter by sending a NACK after the final byte. " Dirk
>: Das ist doch eindeutig geregelt. Wenn der Master sendet beendet er die >: Übertragung mit STOP. Und wenn er empfängt beendet er das mit >: NACK+STOP. >Mhh, und was ist, wenn der master nicht weiß wie lang der frame ist? Der Master weiss immer wie lang der Frame ist. Er holt ihn ja schliesslich aktiv ab, bzw. der Slave sendet nichts von alleine. Dein Problem ist also keins.
Hi >Ich hab mich an das Atmega64 Datenblatt gehalten, welches sagt: >"When the Receiver has received the last byte, or for some reason cannot >receive any more bytes, it should inform the Transmitter by sending a >NACK after the final byte. " Der Satz im Datenblatt ist etwas unglücklich da nicht ersichtlich ist, um welchen Mode es sich handelt. Sieh dir mal weiter hinten im Datenblatt Transmission Modes->Master Receiver Mode an. Dort siehst du, wer wann ACK bzw. NACK sendet. MfG Spess
Hi
>Ich bin aber im Slave receiver mode.
Da wird jedes Byte vom Slave mit einem ACK bestätigt bis der Master Stop
sendet. Ausnahme: der Slave kann keine Daten mehr aufnehmen. Dann sendet
er ein NACK.
MfG Spess
Hi
>Also auch das letzte Byte?
Ja. Nach dem letzten Byte sendet der Master STOP. Du bringst irgend wie
Master und Slave Receive Mode durcheinander.
Im Master Receive Mode kennzeichnet der Master das letzte Byte mit einem
NACK.
MfG Spess
So grad probiert...funktioniert nicht. Ich befürchte grad, der Fehler liegt ganz woanders. Nochmal als ganzes: Ein Controller im Master transmitter Mode, ein anderer im Slave receiver Mode. - Master sendet start. - Master sendet SLA+W und empfängt ACK - Master sendet Bytes und Slave antwortet auf JEDES Byte mit ACK. - Master sendet Stop und Slave setzt TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA); - Master sendet Start für neue Übertragung - Master sendet SLA+W und empfängt NACK Was mache ich falsch? VG Dirk
Wenn der TWI State Machine nicht im Vorhinein das letzte Byte signalisiert wird, dann wird durch die State Machine ein Fehler signalisiert sobald das STOP eintrudelt. Wenn man dann seinerseits per STOP der State Machine das Ende der Übertragung signalisiert, dann ist alles wieder in Butter. Wenn man beim Fehlerzustand jedoch beleidigt oder garnicht reagiert, dann geschieht das hier Beschriebene.
Reicht es, im SR TWCR = (1<<TWEN)|(1<<TWIE)|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO) zu setzen, wenn Stop empfangen wurde? Bleibt nämlich das selbe Verhalten :(
Siehe "Miscellaneous States" im Datasheet des weiterhin geheimnisvoll bleibenden Controllers. Ansonsten empfehle ich dir, beiderseits der Übertragung die TWI States zu protokollieren um festzustellen, was konkret abgeht.
Die States des SR hab ich da: $60 - SLA+W empfangen - ACK geantwortet $80 - Byte empfangen - ACK geantwortet ... $A0 - STOP empfangen - TWINT + TWEA gesetzt (Switched to the not addressed Slave mode; own SLA will be recognized) Von der zweiten Übertragung ist im SR schon nichts mehr zu merken. Auf der MT Seite erhalte ich auf die zweite Start Anforderung ein NACK. VG
Dirk R. schrieb: > $A0 - STOP empfangen - TWINT + TWEA gesetzt (Switched to the not > addressed Slave mode; own SLA will be recognized) Dann ist der garnicht so pingelig wie ich dachte. Könnte es sein, dass der Master es so eilig hat, dass er den Slave schon mit dem zweiten START überrennt, bevor der seinen Abschluss getan hat?
Ich geh kaputt!! Daran lags wirklich...hatte zum Testen einfach zwei Nachrichten nacheinander verschickt. Das kann man aber nicht vorher prüfen, oder? Da hilft nur nochmal probieren?! VG
Ich habe bei sowas ohnehin ein paar Retries drin. Gern auch mit Bisschen Pause dazwischen.
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.