MCU-zu-MCU-I2C-Kommunikation

Ich habe 2 MCUs und möchte sie über einen I2C-Bus miteinander verbinden. MCU1 ist der Controller, während MCU2 das Ziel ist. Nur diese 2 MCUs sind auf dem Bus. Diese Konfiguration ist fest und ich kann sie nicht ändern.

Es gibt 2 Szenarien. Im ersten Szenario befinden sich nur MCU1 und MCU2 am Bus, während in einem zweiten Szenario einige zusätzliche I2C-Geräte ebenfalls an diesen gemeinsamen Bus angeschlossen sind.

Mein Hauptzweck, sie wie oben zu verbinden, besteht darin, Daten von MCU2 (Ziel) an MCU1 (Controller) zu senden.

Was ich bisher über I2C verstehe, ist, dass es sich um ein Befehlsantwortprotokoll handelt. Der Controller gibt den Zielen Befehle, und dann antworten die Ziele auf diesen Befehl und senden ihre Daten an den Controller. Die Ziele können ihre Daten nicht selbst senden, ohne vorher den Befehl erhalten zu haben.

Wenn der Controller 32 Datenbytes vom Ziel empfangen möchte, welchen Befehl sendet er dann an das Ziel und wie bestätigt das Ziel dann, dass es den gültigen Befehl zum Senden von Daten erhalten hat? Ich denke, dies wird als "Blockmodus" -Datenübertragung bezeichnet.

Meine Zieladresse ist auf 0x08 festgelegt.

Wenn Sie von MCU2 zu MCU1 kommunizieren möchten, muss sich MCU2 im Master-Modus und MCU1 im Slave-Modus befinden. In Ihrem Fall müssen Sie MCU1 und MCU2 in den Slave-Modus versetzen. Wenn die MCU1 oder MCU2 auf dem Bus kommunizieren müssen, muss ihr Status auf MASTER geändert werden und dann wird sie auf dem Bus fragen.
Es ist ein wenig verwirrend oben über den Moduswechsel für MCU2. Warum muss ich die Modi ändern? Kann ich die Datenübertragung mit festen Modi für MCU1 und MCU2 durchführen?

Antworten (1)

Glücklicherweise oder leider liegt es an Ihnen, ein Protokoll für dieses Szenario zu entwickeln, da Sie beide Seiten kontrollieren. Wie Sie sagen, kann der Slave nur auf vom Master initiierte Übertragungen reagieren. Ihr Master muss dann den Slave abfragen (in einem wiederkehrenden Zeitplan nach Daten fragen), es sei denn, Sie haben eine andere Möglichkeit für den Slave, zu kommunizieren, wenn die Daten bereit sind. (Letzteres wird üblicherweise mit einer separaten Interrupt-Leitung gelöst.) Master und Slave müssen sich beide auf eine spezielle Antwort einigen, wenn der Slave noch keine Daten verfügbar hat. Auch der Slave muss seine Antwort auf diesen „keine Daten“-Wert zurücksetzen, nachdem er vom Master abgefragt wurde, um zu vermeiden, dass dieselben Daten zweimal gesendet werden.

Der einfachere Weg wäre, die Rollen von Master und Slave zu tauschen, sodass der Master das Senden von Daten an den Slave initiiert.

Wenn Sie auch mit anderen Slaves auf demselben I2C-Bus kommunizieren müssen, sind Sie jedoch eingeschränkt, welches Gerät der Master sein kann, es sei denn, Sie verwenden den Multi-Master-Modus von I2C.

Welche bestimmten I2C-API-Aufrufe erforderlich sind, hängt davon ab, welches Gerät und welche HAL Sie verwenden. Auf physikalischer Ebene handelt es sich um ein vom Master initiiertes „I2C-Lesen“, bei dem der Master nach dem Senden der Slave-Adresse 32 Bytes liest.

Die von mir verwendete Bibliotheksfunktion bietet die Möglichkeit, die I2C-Adresse als 7-Bit oder 10-Bit auszuwählen. Wie soll ich darüber entscheiden?
Es spielt keine Rolle, solange Sie auf beiden Seiten die gleiche Einstellung verwenden. Da Sie 10-Bit nicht benötigen, schlage ich 7-Bit vor.
Dies bedeutet, dass eine 7-Bit-Adresse 7 Bits für die Adresse und zusätzliche 3 Bits für S-, R/W- und ACK-Bits bedeutet. In ähnlicher Weise bedeutet 10-Bit-Adresse 10 Bits für die Adresse und zusätzliche 3 Bits wie oben UND nicht als 7 + 3 Bits = 10 Bits?
Wenn ich bei der Datenübertragung im „Blockmodus“ die Größe des Blocks auf 1 Byte oder 2 Byte einstelle, ist es dann dasselbe wie im „Einzelbytemodus“ oder „Einzelwortmodus“?
Ja. Ich glaube nicht, dass "Einzelwortmodus" ein verwendeter Begriff ist. I2C arbeitet auf Byte-Ebene. Ihr Master könnte den Slave mit einem einzigen Byte abfragen, um zu prüfen, ob Daten verfügbar sind, aber es wird komplexer sein, zwei unterschiedliche Übertragungslängen zum Laufen zu bringen. I2C kann komplex genug sein, um so wie es ist zu debuggen.
Wenn auf meinem I2C-Master (MCU1) Linux installiert ist und ich die Dienstprogramme „i2cset() linux.die.net/man/8/i2cset “ und „i2cget() linux.die.net/man/8/i2cget “ zur Kommunikation verwende und Daten vom i2C-Slave (MCU2) abrufen, was bedeutet dann der Parameter „data-address“ in den oben genannten Dienstprogrammen? Ich kann verstehen, dass „Chip-Adresse“ meine Slave-Adresse = 0x08 ist, aber was wird der nächste Parameter in meinem Fall sein, wenn der Slave eine MCU und kein Sensorchip ist? Im Allgemeinen ist im Fall der Sensorchips dieser obige Parameter die Adresse des Zielregisters, aus dem die Daten gelesen werden.
Es ist üblich, ein Konzept von "Registern" auf dem Basis-I2C zu verwenden, bei dem ein Byte als Adresse unter einer Reihe von benutzerdefinierten Werte-Slots (mangels eines besseren Wortes) innerhalb des adressierten Slaves verwendet wird. Nicht alle Chips verwenden Register und Sie haben tatsächlich keine Verwendung davon, da Sie nur einen 32-Byte-Parameter melden. Um Register zu verwenden, müssten Sie es im Slave implementieren. Linux i2cset arbeitet nur mit Registern. i2cget verwendet möglicherweise keine Register, wenn keins angegeben wird - ich weiß es nicht.