Welche Nachteile sollte ich bei der Entscheidung für eine SPI- oder I2C-Schnittstelle berücksichtigen?
Dieses Beschleunigungsmesser- / Gyro-Breakout-Board ist in zwei Modellen erhältlich, eines für jede Schnittstelle. Wäre eine davon einfacher in ein Arduino-Projekt zu integrieren?
Antworten:
Zusammenfassung
I2C ist ein Bussystem mit bidirektionalen Daten auf der SDA-Leitung. SPI ist eine Punkt-zu-Punkt-Verbindung mit Datenein- und -ausgängen auf separaten Leitungen (MOSI und MISO).
Im Wesentlichen besteht SPI aus zwei Schieberegistern, in denen Sie Daten in ein Schieberegister takten, während Sie Daten aus dem anderen takten. Normalerweise werden Daten in Bytes geschrieben, indem jeweils 8 Taktimpulse hintereinander liegen. Dies ist jedoch keine SPI-Anforderung. Sie können auch Wortlängen von 16 Bit oder sogar 13 Bit haben, wenn Sie möchten. Während in I2C die Synchronisation durch die Startsequenz in SPI erfolgt, wird SS auf High gesetzt (SS ist aktiv auf Low). Sie entscheiden selbst, nach wie vielen Takten dies ist. Wenn Sie 13-Bit-Wörter verwenden, speichert die SS die zuletzt getakteten Bits nach 13 Taktimpulsen.
Da sich die bidirektionalen Daten auf zwei separaten Leitungen befinden, ist die Schnittstelle einfach.
Wie Tcrosley sagt, kann SPI mit einer viel höheren Frequenz arbeiten als I2C.
I2C ist etwas komplexer. Da es sich um einen Bus handelt, müssen Geräte adressiert werden. Ihre Kommunikation beginnt mit einer eindeutigen Startsequenz: Die Datenleitung (SDA) wird nach unten gezogen, während die Uhr (SCL) hoch ist. Der Rest der Kommunikationsdaten darf sich nur ändern, wenn die Uhr niedrig ist. Diese Startsequenz synchronisiert jede Kommunikation.
Da die Kommunikation die Adressierung beinhaltet, werden für eine beliebige Anzahl von Geräten (bis zu 127) nur zwei Leitungen benötigt.
Nachdem jedes Byte (Adresse oder Daten) gesendet wurde, muss der Empfänger den Empfang bestätigen, indem er einen Bestätigungsimpuls auf SDA legt. Wenn Ihr Mikrocontroller über eine I2C-Schnittstelle verfügt, wird dies automatisch erledigt. Sie können es immer noch mit einem Bit-Bang spielen, wenn Ihr Mikrocontroller es nicht unterstützt, aber Sie müssen den E / A-Pin für jedes Quittieren oder Lesen von Daten vom Ausgang zum Eingang umschalten, es sei denn, Sie verwenden einen E / A-Pin zum Lesen und Lesen eine zum Schreiben.
Bei 400 kHz ist Standard-I2C viel langsamer als SPI. Es gibt Hochgeschwindigkeits-I2C-Geräte, die mit 1 MHz arbeiten und immer noch viel langsamer als 20 MHz SPI sind.
quelle
(redigieren Sie: Um klar zu sein, haben viele der folgenden Interessen mit der Signalintegrität zu tun, die durch die Board-to-Board-Verwendung von I2C / SPI-Geräten verursacht wird, wie Olin richtig hervorhebt.)
Wenn Sie keine Einschränkungen haben, die Sie stark in Richtung weniger Drähte drücken (wir hatten ein Projekt mit einem hermetisch abgedichteten Steckverbinder, bei dem jeder zusätzliche Kontakt ziemlich teuer war), vermeiden Sie I2C, wenn möglich, und bleiben Sie bei SPI.
SPI ist auf Hardware- und Softwarebasis recht einfach zu handhaben. In der Hardware gibt es zwei gemeinsam genutzte Datenleitungen, Master In Slave Out (MISO oder SOMI) und Master Out Slave In (MOSI oder SIMO), einen vom Master generierten gemeinsam genutzten Takt und eine Chipauswahl pro Gerät. Die CS-Leitung geht auf LOW, der Takt zykliert und verschiebt im wesentlichen die Eingangsbits und verschiebt die Ausgangsbits, bis die Transaktion beendet ist. An diesem Punkt geht die CS-Leitung auf HIGH. Wenn ihre CS-Leitung hoch ist, kommunizieren Slave-Geräte nicht: Sie ignorieren die CLK- und MOSI-Leitungen und versetzen ihren MISO-Pin in einen hochohmigen Zustand, damit andere ihn verwenden können.
Wenn Sie einen Mikrocontroller mit mehreren SPI-Geräten und einem integrierten SPI-Peripheriegerät haben, senden Sie den CS-Ausgang des Mikrocontrollers an einen Demultiplexer (z. B. 74HC138) und steuern Sie die Adressleitungen, um das Gerät zwischen SPI-Transaktionen auszuwählen. Sie schreiben Wörter in ein Register, um sie für die Ausgabe in die Warteschlange zu stellen, und lesen sie zurück, nachdem der CS-Pin auf Hoch angehoben wurde.
Da alle SPI-Signale unidirektional sind, können sie gepuffert, über eine Isolationsbarriere mit digitalen Isolatoren verwendet und mit Leitungstreibern wie LVDS von Karte zu Karte gesendet werden. Das einzige, worüber Sie sich Sorgen machen müssen, ist die Umlaufverzögerung, die Ihre maximale Frequenz begrenzt.
I2C ist eine ganz andere Geschichte. Vom Standpunkt der Verdrahtung ist es zwar viel einfacher, mit nur zwei Drähten SCL und SDA, aber beide Leitungen sind gemeinsam genutzte bidirektionale Leitungen, die Open-Drain-Geräte mit einem externen Pullup verwenden. Es gibt ein Protokoll für I2C, das mit der Übertragung einer Geräteadresse beginnt, sodass mehrere Geräte verwendet werden können, wenn jedes seine eigene Adresse hat.
Vom Standpunkt der Hardware aus ist es sehr schwierig, I2C in Systemen zu verwenden, die signifikante Störungen aufweisen. Um I2C-Leitungen zu puffern oder zu isolieren, müssen Sie auf exotische ICs zurückgreifen - ja, es gibt sie, aber es gibt nicht viele: Wir haben eins in einem Projekt verwendet und festgestellt, dass Sie einen Isolator verwenden können, aber nicht Verwenden Sie zwei in Reihe - es wurden kleine Spannungsabfälle verwendet, um herauszufinden, welche Seite das treibende Ende der Dinge war, und zwei in Reihe auftretende Abfälle waren zwei große.
Die Schwellenwerte für den Logikpegel von I2C hängen von Vcc ab. Sie müssen also sehr vorsichtig sein, wenn Sie 3-V- / 3,3-V- und 5-V-Geräte im selben System verwenden.
Alle Signale, die ein Kabel mit einer Länge von mehr als einem oder zwei Fuß verwenden, müssen sich um die Kabelkapazität kümmern. Eine Kapazität von 100pf / Meter ist für Mehrleiterkabel nicht ungewöhnlich. Dies führt dazu, dass Sie den Bus verlangsamen oder niedrigere Pullup-Widerstände verwenden müssen, um in der Lage zu sein, mit der zusätzlichen Kapazität richtig umzugehen und die Anforderungen an die Anstiegszeit zu erfüllen.
Nehmen wir also an, Sie haben ein System, das Ihrer Meinung nach gut entwickelt ist, und Sie können die meisten Probleme mit der Signalintegrität lösen, und Rauschen ist selten (aber immer noch vorhanden). Worüber müssen Sie sich Sorgen machen?
Es gibt eine Reihe von Fehlerbedingungen, auf die Sie vorbereitet sein müssen:
Slave-Gerät erkennt ein bestimmtes Byte nicht. Sie müssen dies erkennen und die Kommunikationssequenz stoppen und neu starten. (Mit SPI können Sie normalerweise die gesendeten Daten zurücklesen, wenn Sie sicherstellen möchten, dass sie fehlerfrei empfangen wurden.)
Sie lesen ein Datenbyte von einem Slave-Gerät und das Gerät ist aufgrund von Rauschen auf der Taktleitung "hypnotisiert": Sie haben die erforderlichen 8 Takte zum Lesen dieses Bytes gesendet, aber das Slave-Gerät denkt es aufgrund von Rauschen hat 7 Takte empfangen und sendet immer noch eine 0 auf der Datenleitung. Wenn das Gerät den achten Takt empfangen hätte, hätte es die Datenleitung auf Hochpegel freigegeben, so dass der Master die Datenleitung anheben oder absenken könnte, um ein ACK- oder NACK-Bit zu senden, oder der Master könnte eine Stoppbedingung (P) senden. Aber der Slave hält die Datenleitung immer noch niedrig und wartet vergeblich auf eine weitere Uhr. Wenn ein Master nicht bereit ist, zusätzliche Uhren zu testen, steckt der I2C-Bus in einem Deadlock. Während ich mehrere Mikrocontroller verwendet habe, die die normalen ACK / NACK-Bedingungen handhaben,
Der wirklich schreckliche Fall ist, wenn ein Master Daten auf ein Slave-Gerät schreibt und ein anderer Slave die Geräteadresse falsch interpretiert und der Meinung ist, dass die übertragenen Daten für dieses Gerät bestimmt sind. Es gab I2C-Geräte (I / O-Expander), bei denen die Register gelegentlich falsch eingestellt waren. Es ist fast unmöglich, diesen Fall zu erkennen, und um robust gegen Rauschen zu sein, müssen Sie regelmäßig alle Register einstellen, damit dieser Fehler nach kurzer Zeit behoben wird, wenn Sie auf diesen Fehler stoßen. (SPI hat dieses Problem nie - wenn Sie zufällig einen Fehler in der CS-Leitung haben, wird dieser niemals lange anhalten und Sie erhalten keine Daten, die versehentlich vom falschen Slave-Gerät gelesen wurden.)
Viele dieser Bedingungen könnten im Protokoll ordnungsgemäß behandelt werden, wenn Fehlererkennung (CRC-Codes) vorhanden wäre, aber nur wenige Geräte verfügen über diese.
Ich stelle fest, dass ich in meinem I2C-Master-Gerät komplexe Software erstellen muss, um diesen Bedingungen gerecht zu werden. Meiner Meinung nach lohnt es sich nur, wenn die Einschränkungen bei der Verkabelung uns zwingen, I2C und nicht SPI zu verwenden.
quelle
Das Breakout Board für das Gerät bei SparkFun ist eigentlich nur für die I2C-Version (MPU-6500). Die MPU-6000-Version hat sowohl SPI- als auch I2C-Schnittstellen auf demselben Chip, und ich sehe nicht, dass SparkFun eine Platine mit diesem Chip hat. Ich glaube, Sie können nur I2C verwenden, wenn Sie diese bestimmte Karte verwenden möchten. Aber ich würde I2C aus den folgenden Gründen trotzdem in Ihrer Situation empfehlen.
Im Allgemeinen werden Sie feststellen, dass der I2C-Bus vom Standpunkt der Hardware aus einfacher zu bedienen ist als der SPI-Bus. I2C ist ein 2-Draht-Bus (SCL / SDA):
SPI ist ein 4-Draht-Bus (SCLK / MOSI / MISO / CS):
Sie können mehrere Geräte an einen I2C-Bus anschließen. Jedes Gerät verfügt über eigene Adressen, die in den Chip integriert sind. Die Adresse wird tatsächlich als erstes Byte jedes Befehls (zusammen mit einem Lese- / Schreibbit) über den Bus gesendet. Dies erfordert zusammen mit einigem anderen Overhead, dass mehr Bits über einen I2C-Bus versus SPI für dieselbe Funktionalität gesendet werden.
Unterschiedliche Geräteklassen (Speicher, E / A, LCD usw.) haben unterschiedliche Adressbereiche. Einige Geräte, die in einem System häufig mehrmals verwendet werden (z. B. der PCF8574-E / A-Expander), verwenden eine oder mehrere Adressleitungen (AD0-2 für den PCF8574), die hoch oder niedrig gebunden werden können, um die niedrigen Bits anzugeben der Adresse. Die MPU-6500 verfügt über eine solche Adressleitung (AD0), sodass zwei davon im selben System verwendet werden können.
Sie können auch mehrere Geräte an einen SPI-Bus anschließen, aber jedes Gerät muss über eine eigene Chip-Select-Leitung (CS) verfügen. Daher ist die 4-Draht-Beschreibung ein bisschen eine Fehlbezeichnung - es ist wirklich eine 3-Draht-Schnittstelle + ein zusätzlicher Draht pro Gerät. Ich habe keine Erfahrung mit der Arduino-Serie von Boards, aber ich glaube, dies würde die Verwendung von SPI auf dem Arduino erschweren, da dies bei der Verwendung vieler Chip-Select-Leitungen mit den von den verschiedenen Shields verwendeten gemeinsamen Pin-Zuordnungen unangenehm werden würde .
Ich glaube, die meisten Arduino-Boards arbeiten mit 5 Volt, einige neuere mit 3,3 Volt. Die MPU-6500 wird mit 3,3 V betrieben. Wenn die minimale Eingangs-Hochspannung für den I2C-Bus auf einer 5-V-CPU 3 V oder weniger beträgt, können Sie Pegelumwandlungsprobleme vermeiden, indem Sie lediglich 10-K-Pullup-Widerstände auf 3,3 V auf den SCL- und SDA-Leitungen bereitstellen, da der Bus offen ist. Kollektor. Stellen Sie sicher, dass alle internen 5-V-Pullups auf einer CPU deaktiviert sind.
Ich habe jedoch das Datenblatt für den ATmega2560 überprüft (am Beispiel des ADK 5v Arduino), und seine minimale Eingangsspannung beträgt 0,7 * Vcc oder 3,5 V, was mehr als 3,3 V ist. Sie benötigen also eine Art aktiven Pegel Der TI PCA9306 , für den Pull-Up-Widerstände auf der 5-V- und der 3,3-V-Seite des Chips erforderlich sind, kostet in Einzelmengen nur 78 Cent.
Warum sollte man dann SPI über I2C wählen? Hauptsächlich, weil SPI viel schneller ausgeführt werden kann - in einigen Fällen bis zu 10 MHz. I2C ist im Allgemeinen auf 400 kHz begrenzt. Dies ist jedoch für den Beschleunigungssensor MPU-6050/6000 kein wirkliches Problem, da er für I2C mit 400 kHz und für SPI nur mit 1 MHz arbeitet - kein so großer Unterschied.
quelle
Im Allgemeinen ist SPI ein schnellerer Bus - die Taktfrequenz kann in einem Bereich von MHz liegen. SPI erfordert jedoch mindestens 3 Leitungen für die bidirektionale Kommunikation und eine zusätzliche Slave-Auswahl für jedes Gerät am Bus.
I2C benötigt nur 2 Leitungen, unabhängig davon, wie viele Geräte Sie haben (natürlich in Grenzen). Die Geschwindigkeit liegt jedoch im Bereich von kHz (100-400 kHz ist typisch).
Die meisten Mikrocontroller verfügen heutzutage über Hardware-Unterstützung für beide Busse, sodass beide gleich einfach zu bedienen sind.
quelle
I2C is designed for on-board applications.
- Offensichtlich sind sich die Hersteller von I2C-Geräten nicht einig . Nimm den TMP100 . Auf der Produktseite heißt es ausdrücklich:The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
Gleiches gilt für den TMP75SPI kann viel schneller als I2C ausgeführt werden (einige SPI-Geräte gehen über 60 MHz; ich weiß nicht, ob die "offizielle" I2C-Spezifikation Geräte über 1 MHz zulässt). Die Implementierung eines Slave-Geräts unter Verwendung eines der beiden Protokolle erfordert Hardware-Unterstützung, während beide die einfache Implementierung von "Software-Bit-Bang" -Mastern ermöglichen. Mit relativ minimaler Hardware kann ein I2C-kompatibler Slave erstellt werden, der auch dann ordnungsgemäß funktioniert, wenn der Host willkürlich entscheidet, den Bus für bis zu 500us gleichzeitig zu ignorieren, ohne dass zusätzliche Handshake-Drähte erforderlich sind. Zuverlässige SPI Betrieb jedoch auch mit Hardware - Unterstützung , erfordert in der Regel , dass man entweder einen Handshake Draht hinzufügen, oder aber , dass der Host „ von Hand“ eine Verzögerung nach jedem Byte gleich den Worst-Case - Reaktionszeit des Slave hinzufügen.
Wenn ich meine Druthers hätte, würde die SPI-Unterstützung der Controller einige einfache zusätzliche Funktionen enthalten, um bidirektionale 8-Bit-transparente Datenübertragungen zwischen Controllern mit Handshake- und Wake-up-Fähigkeiten unter Verwendung von insgesamt drei unidirektionalen Kabeln (Clock und MOSI [Master -out-slave-in] vom Master; MISO [master-in-slave-out] vom Slave). Im Vergleich dazu erfordert eine effiziente und zuverlässige Kommunikation zwischen Mikrocontrollern mit "serienmäßigen" SPI-Ports, wenn beide Prozessoren unabhängig voneinander für eine beliebige Zeitspanne verzögert werden, die Verwendung von viel mehr Drähten (Chip-Select, Clock, MISO und MOSI), um zu starten Wenn der Slave möglicherweise asynchron beginnt, Daten zu senden (z. B. weil jemand eine Taste gedrückt hat), muss entweder noch eine andere Leitung als "Wakeup" verwendet werden.
I2C bietet nicht alle Fähigkeiten, die mein "verbessertes" SPI haben würde, aber es bietet eingebaute Handshake-Fähigkeiten, die SPI nicht bietet, und in vielen Implementierungen kann es auch als Wake-up-Funktion angesehen werden, selbst wenn der Master a ist Software-Bit-Bang. Für die Kommunikation zwischen Prozessoren empfehle ich daher dringend I2C über SPI, außer wenn höhere Geschwindigkeiten erforderlich sind, als SPI liefern kann, und die Verwendung zusätzlicher Pins akzeptabel ist. Für Interprozessor-Kommunikationen, bei denen eine geringe Pin-Anzahl erforderlich ist, können UARTs diese sehr empfehlen.
quelle
Diese Frage wurde in den hervorragenden Antworten hier gründlich untersucht, aber vielleicht gibt es noch einen weiteren Gesichtspunkt für I 2 C, den ich aus der Sicht eines Chipherstellers anbieten könnte.
Die elektrische Schnittstelle des I 2 C ist ein offener Kollektor . Jetzt atme und denke über die Auswirkungen nach. Mit I 2 C kann ich einen Chip entwerfen, der völlig unabhängig von der Betriebsspannung des Busses ist. Alles, was ich tun muss, ist, die SDA-Leitung nach unten zu ziehen, wenn es mir gefällt, und die Spannungen von SCL und SDA mit einer auf Masse bezogenen Schwellenspannung zu vergleichen, die ich wählen kann. Und wenn ich die normalen High-Side-Schutzstrukturen weglasse und durch andere Strukturen ersetze, kann ich einen Chip herstellen, der völlig unabhängig vom Rest des Systems sein eigenes Leben führen kann - SCL, SDA speisen niemals Strom in meinen Chip und ich Mit Sicherheit wird diesen Pins kein Strom zugeführt. Das ist der Grund, warum es so ein schöner Bus für Echtzeituhren und andere Sachen mit geringem Stromverbrauch ist.
quelle
Eine Sache, die ich in den anderen Antworten nicht gesehen habe, ist, dass I2C mehrere Master am selben Bus unterstützt. Wenn Sie bidirektionale Kommunikation benötigen und keine abrufbasierte Methode verwenden möchten, erledigt I2C die Aufgabe.
Über größere Entfernungen verfügt CAN über die gleichen Fähigkeiten und ist robuster. Bei CAN handelt es sich jedoch um ein asynchrones Protokoll, für das Hardware-Unterstützung und ein Transceiver erforderlich sind. In einem kostengünstigen System ist dies möglicherweise keine Option.
quelle
Verwenden Sie das SPI-Protokoll und schreiben Sie Ihre Bits immer dann direkt in das Gerät, wenn die Synchronisationszeit ansteigt. Die xnor-Logikschaltung kann verwendet werden, um die "hausgemachte" Adresse aus einem Speicher abzugleichen, um das gewünschte Gerät auszuwählen, als ob es ein i2c-Gerät wäre.
Der i2c integriert den Autorenkreislauf in das Format des Geräts, Standard ... usw. sind komplex und unterschiedlich. Mit einem SPI können Sie einen SPI-Speicher verwenden, um ein Video auf dem Bildschirm anzuzeigen, nicht jedoch i2c.
quelle