Kompromisse bei der Betrachtung von SPI oder I2C?

Welche Kompromisse sollte ich berücksichtigen, wenn ich mich für die Verwendung einer SPI- oder I2C-Schnittstelle entscheide?

Dieses Accelerometer/Gyro Breakout Board ist in zwei Modellen erhältlich, eines für jede Schnittstelle. Wäre eines der beiden einfacher in ein Arduino-Projekt zu integrieren?

http://www.sparkfun.com/products/11028

Geben Sie hier die Bildbeschreibung ein

I2C und SPI haben ihre Stärken. I2C ist komplexer einzurichten, sobald es stabil ist, können Sie es so einfach erweitern (solange Ihre Busverkabelung nicht zu lang oder zu groß wird). SPI ist einfach einzurichten. Sie können es bei Bedarf sehr einfach bitbangen. Die Erweiterung frisst I/O mit allen Chip-Selects. Wenn ich den Luxus von E/A und Anschlussraum habe und keine Busse benötige, würde ich immer mit SPI gehen.
Wie ist I2C komplexer? Ich habe beide Busse auf verschiedenen Mikros (kleine PICs und anständig große ARMs) verwendet und in jedem Fall war das I2C-Setup einfacher (dh weniger Register zum Schreiben). Wenn überhaupt, ist SPI aufgrund der Taktpolarität und der Datenabtastoptionen komplexer.
@Armandas - auf keinen Fall! SPI hat 4 mögliche Modi für Takt-/Datenpolarität, und zwei davon dominieren – fast alle SPI-Geräte aktualisieren ihren MISO-Ausgang an der fallenden Flanke eines Takts und lesen ihren MOSI-Eingang an der steigenden Flanke eines Takts. Welche das sind, erfährst du in wenigen Minuten, indem du dir das Datenblatt ansiehst, und dann bist du fertig. Wenn Sie versehentlich den falschen Modus auswählen, werden Sie es schnell herausfinden, wenn Sie sich die Oszilloskop-Kurven ansehen. SPI-Datenfehler sind selten und lassen Sie nicht in seltsamen Zuständen stecken, wie es I2C tut.
Ich sage, I2c ist viel komplexer, weil ich einmal einen I2C-Treiber für einen ARM-Prozessor schreiben musste. Ich folgte der Zustandsmaschine von NXP-Dokumenten, und sie war ungefähr 20 Zustände lang. Ich habe eine anständige Zeit gebraucht, um die Bestätigung herauszufinden, wann das letzte Byte gelesen/geschrieben wird usw. Ich hatte noch nie eines dieser Probleme mit SPI, ich muss nur die Uhr und die Daten in eine Reihe bringen.
Bitte lesen Sie die Antworten hier, bevor Sie eine Antwort auswählen: electronic.stackexchange.com/questions/13987/… Beide haben ihre Anwendungen.
@JonL, ehrlich gesagt bin ich der einzige, der bisher eine vollständige Antwort gegeben hat, da ich der einzige bin, der das Problem des bestimmten Breakout-Boards diskutiert, das das OP verwenden möchte, und darauf hinweise, dass es nicht verfügbar ist sowohl SPI als auch I2C, aber nur I2C - also muss er I2C verwenden, wenn er dieses spezielle Board verwenden möchte. Die anderen befassten sich nur damit, welche Schnittstelle (SPI oder I2C) einfacher zu verbinden ist, was ich auch behandelt habe.
@Hans: Die von NXP dokumentierte I2C-Implementierung enthält Bestimmungen für Dinge wie Multi-Master-Arbitrierung, die in einer typischen Anwendung nicht benötigt werden, und ist auch auf einen zustandsbasierten Ansatz ausgelegt. Code für einen prozedurgesteuerten I2C-Master ist viel einfacher, als eine solche Dokumentation vermuten lässt.

Antworten (9)

Zusammenfassung

  • SPI ist schneller.
  • I2C ist komplexer und nicht so einfach zu verwenden, wenn Ihr Mikrocontroller keinen I2C-Controller hat.
  • I2C benötigt nur 2 Leitungen.

I2C ist ein Bussystem mit bidirektionalen Daten auf der SDA-Leitung. SPI ist eine Punkt-zu-Punkt-Verbindung mit Dateneingang und Datenausgang auf getrennten Leitungen (MOSI und MISO).

Im Wesentlichen besteht SPI aus zwei Schieberegistern, in denen Sie Daten in ein Schieberegister eintakten, während Sie Daten aus dem anderen austakten. Normalerweise werden Daten in Bytes geschrieben, indem jedes Mal 8 Taktimpulse hintereinander vorliegen, aber das ist 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, erfolgt dies durch SS, das hoch geht (SS ist aktiv niedrig). Nach wie vielen Takten das ist, entscheiden Sie selbst. Wenn Sie 13-Bit-Wörter verwenden, speichert der SS die letzten getakteten Bits nach 13 Taktimpulsen.
Da sich die bidirektionalen Daten auf zwei getrennten Leitungen befinden, ist die Schnittstelle einfach.

SPI im Standardmodus benötigt mindestens vier Leitungen: SCLK (Serial Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) und SS (Slave Select). Im bideroktionalen Modus werden mindestens drei Leitungen benötigt: SCLK (serielle Uhr), MIMO (Master In Master Out), das eine der MOSI- oder MISO-Leitungen ist, und SS (Slave Select). Bei Systemen mit mehr als einem Slave benötigt man für jeden Slave eine SS-Leitung, damit z N Sklaven, die du hast N + 3 Linien im Standardmodus und N + 2 Leitungen im bidirektionalen Modus. Wenn Sie das nicht möchten, können Sie die Slaves im Standardmodus verketten, indem Sie das MOSI-Signal eines Slaves mit dem MISO des nächsten verbinden. Dies verlangsamt die Kommunikation, da Sie alle Slave-Daten durchlaufen müssen.

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, benötigen Sie eine Möglichkeit, Geräte zu adressieren. Ihre Kommunikation beginnt mit einer einzigartigen Startsequenz: Die Datenleitung (SDA) wird niedrig gezogen, während der Takt (SCL) hoch ist, denn der Rest der Kommunikationsdaten darf sich nur ändern, wenn der Takt niedrig ist. Diese Startsequenz synchronisiert jede Kommunikation.
Da die Kommunikation die Adressierung beinhaltet, werden für beliebig viele Geräte (bis zu 127) nur zwei Leitungen benötigt.

Bearbeiten
Es ist offensichtlich, dass die Datenleitung bidirektional ist, aber es ist erwähnenswert, dass dies auch für die Taktleitung gilt. Slaves können den Takt dehnen , um die Busgeschwindigkeit zu steuern. Dies macht I2C weniger geeignet für Pegelverschiebung oder Pufferung. (SPI-Leitungen im Standardmodus sind alle unidirektional.)

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 bitbangen, wenn Ihr Mikrocontroller dies nicht unterstützt, aber Sie müssen den E / A-Pin für jede Bestätigung oder jedes Lesen von Daten von Ausgang auf Eingang umschalten, es sei denn, Sie verwenden einen E / A-Pin zum Lesen und eine zum Schreiben.

Bei 400 kHz ist Standard-I2C viel langsamer als SPI. Es gibt Hochgeschwindigkeits-I2C-Geräte, die mit 1 MHz arbeiten, immer noch viel langsamer als 20 MHz SPI.

Ich habe noch keinen Mikrocontroller getroffen, der alle Eckfälle von I2C bewältigt, um die richtige Fehlererkennung und -behebung auf eine Weise zu handhaben, die verwendbar ist, ohne dass man ein I2C-Experte sein muss. Ich musste immer wieder von einem "intelligenten" I2C-Peripheriegerät auf Bitbanging zurückfallen, um den Fall der fehlenden Uhr zu bewältigen, wenn SDA niedrig gehalten wird, was ein völliger Schmerz ist.
(aber +1, da ich dem Rest Ihrer Antwort zustimme)
Es gibt sogar I2C-Geräte, die mit 3,4 MHz arbeiten, aber ich bin unsicher, ob diese mit langsameren Geräten kombiniert werden können (da alle Geräte in der Lage sein müssen, der Busadressierung zu folgen). Ich glaube auch, dass die Timings von 3,4 MHz I2C etwas anders sind.
@Hans - HS I2C scheint abwärtskompatibel mit den gängigeren 400-kbit-Geräten zu sein. Ehrlich gesagt habe ich (ohne gründliche Recherche) noch nie einen Mikrocontroller gesehen, der HS unterstützt, deshalb wollte ich es nicht erwähnen.
@stevenvh: Die Zwei-Draht-Implementierungen einiger Controller (z. B. Cypress PSOC) erfordern, dass SCK für mindestens ein oder zwei Zyklen einer internen Uhr niedrig ist, bevor sie es verriegeln, und es wird schlecht funktionieren, was es nicht ist. Ich weiß nicht, warum sie eine I2C-Startbedingung ohne einen Systemtaktimpuls nicht erkennen und takten können, aber solche Verhaltensweisen bedeuten, dass, wenn ein solcher Chip mit einer niedrigen Systemtaktgeschwindigkeit läuft, alle I2C-Transaktionen auf dem Bus müssen langsam laufen). Sogar ein 400-kHz-Betrieb ist zu schnell für einen PSOC, der mit 3 MHz läuft.
Es sollte beachtet werden, dass viele SPI-Geräte eine angemessene Verwendung von SS erfordern, selbst wenn sie das einzige Gerät auf dem Bus sind. SS aktiviert nicht nur einen einzelnen Slave, sondern sorgt auch für Synchronisation. Die Vorderflanke von SS wird häufig verwendet, um den Beginn einer neuen Nachricht mit zugehöriger Neusynchronisierung durch die Slave-Gerätelogik anzuzeigen.
@stevenvh: Aber hemmt die SS nicht nur die Uhr? Nein, und das ist der Punkt. Viele Geräte verwenden die Vorderkante von SS, um eine neue Nachricht anzuzeigen. Beispielsweise könnte ein EEPROM die ersten beiden Bytes nach SS als Adresse und die nachfolgenden Bytes als Daten verwenden. Bei A/Ds ist es sehr üblich, dass bedeutungsvolle Bits an einer festen Position relativ zu SS übertragen werden und danach weiterhin Nullen oder undefinierte Bits gesendet werden. Dies ermöglicht eine einfachere Kompatibilität mit Hardware, die nur feste Vielfache von Bits verarbeiten kann, wie 8 oder 16. Bei einigen Geräten ist das erste Byte ein Opcode, der Rest hängt von diesem Opcode ab.
@stevenvh: Die überwiegende Mehrheit der SPI-Geräte verwendet SS zur Synchronisierung und erfordert, dass es durch eine Transaktion gültig bleibt. Einige Geräte haben eine separate Uhraktivierungsleitung, die dazu führt, dass sie Taktimpulse während einer Transaktion ignorieren. Dies kann nützlich sein, wenn eine Interrupt-Service-Routine möglicherweise auf ein Gerät auf einem SPI-Bus zugreifen muss, während der "Hauptleitungscode" auf einige andere Geräte (z. B. einen Flash-Speicherchip) zugreift.
@Olin, Supercat - letzte Nacht im Bett wurde mir klar, dass mein Kommentar zur SPI-Synchronisation völlig falsch ist. Falsch. Ich weiß nicht, was ich geraucht hatte. Ich werde es löschen und meine Antwort bearbeiten.
@stevenvh: Bidirektionales SPI erfordert vier Zeilen; Viele SPI-Geräte verwenden nur eine unidirektionale Übertragung und benötigen drei. Obwohl Schieberegister üblicherweise auf einem SPI-Bus verwendet werden und Daisy-Chaining ermöglichen, und einige komplexere Peripheriegeräte dies ebenfalls tun, sind solche Geräte eher die Ausnahme als die Regel.
@stevenh Die LPC1300/1700/1800/4300-Serie behauptet, den 1-Mbit / s-Betrieb zu unterstützen. Was ich nicht gesehen habe, ist ein Peripheriegerät zum Anschließen!
@OlinLathrop: Ein ADC-Schnittstellendesign, das mir eher gefiel, gab 16 Bit in Big-Endian-Reihenfolge aus (die der Prozessor sogar während der Konvertierung austakten konnte, vorausgesetzt, dass er kein bestimmtes Bit austaktete, bis es verfügbar war ) gefolgt von denselben 16 Bits in Little-Endian-Reihenfolge. Dies bedeutete, dass selbst wenn eine Hardwareplattform nur über einen synchronen seriellen Little-Endian-Port verfügte, eine Konvertierung in ihrer nativen Bitreihenfolge gelesen werden konnte, indem einfach die ersten beiden Bytes übersprungen und die nächsten beiden gelesen wurden.

(Bearbeiten: Um es klar zu sagen, viele der folgenden Bedenken haben mit der Signalintegrität zu tun, die durch die Board-to-Board-Nutzung von I2C/SPI-Geräten verursacht wird, wie Olin richtig hervorhebt.)

Wenn Sie keine Einschränkungen haben, die Sie stark zu weniger Drähten drängen (wir hatten ein Projekt mit einem hermetisch abgedichteten Stecker, bei dem jeder zusätzliche Kontakt ziemlich teuer war), vermeiden Sie nach Möglichkeit I2C und bleiben Sie bei SPI.

SPI ist auf Hardware- und Softwarebasis ziemlich 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 gemeinsam genutzten Takt, der vom Master generiert wird, und eine Chipauswahl pro Gerät. Die CS-Leitung geht auf Low, der Takt läuft und verschiebt im Wesentlichen Eingabebits hinein und Ausgangsbits heraus, bis die Transaktion beendet ist, an welchem ​​Punkt die CS-Leitung auf High geht. 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 jemand anderes ihn verwenden kann.

Wenn Sie einen Mikrocontroller haben, der mehrere SPI-Geräte verwendet und über ein eingebautes SPI-Peripheriegerät verfügt, 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 hoch angehoben wurde.

Da SPI-Signale alle unidirektional sind, können sie gepuffert, mit digitalen Isolatoren über eine Isolationsbarriere hinweg verwendet und mit Leitungstreibern wie LVDS von Platine zu Platine gesendet werden. Das einzige, worüber Sie sich Sorgen machen müssen, ist die Round-Trip-Ausbreitungsverzögerung, die Ihre maximale Frequenz begrenzt.


I2C ist eine ganz andere Geschichte. Obwohl es vom Verkabelungsstandpunkt viel einfacher ist, mit nur zwei Drähten SCL und SDA, sind diese beiden Leitungen 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.

Aus Hardware-Sicht ist es sehr schwierig, I2C in Systemen zu verwenden, die erhebliches Rauschen 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 zu einem Projekt verwendet und festgestellt, dass Sie einen Isolator verwenden könnten, 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 Reihenabfälle waren zwei viel.

Die Logikpegelschwellen von I2C hängen von Vcc ab, daher müssen Sie wirklich vorsichtig sein, wenn Sie 3V/3,3V- und 5V-Geräte im selben System verwenden.

Alle Signale, die ein Kabel von mehr als einem oder zwei Fuß verwenden, müssen sich Gedanken über die Kabelkapazität machen. Eine Kapazität von 100 pf/Meter ist für mehradrige Kabel nicht ungewöhnlich. Dies führt dazu, dass Sie den Bus verlangsamen oder niedrigere Pullup-Widerstände verwenden müssen, um die zusätzliche Kapazität richtig handhaben zu können und die Anforderungen an die Anstiegszeit zu erfüllen.

Nehmen wir also an, Sie haben ein System, von dem Sie denken, dass Sie es gut entworfen haben, 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:

  • Das Slave-Gerät bestätigt ein bestimmtes Byte nicht. Sie müssen dies erkennen und die Kommunikationssequenz stoppen und neu starten. (Mit SPI können Sie normalerweise die von Ihnen 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 wird aufgrund von Rauschen auf der Taktleitung "hypnotisiert": Sie haben die erforderlichen 8 Takte gesendet, um dieses Byte zu lesen, aber aufgrund von Rauschen denkt das Slave-Gerät es hat 7 Takte empfangen und sendet immer noch eine 0 auf der Datenleitung. Wenn das Gerät den 8. Takt empfangen hätte, hätte es die Datenleitung hoch freigegeben, so dass der Master die Datenleitung anheben oder absenken könnte, um ein ACK- oder NACK-Bit zu übertragen, oder der Master könnte eine Stoppbedingung (P) übertragen. Aber der Slave hält die Datenleitung immer noch niedrig und wartet vergeblich auf einen weiteren Takt. Wenn ein Master nicht bereit ist, zusätzliche Takte auszuprobieren, bleibt der I2C-Bus in einem Deadlock stecken. Obwohl ich mehrere Mikrocontroller verwendet habe, die die normalen ACK/NACK-Bedingungen handhaben,

  • Der wirklich schreckliche Fall ist, wenn ein Master Daten an ein Slave-Gerät schreibt und ein anderer Slave die Geräteadresse falsch interpretiert und denkt, dass die übertragenen Daten für ihn bestimmt sind. Wir hatten I2C-Geräte (E/A-Expander), bei denen aus diesem Grund gelegentlich Register falsch eingestellt waren. Es ist fast unmöglich, diesen Fall zu erkennen, und um robust gegenüber Rauschen zu sein, müssen Sie regelmäßig alle Register einstellen, damit dieser Fehler zumindest nach kurzer Zeit behoben wird, wenn Sie auf diesen Fehler stoßen. (SPI hat dieses Problem nie – wenn Sie zufällig eine Störung auf der CS-Leitung haben, wird sie nie lange andauern und Sie werden keine Daten versehentlich vom falschen Slave-Gerät lesen.)

Viele dieser Bedingungen könnten im Protokoll richtig behandelt werden, wenn Fehlererkennung (CRC-Codes) vorhanden wäre, aber nur wenige Geräte haben dies.


Ich finde, dass ich komplexe Software in meinem I2C-Master-Gerät bauen muss, um diese Bedingungen zu bewältigen. Meiner Meinung nach lohnt es sich einfach nicht, es sei denn, die Einschränkungen bei der Verkabelung zwingen uns, I2C und nicht SPI zu verwenden.

Ihre religiöse Abneigung gegen IIC hat hier keinen Platz. Sowohl IIC als auch SPI sind gut in dem, was sie tun, und jeder hat seinen Platz. Die meisten Ihrer Einwände gegen IIC beruhen auf einer unangemessenen Verwendung. IIC sollte nur als On-Board betrachtet werden, obwohl es routinemäßig in der Stromversorgungsindustrie zur Steuerung intelligenter Stromversorgungen verwendet wird. Wenn Sie IIC-Puffer wünschen, ist dies ein starker Hinweis darauf, dass IIC nicht die richtige Lösung ist. IIC funktioniert jedoch sehr gut für Geräte mit niedriger Geschwindigkeit, die sich alle auf derselben Platine befinden.
Die Logikpegelschwellen von I2C hängen von Vcc ab, daher müssen Sie wirklich vorsichtig sein, wenn Sie 3V/3,3V- und 5V-Geräte im selben System verwenden . Nein, das ist falsch. IIC-Logikschwellenwerte liegen bei festen Spannungen. Sie können 5-V- und 3,3-V-Systeme trivial mischen, indem Sie die Leitungen auf nur 3,3 V hochziehen.
Olin – können Sie in einer Spezifikation auf die festen Spannungsschwellen hinweisen? Ich hatte den Eindruck, dass sie auch behoben wurden (SMBus-Schwellenwerte sind festgelegt), aber ich habe im NXP I2C-Benutzerhandbuch (UM10204) nachgesehen und sie geben die Schwellenwerte als 0,3 VDD und 0,7 VDD an.
Es ist keine religiöse Abneigung gegen I2C, es ist eine praktische Abneigung gegen I2C. Sie haben Recht damit, dass es mit Bordsystemen viel einfacher ist; Ich werde es verwenden, wenn es sinnvoll ist, aber es erhöht die Softwarekosten, und zu viele Hardwareingenieure stecken einfach ein I2C-Gerät auf eine Platine, ohne die Kompromisse zu diskutieren, die mehr Software-Kopfschmerzen verursachen.
Ich weiß nicht mehr genau, wo ich es gesehen habe, und wenn ich ein wenig herumgrabe, scheint es einige Verwirrung und verschiedene Optionen zu geben, aber ich bin mir ziemlich sicher, dass ich mich zum Beispiel an 1,5 V als die maximale logische niedrige Schwelle erinnere.
IIC ist elektrisch etwas einfacher zu implementieren und SPI vielleicht etwas einfacher in der Firmware. Beide sind jedoch ziemlich einfach und geradlinig in beiderlei Hinsicht.
I2C ist für den Einsatz in elektrisch sauberen Umgebungen ausgelegt und kann nicht einfach für den Einsatz in feindlicheren Umgebungen "befestigt" werden. Allerdings kann I2C für die Kommunikation zwischen Prozessoren in elektrisch sauberen Umgebungen viel bequemer sein als SPI. UARTs können noch schöner sein, aber Prozessoren scheinen nie genug zu haben, und die Art und Weise, wie die UARTs vieler Controller in ihre Taktsysteme integriert sind, macht es schwierig, die Taktgeschwindigkeit zu ändern, ohne Daten zu beschädigen, die das andere Ende möglicherweise asynchron gesendet hat.
@Olin - Die feste Schwelle von 1,5 V scheint in der Vergangenheit verwendet worden zu sein, aber gemäß der neuesten Version der Spezifikation liegen die Schwellen tatsächlich bei 0,3 Vcc und 0,7 Vcc. Dieses Zitat aus der Spezifikation erwähnt die 1,5 V für ältere Geräte.
@JasonS Es sind also 6 Jahre vergangen und es gab viele nützliche Diskussionen in den Kommentaren. Ist es möglich, dass wir in jedem Fall eine Liste von Fällen, I2C-Zuverlässigkeit und Fehlermodi haben können? Wenn Sie zB auf ein einzelnes Gerät schreiben, scheint es 100% in Ordnung zu sein. Beim Schreiben auf mehrere Geräte können einige die Daten falsch interpretieren. Wenn Sie von einem einzelnen Gerät lesen, müssen Sie möglicherweise einen Bit-Bang durchführen und zurücksetzen. Beim Lesen von mehreren Geräten ist möglicherweise ein vollständiger Aus- und Wiedereinschalten erforderlich, um einen Deadlock zu lösen?

Das Breakout-Board für Geräte 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 ein Board mit diesem Chip hat. Ich glaube also, dass Sie auf die Verwendung von I2C beschränkt sind, wenn Sie dieses bestimmte Board verwenden möchten. Aber ich wollte I2C trotzdem in Ihrer Situation aus den folgenden Gründen empfehlen.

Im Allgemeinen werden Sie feststellen, dass der I2C-Bus aus Hardware-Sicht einfacher zu verwenden ist als der SPI-Bus. I2C ist ein 2-Draht-Bus (SCL/SDA):

SCL – Serial clock.
SDA – Serial data (bidirectional).

SPI ist ein 4-Draht-Bus (SCLK/MOSI/MISO/CS):

SCLK– Serial clock.
MOSI – Master-out, Slave-in. Data from the CPU to the peripheral.
MISO – Master-in, Slave out. Data from the peripheral back to the CPU.
CS – Chip select.

Sie können mehrere Geräte an einen I2C-Bus anschließen. Jedes Gerät hat seinen eigenen Satz von Adressen, die in den Chip eingebaut sind. Die Adresse wird tatsächlich als erstes Byte jedes Befehls (zusammen mit einem Lese-/Schreibbit) über den Bus gesendet. Dies erfordert zusammen mit einigen anderen Overheads, dass mehr Bits über einen I2C-Bus als über SPI für die gleiche Funktionalität gesendet werden.

Unterschiedliche Geräteklassen (Speicher, E/A, LCD usw.) haben unterschiedliche Adressbereiche. Einige Geräte, die üblicherweise mehr als einmal in einem System verwendet werden (z. B. der E/A-Expander PCF8574), 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 hat eine solche Adressleitung (AD0), sodass zwei davon im selben System verwendet werden können.

Sie können auch mehrere Geräte an einem SPI-Bus haben, aber jedes Gerät muss seine eigene Chip-Select-Leitung (CS) haben. Daher ist die 4-Draht-Beschreibung etwas irreführend – es handelt sich tatsächlich um eine Drei-Draht-Schnittstelle + ein zusätzliches Kabel 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 mit den üblichen Pin-Zuweisungen, die von den verschiedenen Shields verwendet werden, umständlich werden würde, wenn Sie viele Chip-Select-Leitungen benötigen würden .

Ich glaube, die meisten Arduino-Boards laufen mit 5 Volt, einige neuere mit 3,3 V. Die MPU-6500 läuft mit 3,3 V. Wenn die minimale "hohe" Eingangsspannung für den I2C-Bus auf einer 5-V-CPU 3 V oder weniger beträgt, können Sie Pegelumwandlungsprobleme vermeiden, indem Sie einfach 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 „hohe“ Eingangsspannung beträgt 0,7 * Vcc oder 3,5 V, was größer als 3,3 V ist. Sie benötigen also eine Art aktiven Pegel Der TI PCA9306 , der Pullups-Widerstände sowohl auf der 5-V- als auch auf der 3,3-V-Seite des Chips benötigt, kostet nur 78 Cent in Einzelstückzahlen.

Warum dann jemals SPI über I2C wählen? Hauptsächlich, weil SPI viel viel schneller ausgeführt werden kann - in einigen Fällen bis zu vielen 10 MHz. I2C ist im Allgemeinen auf 400 KHz begrenzt. Aber das ist nicht wirklich ein Problem für den MPU-6050/6000-Beschleunigungsmesser, da er mit 400 KHz für I2C und nur 1 MHz für SPI läuft – kein großer Unterschied.

Ein weiterer Grund, SPI gegenüber I2C zu wählen: Alle Leitungen sind unidirektional, was Dinge wie Pegelumsetzer etwas einfacher macht.
@markrages, ich habe das Datenblatt für eine 5-V-Arduino-CPU überprüft und festgestellt, dass meine einfache Pullup-Lösung nicht funktioniert, da die Mindesteingabe für den I2C 0,7 * Vcc oder 3,5 V beträgt. Also braucht man einen Levelshifter. Ich habe meine Antwort geändert, um dies anzuzeigen, und empfehle die Verwendung eines Chips. Ich stimme zu, dass die Pegelverschiebung für SPI einfacher ist, da Sie nur eine CPU-Eingangsleitung zu behandeln haben (MISO) - die Ausgänge können mit Spannungsteilern behandelt werden.
I2C ist einfacher als SPI?! Das einzige, was bei I2C einfacher ist, ist die Konnektivität, wenn Sie einfach alles zusammenfügen können. Ansonsten ist die Signalintegrität in I2C schwieriger, und die robuste Softwareimplementierung ist in I2C viel schwieriger.
@JasonS, ich habe Dutzende von Embedded-Software-Projekten mit I2C abgeschlossen und bin nie auf die Lock-up-Probleme gestoßen, die Sie in Ihrem Beitrag erwähnen. Ich kann verstehen, dass Sie es aufgrund Ihrer schlechten Erfahrungen nicht mögen. Ich habe derzeit ein Produkt auf dem Markt, das einen I2C-DAC zur Audioausgabe verwendet und gleichzeitig den nächsten Datenpuffer von einer SD-Karte über SPI liest. Funktioniert super. Ich konnte SPI nicht sowohl für den DAC als auch für die SD-Karte verwenden, da ich Buskonflikte bekam und das Audio unterbrochen wurde. Das Mikro (ein Low-End-Gerät) hat nur einen SPI- und einen I2C-Port.
Ich bin beeindruckt, dass Sie Audio an einen I2C-DAC ausgeben können! (Was ist die maximale Taktrate?) Wenn Sie Onboard-ICs mit kurzen Laufzeiten verwenden, ist die Wahrscheinlichkeit, dass es zu einem Lockup kommt, extrem gering, aber es besteht immer noch. (Sie würden auch nie darauf stoßen, wenn Sie nur Daten auf I2C schreiben. Sie müssen von einem Gerät lesen, das bereit ist, ewig auf das zu warten, was es für eine fehlende / zusätzliche Uhr hält.)
@JasonS, das Audio ist nur Sprachqualität, 8 kHz - ich verwende einen 128-us-Interrupt, um jedes 16-Bit-Sample auszugeben. Der I2C läuft auch auf einem eigenen Interrupt. Die freie Zeit wird genutzt, um Daten von der SD-Karte auszulesen. Guter Punkt, dass beim Schreiben nie eine Sperre auftritt. Abgesehen von ADCs habe ich im Allgemeinen I2C für Ausgabegeräte verwendet. Wussten Sie jedoch, dass die schreibgeschützte Schnittstelle (2 Tasten, Beschleunigungsmesser und Joystick) zwischen der Wii-Fernbedienung und dem Wii-Nunchuck (über ein 3-Fuß-Kabel) I2C bei 400 KHz ist? Viele Informationen im Internet über das Hacken dieser Geräteschnittstelle.
@JasonS: Für die Kommunikation zwischen zwei Mikrocontrollern ist das Fehlen von Handshaking in SPI ein echtes Problem.
Entschuldigung für meine Ablehnung; Wenn Sie eine Token-Bearbeitung vornehmen (Leerzeichen hinzufügen oder was auch immer), entferne ich die Ablehnung.
JasonS, ich habe meine Antwort bearbeitet, um klarer zu machen, dass der I2C-Bus aus Hardware-Sicht im Allgemeinen einfacher zu verwenden ist (trotz Problemen mit dem Pegelübergang).
-1 --------> +1

Im Allgemeinen ist SPI ein schnellerer Bus – die Taktfrequenz kann im MHz-Bereich liegen. SPI erfordert jedoch mindestens 3 Leitungen für die bidirektionale Kommunikation und einen zusätzlichen Slave-Select für jedes Gerät am Bus.

I2C benötigt nur 2 Leitungen, unabhängig davon, wie viele Geräte Sie haben (in Grenzen natürlich). Die Geschwindigkeit liegt jedoch im Bereich von kHz (typisch sind 100-400 kHz).

Die meisten Mikrocontroller haben heutzutage Hardwareunterstützung für beide Busse, sodass beide gleichermaßen einfach zu verwenden sind.

-1: Beide sind nicht gleich einfach zu bedienen. I2C hat eine Menge komplexer Fehlerbehandlung und -wiederherstellung, die nicht oft von Mikrocontroller-Peripheriegeräten gehandhabt wird (sicherlich nicht in PIC18-, PIC30- oder TI C28xx-DSPs - Sie erhalten ein Peripheriegerät, das die meisten I2C-, aber nicht alle Fälle bewältigen kann .)
@Jason: Sie scheinen einige Vorurteile gegenüber IIC zu haben, aber es ist unfair, andere Leute deswegen anzurufen. Sowohl IIC als auch SPI sind "einfach", wobei jeder seine eigenen Falten hat. SPI benötigt zusätzliche Leitungen, was nicht einfach sein kann. IIC ist etwas komplizierter, aber es ist immer noch einfach, alle Firmware-Implementierungen zu machen, was ich vielleicht mal gemacht habe. Es dauert nicht allzu viel Code. Beide haben ihren Platz und beide sind leicht genug, um für niemanden, der weiß, was sie tun, ein Faktor zu sein.
Nicht ungerecht. Ich stimme gerne zu, wenn die Aussage "ebenso einfach zu bedienen" korrigiert oder zumindest klargestellt wird. Ich fordere jeden auf, Software auf einem Mikroprozessor mit intelligenten I2C- und SPI-Peripheriegeräten zu schreiben, um eine Schnittstelle mit einer IC-Serie herzustellen, die sowohl I2C- als auch SPI-Varianten hat, und zeige mir die Softwarekomplexität anhand eines beliebigen objektiven Maßes (Codezeilen, Anzahl der Zustände, zyklomatische Komplexität). , usw.), um zu zeigen, dass sie genauso einfach zu verwenden sind. Beispiele: Microchip 24LC256/25LC256 EEPROM, MCP23017/23S17 E/A-Expander.
@Jason: Ich habe gerade nachgesehen, und mein generischer IIC-Code für die Firmware - Implementierung von IIC auf 8-Bit-PICs besteht nur aus 311 Zeilen, und wahrscheinlich sind mehr als die Hälfte davon Kommentare. Dadurch erhalten Sie eine prozedurale Schnittstelle zum IIC-Bus auf der Ebene der Routinen für Start, Put, Get, Stop usw. Große Sache. Ein Modul, das das aufruft, um ein einfaches EEPROM anzusteuern, hat 272 Zeilen, wahrscheinlich wieder 1/2 Kommentare, und das beinhaltet einige High-Level-Verwaltungen wie Standarddaten, UART-Debug-Schnittstelle usw. Das ist alles so trivial, dass man sich darüber streiten muss, ob es 10 Anweisungen weniger braucht als SPI ist sinnlos.
@JasonS: Nur weil Sie I2C nicht einfach zu bedienen finden, macht es das nicht für alle schwierig. Ich habe viele Industrieanlagen mit I2C entworfen und bin nie auf die Probleme gestoßen, die Sie in Ihrer Antwort beschreiben. Ich denke, Olin hat Recht: Sie haben I2C falsch angewendet und eine sehr starke Abneigung dagegen entwickelt. An einer Meinung ist nichts auszusetzen, und Sie machen einige gute Punkte, aber es in fast jeder Antwort hier zu verschwenden und Ihre Haltung weiterhin zu verteidigen ... das ist keine praktische Abneigung; das ist religiöser Fanatismus. Deine Antwort war sehr gut. Es ist nicht nötig, auch alle anderen zu kommentieren.
@AndrewKohlsmith: Um Jason gerecht zu werden, gibt es einige Tricks mit Bit-Bang-I2C, die die Dinge viel einfacher machen können, aber die Gerätedokumentation zeigt sie normalerweise nicht und viele Hardwareimplementierungen unterstützen sie nicht. Es ist zum Beispiel oft einfacher, eine Byte-Lese-Routine eine ACK senden zu lassen, bevor sie jedes Byte nach dem ersten liest, und eine NAK-Routine aufzurufen, nachdem das letzte Byte gelesen wurde, als eine Byte-Lese-Routine zu haben, die einen Parameter zur Angabe verwendet ob ACK oder NAK, da man vielleicht nicht weiß, bis man ein Byte gelesen hat, ob man ein weiteres haben möchte.
Ok, ich möchte mich dafür entschuldigen, dass ich sowohl in meinen Kommentaren zu anderen Beiträgen als auch in meiner eigenen Antwort einen wütenden Ton angeschlagen habe. Was ich zugeben möchte, ist, dass es Möglichkeiten gibt, I2C-Software mit On-Chip-Peripheriegeräten zu schreiben, die relativ einfach sind, wobei bestimmte seltene Fehlerbedingungen vernachlässigt werden. Trotzdem denke ich immer noch, dass es irreführend ist zu sagen, dass I2C einfach ist. Und ich glaube nicht, dass ich I2C falsch angewendet habe. Schauen Sie sich den TMP75 an - einen I2C-Temperatursensor. Sie können bis zu 27 davon mit in den Bus nehmen. (Wir haben ein System mit 8.) Würde irgendjemand sie alle auf ein Board setzen? Das Datenblatt warnt Sie nicht vor Off-Board-Problemen.
Olin: Nur neugierig – ist Ihre Implementierung blockierend oder nicht blockierend (z. B. zustandsgesteuert)? Ich kann sehen, dass eine blockierende Implementierung Fehlerbedingungen ohne allzu große Probleme behandeln könnte. Ich habe ein System, das harte Echtzeitanforderungen hat, und ich muss meine I2C-Verarbeitung wegen all der verschiedenen Fehlerfälle in eine Zustandsmaschine aufteilen - während die SPI-Verarbeitung ein Kinderspiel ist; Wir schalten einfach unsere CS-Adresse um, senken die CS-Aktivierungsleitung, stellen Sendedaten in die Warteschlange, warten einige Mikrosekunden, erhöhen die CS-Aktivierungsleitung und lesen die Empfangsdaten.
Andrew: "Laufen Sie niemals auf die Probleme zu, die Sie in Ihrer Antwort beschreiben." Sicher, besonders wenn der I2C-Bus mit relativ kurzen Spuren an Bord ist. Weniger Rauschen = Wahrscheinlichkeit einer verpassten I2C-Uhr sinkt auf einen sehr geringen Betrag. Wir haben 8 TMP75-Sensoren in einem lauten Industriesystem. (Im Nachhinein wünschte ich, unser Designer hätte analoge Temperatursensoren verwendet.) Wenn es gelegentliche Datenfehler wären (die wir bekommen), wäre es nicht so schlimm. Aber das Problem ist, dass Sie einen Deadlock bekommen können, und selbst wenn die Wahrscheinlichkeit des Fehlers gering ist, ist Ihre Wahrscheinlichkeit, dass Sie ohne die richtige Fehlerbehandlung entkommen, 0, wenn Sie einmal dort sind.
@Armandas: Entschuldigung für meine Ablehnung; Wenn Sie eine Token-Bearbeitung vornehmen (Leerzeichen hinzufügen oder was auch immer), entferne ich die Ablehnung.
@JasonS, das ist mein Punkt: I2C ist für On-Board-Anwendungen konzipiert. Es kann gestreckt werden, um über Kabel übertragen zu werden, aber das ist nicht die beabsichtigte Anwendung, und Sie müssen für die zusätzliche Komplexität entwerfen. Was Zombie-Geräte angeht: Kein vernünftiger I2C-Slave würde die Uhr auf unbestimmte Zeit dehnen, und wenn Sie die Kontrolle über die Uhr haben, können Sie die I2C-Übertragung abbrechen und den Bus zurücksetzen. Es ist nicht das verrückte, schwierige System, als das Sie es darzustellen scheinen.
@Andrew Kohlsmith - I2C is designed for on-board applications.- Anscheinend sind I2C-Gerätehersteller anderer Meinung als Sie. Nimm den TMP100 . Auf der Produktseite heißt es explizit: 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 TMP75
Für das, was es wert ist, habe ich 8 TMP100 auf einem I2C-Bus ausgeführt, der ~ 15 'lang war, aber die Umgebung hatte wenig Lärm. Die gesamte I2C-Schnittstelle für dieses Projekt war ein Bit-Banged, und es war eine Nervensäge.
Ich denke, dieses ganze Argument läuft darauf hinaus, dass Menschen unterschiedliche Perspektiven haben. Sie haben Jason S., der extrem hochzuverlässige industrielle Steuerungssysteme mit harter Echtzeit zu entwerfen scheint, und Andrew Kohlsmith und Olin Lathrop, die eher verbraucherorientierte Geräte entwerfen (?). I2C ist in einer Umgebung, in der diese Fehlerrate von 0,001 % ein erhebliches und ernstes Problem darstellt, möglicherweise nicht realisierbar (insbesondere, wenn Sie nicht ~ 1 Sekunde auf das Timeout warten können). In vielen Situationen ist ein solcher Fehler jedoch ausreichend unwahrscheinlich, um keine Probleme zu verursachen, oder die Verzögerung, die er einführen würde, ist nicht problematisch.
Persönlich würde ich mit SPI über I2C gehen, aber das liegt eher daran, dass ich ziemlich schlecht im Programmieren bin und die Komplexität eines zusätzlichen Bleidrahts trivial finde. YMMV.
@JasonS Keine Sorge, es ist eine einfache Antwort und punktuell ist es ungefähr dort, wo es sein sollte.
@FakeName Der TMP100 gibt nirgendwo an, dass er für die Temperaturerfassung außerhalb des Fahrzeugs gedacht ist. Ihr Angebot besagt lediglich, dass es für bestimmte Anwendungen ideal ist. In diesen Anwendungen können Sie die Temperatur mit dem Gerät messen. Standard-Marketing-Flusen, das ist alles. Maxim ist besonders schlecht, wenn es darum geht, eine Unmenge von Anwendungen für jedes Gerät aufzulisten.
@FakeName Als ich ein Hitzdraht-Anemometer baute, verwendete ich Geräte mit zwei Transistoren, die über verdrillte Paare mit einer Standard-SMBus-Temperatur-/Lüftersteuerung verbunden waren. Wie Sie wissen, ist SMBus ein verbesserter I2C, aber der Chip war an Bord und hatte nie Kommunikationsprobleme. Ich glaube, du hast den Temperatursensor falsch angebracht.
@FakeName Du liegst falsch; Ich habe 13 Jahre mit industrieller Leistungselektronik gearbeitet. (Das Starten und Überwachen von GROSSEN Dreiphasenmotoren ist eine SEHR laute Umgebung.) Es geht nicht darum, dass SPI zuverlässiger ist, sondern darum, das System mit allen geplanten und berücksichtigten Fehlermodi zu entwerfen und bei Bedarf Wiederherstellungsoptionen in das System einzubauen. Ich habe noch nie eine Rauschspitze gehabt, die meine I2C- (oder SPI-) Kommunikation zerstört hat, aber ich habe mich auch nie ausschließlich auf den I2C-Controller verlassen, um alles für mich zu erledigen. Es geht um Planung und Design, nicht darum, dass ein Bus besser ist.
"Aber ich habe mich auch nie ausschließlich auf den I2C-Controller verlassen, um alles für mich zu erledigen" - das ist nicht einfach, worauf ich hinaus wollte.
@akohlsmith: Single-Master-Single-Slave-I2C sollte mit einem "Bit-Bang" -Master robust sein. Wenn es mehrere Slaves gibt und zwei gleichzeitig auf unterschiedliche Weise "verwirrt" werden, kann der Bus unwiederbringlich hängen bleiben (z. B. wenn zwei oder mehr Speicherchips, die mit Nullen gefüllt sind, beide glauben, dass der Master versucht, sie zu lesen, aber ihre Bitzähler nicht synchron sind, dann wird jeder SDA nur dann freigeben, wenn der andere es behauptet, und nichts, was der Master tun kann, wird den Bus freigeben, es sei denn, er kann ein "High" treiben, das stark genug ist, um alle Slaves zu übersteuern.

SPI kann viel schneller ausgeführt werden als I2C (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 beider Protokolle erfordert Hardwareunterstützung, während beide eine einfache Implementierung von "Software-Bit-Bang"-Mastern ermöglichen. Mit relativ minimaler Hardware kann man einen I2C-kompatiblen Slave konstruieren, der auch dann korrekt funktioniert, wenn der Host willkürlich entscheidet, den Bus für bis zu 500 us gleichzeitig zu ignorieren, ohne dass zusätzliche Handshaking-Kabel erforderlich sind. Ein zuverlässiger SPI-Betrieb erfordert jedoch, selbst mit Hardwareunterstützung , im Allgemeinen, dass entweder ein Handshake-Kabel hinzugefügt wird oder dass der Host "manuell" nach jedem Byte eine Verzögerung hinzufügt, die der Worst-Case-Antwortzeit des Slaves entspricht.

Wenn ich meine Druther hätte, würde die SPI-Unterstützung der Controller ein paar einfache zusätzliche Funktionen enthalten, um 8-Bit-transparente bidirektionale Datenübertragungen zwischen Controllern mit Handshaking- und Wake-up-Fähigkeiten bereitzustellen, wobei insgesamt drei unidirektionale Drähte verwendet werden (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 "Standard" -SPI-Ports, wenn beide Prozessoren unabhängig voneinander für beliebige Zeiträume verzögert werden können, die Verwendung von viel mehr Drähten (Chip-Select, Clock, MISO und MOSI zum Starten). mit plus einer Art Bestätigungsleitung vom Slave. Wenn der Slave möglicherweise asynchron Daten zu senden beginnt (z. B. weil jemand einen Knopf gedrückt hat), muss man entweder eine weitere Leitung als "Weck" verwenden

I2C bietet nicht alle Fähigkeiten, die mein "verbessertes" SPI haben würde, aber es bietet integrierte Handshaking-Fähigkeiten, die SPI fehlt, und in vielen Implementierungen kann es auch zum Aufwecken verwendet werden, selbst wenn der Master ein ist Software-Bit-Bang. Für die Kommunikation zwischen Prozessoren würde ich daher dringend I2C über SPI empfehlen, außer wenn höhere Geschwindigkeiten benötigt werden, als SPI liefern kann, und die Verwendung zusätzlicher Pins akzeptabel ist. Für die Kommunikation zwischen Prozessoren, bei der eine geringe Anzahl von Pins erforderlich ist, haben UARTs viele Vorteile.

Es gibt eine Hochgeschwindigkeitsversion von I2C, die 1 MHz zulässt; normaler I2C ist 400kHz.
@TheResistance: Ich weiß, dass normales I2C 400 kHz war, aber Versionen wurden bis zu 1 MHz spezifiziert. Was ich nicht weiß ist, ob schnellere Versionen angegeben wurden.
Laut Spezifikation ist 400kbps (nicht kHz, da habe ich die falschen Einheiten verwendet) Fast-Mode, 1Mbps ist Fast-Mode Plus und es gibt einen High-Speed-Mode bis 3,4Mbps. Ultraschnell geht bis zu 5 Mbit/s, ist aber unidirektional.
@TheResistance: Danke. Von diesen späteren Versionen hatte ich noch nichts gehört. Was genau meinst du mit "unidirektional"? Ich weiß, dass die Geschwindigkeit der SPI-Slave-to-Master-Kommunikation schneller sein kann als die Master-to-Slave-Kommunikation, da der Slave seine Uhr garantiert nach dem Master erhält, aber ich bin mir nicht sicher, ob es ein gleichwertiges Konzept für I2C gibt. Haben Sie einen Link?
Die Spezifikation finden Sie hier . Auf Seite 23 heißt es, dass Ultra-Fast für Geräte verwendet werden kann, die keine Daten zurücksenden (nur schreiben), nicht einmal ACK.
@TheResistance: Das ultraschnelle Format scheint etwas merkwürdig zu sein. Wenn ich Push-Pull-Kommunikation benötige, um mit minimalen Kabeln mit einem CPLD zu sprechen, habe ich SPI verwendet, aber die Kommunikationsschnittstelle wurde zurückgesetzt, wenn sie zwei oder mehr steigende Flanken auf MOSI empfing, während der Takt niedrig war (erzeugt durch Umschalten von MOSI auf Allzweck E/A). Ein solcher Ansatz ermöglichte die Verwendung der SPI-Master-Hardware fast aller Controller (viele I2C-Implementierungen können nicht als Push-Pull konfiguriert werden) und erforderte keinen zusätzlichen Takt nach jedem Byte.

Diese Frage wurde in den hervorragenden Antworten hier gründlich untersucht, aber vielleicht gibt es noch einen weiteren Standpunkt zu I 2 C, den ich aus Sicht eines Chipherstellers anbieten könnte.

Die elektrische Schnittstelle des I 2 C ist ein offener Kollektor . Jetzt atmen Sie und denken Sie an die Auswirkungen. 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 Belieben nach unten zu ziehen und die Spannungen von SCL und SDA mit einer massebezogenen 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 unabhängig vom Rest des Systems sein eigenes Leben führen kann - SCL, SDA speisen meinen Chip und mich niemals mit Strom wird diesen Pins sicherlich keinen Strom zuführen. Deshalb ist es so ein schöner Bus für Echtzeituhren und andere Dinge mit geringem Stromverbrauch.

Eine Sache, die ich in den anderen Antworten nicht erwähnt habe, ist, dass I2C mehrere Master auf demselben Bus unterstützt. Wenn Sie eine bidirektionale Kommunikation benötigen und keine abfragebasierte Methode verwenden möchten, erledigt I2C die Arbeit.

Über längere Distanzen hat CAN die gleiche Leistungsfähigkeit und ist robuster. CAN ist jedoch ein asynchrones Protokoll, das Hardwareunterstützung und einen Transceiver erfordert, sodass es in einem kostengünstigen System möglicherweise keine Option ist.

Guter Punkt (auf Multi-Master), ich habe auch SPI-Geräte mit Interrupt-Pins gesehen, während ein Gerät immer noch der Master ist, können beide die (bidirektionale) Kommunikation instanziieren. Für abgesetzte Geräte gibt es natürlich solidere und bessere Möglichkeiten (zB CAN).

Verwenden Sie das SPI-Protokoll und schreiben Sie Ihre Bits direkt auf das Gerät, wenn die Synchronisierungsuhr steigt. 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 die Autorenschaltung 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, aber nicht i2c.

I2C ist ein Bus mit Datenadressen. SPI ist ein Bus mit physikalischen Adressen.

I2C, wie oben erwähnt, ist ohne einen Hardware-Controller nicht einfach oder einfach.

Im Übrigen ist SPI ohne einen Hardware-Controller im Kontext dieser Diskussion auch nicht einfach. Vor allem, weil das Timing so schnell ist, kann es schwierig sein, es vorherzusehen, und jedes Gerät hat sein eigenes Protokoll und seine eigenen Anomalien.

Mein Vorschlag ist, diese Entscheidung basierend auf der Bandbreite zu treffen.

Wenn Ihre Anwendung von Zeitpräzision und Datenrate profitiert. Insbesondere wenn I2C nicht die volle Bandbreite bietet, verwenden Sie SPI.

Wahrscheinlich existiert für beide eine Bibliothek zur Schnittstelle oder wird es in Kürze geben. Wenn nicht, löse ich persönlich SPI-Probleme lieber als I2C-Probleme.

Wenn Sie keines dieser Themen betrifft. Verwenden Sie I2C einfach, weil es wahrscheinlicher ist, dass Code vorhanden ist und weniger Verbindungen hergestellt werden müssen.