Quels compromis devrais-je prendre en compte lorsque je décide d'utiliser une interface SPI ou I2C?
Cette carte opto-isolée pour accéléromètre / gyroscope est disponible en deux modèles, un pour chaque interface. Est-ce que l'un ou l'autre serait plus facile à intégrer dans un projet Arduino?
Réponses:
Sommaire
I2C est un système de bus avec des données bidirectionnelles sur la ligne SDA. SPI est une connexion point à point avec des données en entrée et des données en sortie sur des lignes séparées (MOSI et MISO).
Essentiellement, SPI consiste en une paire de registres à décalage, dans lesquels vous synchronisez des données dans un registre à décalage, tandis que vous synchronisez des données avec un autre. Habituellement, les données sont écrites en octets en ayant chaque fois 8 impulsions d'horloge successives, mais ce n'est pas une exigence SPI. Vous pouvez également avoir une longueur de mot de 16 bits ou même de 13 bits, si vous le souhaitez. Tandis qu'en I2C, la synchronisation est effectuée par la séquence de démarrage dans SPI, le SS passe à l'état haut (le SS est actif bas). Vous décidez vous-même après le nombre d'impulsions d'horloge. Si vous utilisez des mots de 13 bits, le SS verrouille le dernier horloge en bits après 13 impulsions d'horloge.
Comme les données bidirectionnelles se trouvent sur deux lignes distinctes, l’interface est facile.
SPI en mode standard nécessite au moins quatre lignes: SCLK (horloge série), MOSI (entrée maître esclave sortie), MISO (sortie maître esclave) et SS (sélection esclave). En mode bidirectionnel, il faut au moins trois lignes: SCLK (horloge série), MIMO (Master In Master Out), qui est l’une des lignes MOSI ou MISO, et SS (Slave Select). Dans les systèmes avec plusieurs esclaves, vous avez besoin d'une ligne SS pour chaque esclave. Ainsi, pour esclaves, vous avez lignes en mode standard et lignes en mode bidirectionnel. Si vous ne le souhaitez pas, en mode standard, vous pouvez chaîner les esclaves en connectant le signal MOSI d'un esclave au MISO du suivant. Cela ralentira la communication car vous devez parcourir toutes les données des esclaves.N + 3 N + 2N N+3 N+2
Comme tcrosley, SPI peut fonctionner à une fréquence beaucoup plus élevée que I2C.
I2C est un peu plus complexe. Puisqu'il s'agit d'un bus, vous avez besoin d'un moyen d'adresser les appareils. Votre communication commence par une séquence de démarrage unique: la ligne de données (SDA) est abaissée alors que l'horloge (SCL) est haute, car le reste des données de communication ne peut changer que lorsque l'horloge est basse. Cette séquence de démarrage synchronise chaque communication.
Étant donné que la communication comprend l'adressage, deux lignes sont nécessaires pour un nombre quelconque de périphériques (jusqu'à 127).
Après l'envoi de chaque octet (adresse ou données), le destinataire doit accuser réception en transmettant une impulsion d'accusé de réception à la SDA. Si votre microcontrôleur a une interface I2C, celle-ci sera automatiquement prise en charge. Vous pouvez toujours bit-bang si votre microcontrôleur ne le prend pas en charge, mais vous devrez commuter la broche d'E / S de sortie en sortie pour chaque accusé de réception ou lire des données, sauf si vous utilisez une broche d'E / S pour la lecture et la lecture. un pour l'écriture.
À 400kHz, la norme I2C est beaucoup plus lente que SPI. Il existe des périphériques I2C haut débit qui fonctionnent à 1 MHz, toujours beaucoup plus lentement que le SPI à 20 MHz.
la source
(Edit: pour être clair, bon nombre des problèmes suivants ont trait à l'intégrité du signal provoquée par l'utilisation carte à carte des périphériques I2C / SPI, comme le fait remarquer Olin à juste titre.)
À moins de contraintes contraignantes qui vous poussent à réduire le nombre de fils (nous avions un projet avec un connecteur hermétique scellé, chaque contact supplémentaire étant assez coûteux), évitez autant que possible I2C et respectez SPI.
Il est assez facile de traiter avec SPI sur une base matérielle et logicielle. En matériel, il existe deux lignes de données partagées, une entrée maître entrée esclave (MISO ou SOMI) et une entrée maître sortie esclave (MOSI ou SIMO), une horloge partagée générée par le maître et une puce de sélection par périphérique. La ligne CS devient basse, l'horloge se cycle et se décale essentiellement en bits d'entrée et en sortie, jusqu'à la fin de la transaction, point auquel la ligne CS devient haute. Lorsque leur ligne CS est haute, les périphériques esclaves ne communiquent pas: ils ignorent les lignes CLK et MOSI et placent leur broche MISO dans un état haute impédance pour permettre à une autre personne de l'utiliser.
Si vous avez un microcontrôleur utilisant plusieurs périphériques SPI et qu'il possède un périphérique SPI intégré, envoyez la sortie CS du microcontrôleur à un démultiplexeur (par exemple 74HC138) et contrôlez les lignes d'adresse pour sélectionner le périphérique entre les transactions SPI. vous écrivez des mots dans un registre pour les mettre en file d'attente et les relire une fois que la broche CS est élevée.
Les signaux SPI étant tous unidirectionnels, ils peuvent être mis en mémoire tampon, utilisés au-delà d’une barrière d’isolement avec des isolateurs numériques et peuvent être envoyés d’une carte à l’autre à l’aide de pilotes de ligne tels que LVDS. La seule chose qui vous préoccupe est le délai de propagation aller-retour, qui limitera votre fréquence maximale.
I2C est une histoire complètement différente. Bien que cela soit beaucoup plus simple du point de vue du câblage, avec seulement deux fils SCL et SDA, ces deux lignes sont des lignes bidirectionnelles partagées qui utilisent des périphériques à drain ouvert avec une extraction externe. Il existe un protocole pour I2C qui commence par transmettre une adresse de périphérique, de sorte que plusieurs périphériques puissent être utilisés si chacun a sa propre adresse.
Du point de vue matériel, il est très difficile d’utiliser I2C dans des systèmes très bruyants. Pour tamponner ou isoler les lignes I2C, vous devez recourir à des CI exotiques - oui, ils existent, mais ils sont peu nombreux: nous avons utilisé un projet individuel et avons réalisé que vous pouviez utiliser un isolateur, mais vous ne pouviez pas. utiliser deux en série - il a utilisé de petites chutes de tension pour déterminer quel côté était le moteur, et deux chutes de série étaient deux beaucoup.
Les seuils de niveau logique d'I2C dépendent de Vcc. Vous devez donc faire très attention si vous utilisez des appareils 3V / 3,3V et 5V dans le même système.
Tous les signaux utilisant un câble de plus d'un pied ou deux doivent s'inquiéter de la capacité du câble. Une capacité de 100 pf / mètre n'est pas inhabituelle pour un câble multiconducteur. Cela vous oblige à ralentir le bus ou à utiliser des résistances de rappel plus faibles pour pouvoir gérer correctement la capacité supplémentaire et répondre aux exigences de temps de montée.
Supposons donc que vous avez un système que vous pensez avoir bien conçu et que vous pouvez gérer la plupart des problèmes d’intégrité du signal. Le bruit est rare (mais toujours présent). De quoi as-tu à t'inquiéter?
Il y a un tas de conditions d'erreur que vous devez être prêt à gérer:
Le périphérique esclave ne reconnaît pas un octet particulier. Vous devez le détecter, puis arrêter et redémarrer la séquence de communication. (Avec SPI, vous pouvez généralement relire les données que vous envoyez si vous voulez vous assurer qu'elles ont été reçues sans erreur.)
Vous lisez un octet de données d'un périphérique esclave, et le périphérique est "hypnotisé" à cause du bruit sur la ligne d'horloge: vous avez envoyé les 8 horloges requises pour lire cet octet, mais à cause du bruit, le périphérique esclave le pense a reçu 7 horloges et transmet toujours un 0 sur la ligne de données. Si le dispositif avait reçu la 8ème horloge, il aurait relâché la ligne de données à l'état haut afin que le maître puisse élever ou abaisser la ligne de données pour transmettre un bit ACK ou NACK, ou qu'il puisse émettre une condition d'arrêt (P). Mais l'esclave tient toujours la ligne de données basse, attendant en vain une autre horloge. Si un maître n'est pas prêt à essayer des horloges supplémentaires, le bus I2C sera bloqué dans une impasse. Bien que j’ai utilisé plusieurs microcontrôleurs qui gèrent les conditions normales d’ACK / NACK,
Le cas vraiment horrible est lorsqu'un maître écrit des données sur un périphérique esclave et qu'un autre esclave interprète l'adresse de périphérique de manière incorrecte et pense que les données transmises lui sont destinées. Des périphériques I2C (expandeurs d'E / S) ont parfois des registres mal configurés à cause de cela. Il est presque impossible de détecter ce cas, et pour résister au bruit, vous devez définir périodiquement tous les registres, de sorte que si vous rencontrez cette erreur, elle sera au moins corrigée après une courte période. (SPI n'a jamais ce problème - si vous rencontrez un petit problème sur la ligne CS, il ne persistera jamais et les données ne seront pas lues accidentellement par le mauvais périphérique esclave.)
Un grand nombre de ces conditions pourraient être gérées correctement dans le protocole en cas de détection d'erreur (codes CRC), mais peu de périphériques en disposent.
Je constate que je dois créer un logiciel complexe sur mon périphérique maître I2C pour gérer ces conditions. À mon avis, cela ne vaut tout simplement pas la peine, à moins que les contraintes de câblage ne nous obligent à utiliser I2C et non SPI.
la source
La carte opto-isolée pour le périphérique chez SparkFun est en fait pour la version I2C uniquement (MPU-6500). La version MPU-6000 dispose des interfaces SPI et I2C sur la même puce, et je ne vois pas que SparkFun possède une carte avec cette puce. Je pense donc que vous êtes limité à utiliser I2C si vous souhaitez utiliser ce forum particulier. Mais j’allais quand même recommander l’utilisation de I2C dans votre situation pour les raisons suivantes.
En général, vous constaterez que le bus I2C est plus facile à utiliser du point de vue matériel que le bus SPI. I2C est un bus à 2 fils (SCL / SDA):
SPI est un bus à 4 fils (SCLK / MOSI / MISO / CS):
Vous pouvez avoir plusieurs périphériques connectés à un bus I2C. Chaque appareil possède son propre ensemble d'adresses intégrées à la puce. L'adresse est en fait diffusée sur le bus en tant que premier octet de chaque commande (avec un bit de lecture / écriture). Ceci, ainsi que d'autres frais généraux, nécessite l'envoi de davantage de bits sur un bus I2C par rapport à SPI pour la même fonctionnalité.
Différentes classes de périphériques (mémoire, E / S, LCD, etc.) ont des plages d'adresses différentes. Certains périphériques, qui sont couramment utilisés plus d’une fois dans un système (tel que le module d’extension d’E / S PCF8574), utilisent une ou plusieurs lignes d’adresse (AD0-2 pour le PCF8574) qui peuvent être liées haut ou bas pour spécifier les bits faibles. de l'adresse. Le MPU-6500 possède une seule ligne d'adresse (AD0), de sorte que deux d'entre elles peuvent être utilisées dans le même système.
Vous pouvez également avoir plusieurs périphériques sur un bus SPI, mais chaque périphérique doit avoir sa propre ligne de sélection de puce (CS). Par conséquent, la description à 4 fils est un peu abusive - il s’agit en réalité d’une interface à trois fils + d’un fil supplémentaire par appareil. Je ne connais pas la série de cartes Arduino, mais je pense que cela compliquerait l'utilisation de SPI sur Arduino, car si vous aviez besoin de nombreuses lignes de sélection de puces, cela commencerait à devenir encombrant avec les affectations de broches communes utilisées par les différents boucliers. .
Je crois que la plupart des cartes Arduino fonctionnent à 5 volts, certaines plus récentes à 3,3 v. Le MPU-6500 fonctionne à 3,3 v. Si la tension d'entrée "élevée" minimum pour un bus I2C sur une CPU 5v est de 3v ou moins, vous pouvez éviter les problèmes de conversion de niveau en fournissant simplement des résistances de rappel 10K à 3,3v sur les lignes SCL et SDA, car le bus est ouvert. collectionneur. Assurez-vous que tous les transferts internes 5v sur un processeur sont désactivés.
Cependant, j'ai vérifié la fiche technique de l'ATmega2560 (en prenant l'exemple de l'Arduino ADK 5v), et sa tension d'entrée "haute" minimale est de 0,7 * Vcc, ou 3,5 V, ce qui est supérieur à 3,3 V. Vous avez donc besoin d'un niveau de niveau actif La TI PCA9306 , qui nécessite des résistances de pullup sur les côtés 5v et 3,3v de la puce, ne coûte que 78 cents en quantités uniques.
Pourquoi alors ne jamais choisir SPI sur I2C? Principalement parce que le SPI peut être exécuté beaucoup plus rapidement - jusqu'à 10 MHz dans certains cas. I2C est généralement limité à 400 KHz. Mais ce n’est pas vraiment un problème pour l’accéléromètre MPU-6050/6000, car il fonctionne à 400 kHz pour I2C et à seulement 1 MHz pour SPI - ce n’est pas une si grande différence.
la source
En général, SPI est un bus plus rapide - la fréquence d'horloge peut être dans une plage de MHz. Cependant, SPI nécessite au moins 3 lignes pour la communication bidirectionnelle et un esclave supplémentaire pour chaque périphérique du bus.
I2C ne nécessite que 2 lignes, quel que soit le nombre de périphériques que vous possédez (dans les limites bien sûr). La vitesse, cependant, est dans la gamme de kHz (100-400 kHz est typique).
La plupart des microcontrôleurs, de nos jours, prennent en charge le matériel pour les deux bus, ce qui facilite leur utilisation.
la source
I2C is designed for on-board applications.
- Apparemment, les fabricants d’appareils I2C ne sont pas d’accord avec vous. Prenez le TMP100 . La page du produit indique explicitement:The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
La même chose est vraie pour le TMP75SPI peut être exécuté beaucoup plus rapidement que I2C (certains périphériques SPI dépassent 60 MHz; je ne sais pas si la spécification "officielle" de I2C autorise les périphériques supérieurs à 1 MHz). L'implémentation d'un périphérique esclave à l'aide de l'un ou l'autre protocole nécessite un support matériel, alors que les deux permettent une implémentation aisée des maîtres "logiciels bit-bang". Avec un matériel relativement minimal, il est possible de construire un esclave compatible I2C qui fonctionnera correctement même si l’hôte peut décider arbitrairement d’ignorer le bus jusqu’à 500 us à la fois, sans nécessiter de fils de transfert supplémentaires. Le bon fonctionnement du SPI, cependant, même avec un support matériel , nécessite généralement soit l’ajout d’un fil de liaison, soit le fait que l’hôte ajoute "manuellement" un délai après chaque octet égal au temps de réponse le plus défavorable de l’esclave.
Si j’avais mes capacités, le support SPI des contrôleurs contiendrait quelques fonctionnalités supplémentaires simples permettant des transferts de données bidirectionnels transparents sur 8 bits entre contrôleurs dotés de capacités de prise de contact et de réveil, utilisant un total de trois fils unidirectionnels (Clock et MOSI [master]). -out-slave-in] du maître; MISO [maître-in-slave-out] de l'esclave). En comparaison, une communication efficace et fiable entre les microcontrôleurs dotés de ports SPI "standard", lorsque les deux processeurs peuvent être retardés indépendamment pour des durées arbitraires, nécessite l'utilisation de beaucoup plus de fils (puce à puce, horloge, MISO et MOSI). Avec, en plus, une sorte de câble d’accusé de réception de l’esclave. Si l’esclave peut commencer à envoyer des données de manière asynchrone (par exemple, parce que quelqu'un a appuyé sur un bouton), il faut alors utiliser un autre câble comme "réveil".
I2C ne fournit pas toutes les capacités que mon SPI "amélioré" aurait, mais il offre des capacités de prise de contact intégrées qui manquent à SPI. logiciel bit-bang. Pour les communications entre processeurs, je recommande donc fortement I2C sur SPI sauf lorsque des vitesses supérieures à celles que SPI peut fournir sont nécessaires, et que l’utilisation de broches supplémentaires est acceptable. Pour les communications entre processeurs nécessitant un nombre de broches faible, les UART ont beaucoup à leur recommander.
la source
Les excellentes réponses fournies ici ont exploré à fond cette question, mais il y a peut-être un autre point de vue sur I 2 C que je pourrais offrir du point de vue d'un fabricant de puces.
L' interface électrique de l' I 2 C est un collecteur ouvert . Maintenant, respirez et réfléchissez aux implications. En utilisant I 2 C, je peux concevoir une puce totalement indépendante de la tension de fonctionnement du bus. Tout ce que j'ai besoin de pouvoir faire, c'est abaisser la ligne SDA si cela me plaît, et comparer les tensions de SCL et de SDA à une tension de seuil référencée à la masse, que je peux choisir. Et si je laisse de côté les structures de protection latérale normales et les remplace par d'autres structures, je peux fabriquer une puce qui peut totalement vivre de sa propre vie, indépendamment du reste du système - SCL, SDA ne jamais alimenter ma puce en courant et moi-même. certainement ne pas alimenter en courant ces broches. C'est pourquoi il s'agit d'un si bon bus pour les horloges en temps réel et autres appareils de faible puissance comme celui-là.
la source
Une chose que je n'ai pas vue mentionnée dans les autres réponses est qu'I2C prend en charge plusieurs maîtres sur le même bus. Si vous avez besoin d'une communication bidirectionnelle et que vous ne voulez pas utiliser une méthode basée sur une interrogation, I2C fera le travail.
Sur de plus longues distances, CAN a la même capacité et est plus robuste. Mais CAN est un protocole asynchrone nécessitant un support matériel et un émetteur-récepteur. Par conséquent, il peut ne pas être une option dans un système à faible coût.
la source
Utilisez le protocole SPI et écrivez vos bits directement sur l'appareil chaque fois que l'horloge de synchronisation monte. Le circuit logique xnor peut être utilisé pour faire correspondre l'adresse "personnalisée" d'une mémoire afin de sélectionner le périphérique souhaité comme s'il s'agissait d'un périphérique i2c.
L’i2c intègre le circuit d’auteur dans le format de l’appareil. Les normes, etc., sont complexes et différentes. Avec un spi, vous pouvez utiliser une mémoire spi pour afficher une vidéo à l’écran, mais pas i2c.
la source