Forum: Mikrocontroller und Digitale Elektronik Saubere I2C Kommunikation


von Ehren (Gast)


Lesenswert?

Hallo zusammen,

momentan sende ich Daten vom Master zum Slave. Der Slave kopiert im 
Interrupt (Stop-Bit) den Buffer mit der empfangenen I2C-Nachricht in 
einen RAM-Buffer. Diesen möchte ich in der Main-Loop verarbeiten. Wie 
stelle ich sicher, dass mir bei einen neuen Interrupt der RAM-Buffer 
nicht wieder überschrieben wird, obwohl ich den RAM-Buffer in der 
Main-Loop noch nicht verarbeitet habe.
Ich wollte jetzt nicht den RAM-Buffer größer machen (momentan 25 Byte), 
da ich nur 1 kByte RAM habe. Zudem will ich die Nachricht nicht direkt 
im Interrupt verarbeiten. ???

Danke im voraus!

Gruß

von Cyblord -. (cyblord)


Lesenswert?

Du sperrst den Buffer bis der Inhalt verarbeitet wurde. Vorher darf 
nichts neues rein. Das führt aber evt. zum Verlust von Nachrichten. Das 
kannst du einfach über ein lockbit/byte Flag realisieren. Die I2C 
Empfangsroutine wertet das Flag aus und verwirft ankommende Bytes wenn 
das Flag gesetzt ist.

Es gibt nur 2 Möglichkeiten: Entweder die Nachrichten kommen zeitlich 
langsam genug an, dann ist alles ok, oder sie kommen schneller als du 
sie verarbeiten willst/kannst. Dann musst du entscheiden: Speichern in 
einem Buffer welcher groß genug ist, oder Buffer sperren und Nachrichten 
verlieren.

von Jim M. (turboj)


Lesenswert?

Ehren schrieb:
> Wie
> stelle ich sicher, dass mir bei einen neuen Interrupt der RAM-Buffer
> nicht wieder überschrieben wird, obwohl ich den RAM-Buffer in der
> Main-Loop noch nicht verarbeitet habe.

Wenn das I²C Interface ordentliches Clock-Stretching macht, dann einfach 
den I2C-Interrupt deaktivieren und in main() nach der Verarbeitung 
wieder anschalten.

von (prx) A. K. (prx)


Lesenswert?

Wenn du keine einlaufenden Daten willst, dann kannst du den µC dagegen 
sperren, indem du I2C deaktivierst, bis der Puffer verarbeitet ist. Der 
Master kriegt dann NACK.

Alternativ liesse sich ggf. Clock Stretching nutzen, um einen 
Master-Zugriff so lange anzuhalten, bis der Slave wieder aufnahmefähig 
ist. Dazu müsste man dann aber mehr über den Slave wissen.

Nicht jeder Master kann Clock Stretching sauber verarbeiten. Zwei die es 
nicht können sind Bus Pirate und Raspberry Pi.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Genau wie cyblord schreibt; wobei ich nicht den Buffer sperre, sondern 
i2c erst gar nicht wieder aktiviere. Sendet der Master weiter, kriegt er 
ein NAK (bzw. keine Antwort). Das kann natürlich den Master verwirren. 
Wenn du den Master selbst unter Kontrolle hast, kannst du dort ein 
sauberes Retry machen. Ist die Nachricht verarbeitet, aktivierst du den 
Slave wieder.

Ich mach das so bei meinen i2c-LCD-Slaves.

edit: andere waren schneller...

von uwe (Gast)


Lesenswert?

Nen Double Buffer könnte sich schon lohnen. Wenn die main halt die Daten 
verarbeitet kann in einem zweiten Bufferempfangen werden.
Sollte dieser auch voll sein wird hoffenlich der erste bald wieder frei 
sein.
Solange muß das Protokoll halt dafür sorgen das dem Sender mitgeteilt 
wird warte mal bzw. bitte wiederhole noch mal die Nachricht.
Machst du ja auch so wenn du dir ne Handy nummer aufschreibst: Äh was 
kam nach der 5 Ziffer?? Kannst du noch mal wiederholen?!

von Ehren (Gast)


Lesenswert?

Hallo zusammen,

Danke für die Antworten. Werde versuchen den I2C zu deaktivieren, bis er 
die Nachricht verarbeitet hat. Ansonsten muss ich mal schauen wie groß 
ich meinen Ringspeicher machen kann...

Danke und Gruß

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.