Bir SPI veya I2C arayüzü kullanmaya karar verirken hangi tradeolojileri dikkate almalıyım?
Bu ivmeölçer / gyro koparma kartı, her arayüz için bir tane olmak üzere iki modelde mevcuttur. Bir Arduino projesine entegrasyonu daha kolay olur mu?
Bir SPI veya I2C arayüzü kullanmaya karar verirken hangi tradeolojileri dikkate almalıyım?
Bu ivmeölçer / gyro koparma kartı, her arayüz için bir tane olmak üzere iki modelde mevcuttur. Bir Arduino projesine entegrasyonu daha kolay olur mu?
Yanıtlar:
özet
I2C, SDA hattında çift yönlü veri içeren bir veriyolu sistemidir. SPI, ayrı hatlarda (MOSI ve MISO) veri girişi ve çıkışı olan noktadan noktaya bir bağlantıdır.
Temelde SPI , verileri diğer birinden çıkarırken bir vardiya kaydında verileri saatine geçirdiğiniz bir çift vardiya kaydından oluşur. Genellikle veri bayt cinsinden her defasında 8 saat darbeli olarak yazılır, ancak bu bir SPI gereksinimi değildir. Dilerseniz 16 bit, hatta 13 bit kelime uzunluklarına da sahip olabilirsiniz. I2C'de senkronizasyon SPI'deki start dizisi ile yapılırken, SS yükselmesiyle yapılır (SS aktif düşük). Bu saat kaç darbeden sonra kendinize karar verin. 13 bit kelime kullanırsanız, SS, 13 saat darbesinden sonra bitlerle geçen sonuncuyu kilitleyecektir.
İki yönlü veri iki ayrı satırda olduğu için arayüz kullanımı kolaydır.
Tcrosley’in dediği gibi SPI, I2C’den çok daha yüksek bir frekansta çalışabilir.
I2C biraz daha karmaşık. Bir veri yolu olduğundan, aygıtları ele almak için bir yol gerekir. İletişiminiz benzersiz bir başlatma dizisiyle başlar: saat (SCL) yüksekken veri hattı (SDA) aşağı çekilir, çünkü iletişim verilerinin geri kalanının yalnızca saat düşük olduğunda değişmesine izin verilir. Bu başlangıç sırası her iletişimi senkronize eder.
İletişim adreslemeyi içerdiğinden, herhangi bir sayıdaki cihaz için sadece iki hat gerekir (en fazla 127).
düzenleme
Veri hattının çift yönlü olduğu açıktır, ancak bunun saat satırı için de geçerli olduğunu belirtmekte fayda vardır. Slave'ler bus hızını kontrol etmek için saati uzatabilir . Bu, I2C'yi seviye değişimi veya tamponlama için daha az uygun hale getirir. (Standart modda SPI satırlarının tümü tek yönlüdür.)
Her bayt (adres veya veri) gönderildikten sonra, alıcı SDA'ya bir onaylama nabzı koyarak makbuzu onaylamalıdır. Mikrodenetleyiciniz bir I2C arayüzüne sahipse, bu otomatik olarak halledilir. Mikrodenetleyiciniz desteklemiyorsa, hala bit-bang yapabilirsiniz, ancak okumak için bir G / Ç pimi kullanmıyorsanız, her onaylama veya okuma verisi için G / Ç pimini çıktıdan girişe çevirmeniz gerekir. yazmak için bir tane.
400kHz'de standart I2C, SPI'dan çok daha yavaştır. 20 MHz SPI'dan çok daha yavaş, 1 MHz'de çalışan yüksek hızlı I2C cihazları var.
(düzenleme: Açıkçası, aşağıdaki kaygılardan birçoğunun, Olin'in doğru şekilde işaret ettiği gibi I2C / SPI cihazlarının kart-kart kullanımından kaynaklanan sinyal bütünlüğü ile ilgisi vardır.)
Sizi daha az kabloya doğru zorlayan kısıtlamalarınız olmadığı sürece (her ek temasın oldukça pahalı olduğu hermetik olarak kapatılmış bir konektörü olan bir projemiz vardı), mümkün olduğunda I2C'den kaçının ve SPI'ye bağlı kalın.
SPI, bir donanım ve yazılım temelinde başa çıkmak için oldukça kolaydır. Donanımda iki paylaşılan veri hattı vardır: Master tarafından oluşturulan paylaşılan bir saat Master In Slave Out (MISO veya SOMI) ve Master Out Slave In (MOSI veya SIMO) ve cihaz başına bir yonga seçimi. CS hattı alçalır, saat döner ve esasen giriş bitlerinde kayar ve işlem bitene kadar CS hattının yüksek olduğu noktada çıkış bitlerini kaydırır. CS çizgileri yüksek olduğunda, bağımlı cihazlar iletişim kurmaz: CLK ve MOSI hatlarını yok sayarlar ve MISO pimlerini başkalarının kullanmasına izin vermek için yüksek empedanslı bir duruma getirirler.
Birkaç SPI cihazı kullanan bir mikrodenetleyiciniz varsa ve yerleşik bir SPI çevre birimine sahipse, mikrodenetleyicinin CS çıkışını bir ayırıcıya (örneğin 74HC138) gönderin ve SPI işlemleri arasında aygıtı seçmek için adres satırlarını kontrol edin; Bir sicile çıktılarını sıraya koymak için sözcükler yazarsınız ve CS pimi yükseltildikten sonra tekrar okursunuz.
SPI sinyallerinin hepsi tek yönlü olduğundan, bunlar tamponlanabilir, dijital izolatörlü bir izolasyon bariyeri boyunca kullanılabilir ve LVDS gibi hat sürücüleri kullanılarak panodan panoya gönderilebilir. Endişelenmeniz gereken tek şey, maksimum sıklığınızı sınırlayacak gidiş dönüş yayılma gecikmesidir.
I2C tamamen farklı bir hikaye. Bir kablolama noktasından çok daha basit olmasına rağmen, sadece iki telli SCL ve SDA ile, her iki hat da harici çekmeli açık tahliye cihazları kullanan iki yönlü hatlardır. I2C için bir cihaz adresi ileterek başlayan bir protokol vardır, böylece her biri kendi adresine sahipse birden fazla cihaz kullanılabilir.
Bir donanım açısından, I2C'yi önemli gürültü yapan sistemlerde kullanmak çok zordur. I2C hatlarını tamponlamak veya izole etmek için egzotik IC'lere başvurmanız gerekir - evet, varlar, ama çok fazla değiliz: tek bir projede kullandık ve tek bir izolatör kullanabileceğinizi anladınız ama seri olarak iki tane kullan - hangi tarafın işlerin sonu olduğuna karar vermek için küçük voltaj düşüşleri kullandı ve iki seri düşüş iki tane oldu.
I2C'nin mantık seviyesi eşikleri Vcc'ye bağlıdır, bu nedenle aynı sistemde 3V / 3.3V ve 5V cihazları kullanıyorsanız gerçekten dikkatli olmalısınız.
Bir ya da iki ayaktan daha büyük bir kablo kullanan herhangi bir sinyal, kablo kapasitansı için endişelenmelidir. 100pf / meter kapasitansı çok iletkenli kablo için sıra dışı değildir. Bu, ekstra kapasitansı doğru bir şekilde ele alabilmeniz ve yükselme süresi gereksinimlerini karşılayabilmeniz için otobüsü yavaşlatmanız veya daha düşük çekme dirençleri kullanmanıza neden olur.
Diyelim ki iyi tasarladığınızı düşündüğünüz bir sisteminiz var ve sinyal bütünlüğü sorunlarının çoğuyla başa çıkabilirsiniz ve gürültü nadirdir (ancak hala mevcut). Endişelenecek neyin var?
Başa çıkmanız gereken bir sürü hata koşulu var:
Slave cihazı belirli bir baytı onaylamaz. Bunu algılamanız ve iletişim sırasını durdurup yeniden başlatmanız gerekir. (SPI ile, hatasız alındığından emin olmak istiyorsanız, genellikle gönderdiğiniz verileri okuyabilirsiniz.)
Bir köle cihazından bir veri baytı okuyorsunuz ve cihaz saat satırındaki gürültü nedeniyle "hipnotize" ediyor: o baytı okumak için gerekli 8 saati gönderdiniz, ancak gürültü nedeniyle köle cihazı onu düşünüyor 7 saat aldı ve veri hattında hala 0 iletiyor. Cihaz 8. saati almış olsaydı, veri hattını yüksek olacaktı, böylece ana bir ACK ya da NACK bitini iletmek için ana veri hattını kaldırabilir ya da indirdi ya da ana bir durma (P) koşulu iletebilirdi. Ancak, köle hala veri hattını düşük tutuyor, boş bir zaman için boşuna bekliyor. Bir master ekstra saatler denemek için hazır değilse, I2C veriyolu kilitlenmeye sıkışmış olacaktır. Normal ACK / NACK koşullarını işleyen birkaç mikrodenetleyici kullanmış olmama rağmen,
Gerçekten çok kötü olan bir durum, bir ana cihazın bir ikincil cihaza veri yazması ve bir başka kölen cihazın adresini yanlış yorumlaması ve iletilen verinin bunun için olduğunu düşünmesidir. Bu nedenle, zaman zaman yanlış ayarlanan kayıtlara sahip olan I2C cihazlarımız (G / Ç genişleticileri) vardı. Bu vakayı tespit etmek ve gürültüye dayanıklı olmak neredeyse imkansızdır, tüm kayıtları düzenli aralıklarla ayarlamanız gerekir, böylece bu hatayla karşılaşırsanız en azından kısa bir süre sonra düzeltilecektir. (SPI hiçbir zaman bu problemi yaşamaz - CS hattında bir aksaklık olursa, uzun süre kalıcı olmaz ve yanlışlıkla yanlış bağımlı cihaz tarafından okunan verileri alamazsınız.)
Hata tespiti (CRC kodları) olsaydı, protokolde bu koşulların birçoğu uygun şekilde ele alınabilirdi, ancak çok az sayıda cihaz buna sahipti.
Bu koşulları yerine getirmek için I2C ana cihazımda karmaşık bir yazılım geliştirmem gerektiğini düşünüyorum. Bana göre, kablolamadaki kısıtlamalar bizi I2C kullanmaya ve SPI kullanmaya zorlamadıkça, buna değmez.
SparkFun'daki cihaz için ana kart aslında sadece I2C versiyonu içindir (MPU-6500). MPU-6000 sürümü aynı çip üzerinde hem SPI hem de I2C arayüzüne sahiptir ve SparkFun'un bu çipli bir anakartı olduğunu görmüyorum. Bu nedenle, söz konusu tahtayı kullanmak istiyorsanız, I2C kullanmakla sınırlı olduğunuza inanıyorum. Ancak aşağıdaki nedenlerden dolayı durumunuzda I2C'yi kullanmanızı tavsiye edecektim.
Genel olarak, I2C veri yolunun donanım açısından SPI veri yolundan daha kolay olduğunu göreceksiniz. I2C 2 kablolu bir veriyolu (SCL / SDA):
SCL – Serial clock.
SDA – Serial data (bidirectional).
SPI 4 kablolu bir otobüsdür (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.
Bir I2C veriyoluna bağlı birkaç cihazınız olabilir. Her cihazın yongada yerleşik kendi adresi vardır. Adres aslında veri yolu üzerinden her komutun ilk baytı olarak yayınlanır (bir okuma / yazma biti ile birlikte). Bu, diğer bazı ek yüklerle birlikte, aynı işlevsellik için I2C veriyoluna karşı SPI gönderilmesi için daha fazla bit gerektirir.
Farklı cihaz sınıflarının (bellek, G / Ç, LCD vb.) Farklı adres aralıkları vardır. Genellikle bir sistemde (PCF8574 I / O genişletici gibi) bir kereden fazla kullanılan bazı cihazlar, düşük bitleri belirtmek için yüksek veya düşük olarak bağlanabilen bir veya daha fazla adres satırı (PCF8574 için AD0-2) kullanır. Adresin MPU-6500 böyle bir adres hattına (AD0) sahiptir, bu nedenle ikisi aynı sistemde kullanılabilir.
Ayrıca bir SPI veriyolunda birden fazla cihazınız olabilir, ancak her cihazın kendi yonga seçimi (CS) hattına sahip olması gerekir. Bu nedenle, 4 telli açıklama bir yanlış adreste bir parçadır - gerçekten üç telli bir arayüz + cihaz başına bir ek teldir. Arduino serisi anakartlar konusunda tecrübeli değilim, ancak bunun Arduino'da SPI kullanmanın daha zor olacağını düşünüyorum, çünkü çok fazla talaş seçme hattı gerekiyorsa, bu, çeşitli kalkanlar tarafından kullanılan genel pin atamaları ile hantallaşmaya başlar. .
Arduino kurullarının çoğunun 5 voltta çalıştığını düşünüyorum, bazılarında da yeniler 3.3v'de çalışıyor. MPU-6500 3.3v'da çalışıyor. Bir 5v işlemcideki I2C veriyolu için minimum "yüksek" gerilim 3V veya daha düşükse, SCL ve SDA hatlarında 10K'lık çekme dirençleri 3.3V'a kadar veri yolu açık olduğundan, seviye dönüştürme sorunlarından kaçınabilirsiniz. kolektör. Bir CPU üzerindeki 5v dahili çekimlerin devre dışı bırakıldığından emin olun.
Ancak ATmega2560 için veri sayfasını kontrol ettim (örnek olarak ADK 5v Arduino'yu kullanarak) ve minimum 'yüksek "voltaj girişi, 3.3v'den daha büyük olan 0.7 * Vcc veya 3.5v'dir. Dönüştürme Çipin hem 5v hem de 3.3v taraflarında çekme dirençleri gerektiren TI PCA9306 , tek miktarlarda sadece 78 kuruşa mal oluyor.
Neden o zaman I2C üzerinden SPI'yi seçtiniz? Temelde, SPI'nin çok daha hızlı çalışabilmesi nedeniyle - bazı durumlarda 10 MHz'e kadar. I2C genellikle 400 KHz ile sınırlıdır. Ancak bu gerçekten MPU-6050/6000 ivmeölçer için bir sorun değil, çünkü I2C için 400 KHz'de ve SPI için sadece 1 MHz'de çalışıyor - fark bu kadar değil.
Genel olarak, SPI daha hızlı bir veriyoludur - saat frekansı MHz aralığında olabilir. Bununla birlikte, SPI iki yönlü iletişim için en az 3 hat ve veri yolu üzerindeki her cihaz için ek bir slave seçimi gerektirir.
I2C, kaç tane cihaza sahip olduğunuza bakmaksızın (tabii ki limitler dahilinde) sadece 2 hat gerektirir. Bununla birlikte, hız kHz aralığındadır (100-400kHz tipik).
Günümüzde çoğu mikrodenetleyici her iki veri yolu için donanım desteğine sahiptir, bu yüzden her ikisi de kullanımı aynı derecede kolaydır.
I2C is designed for on-board applications.
- Görünüşe göre I2C cihaz üreticileri size katılmıyor. TMP100'ü alın . Ürün sayfasında açıkça belirtildiği gibi: The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
Aynı TMP75
SPI, I2C'den çok daha hızlı çalıştırılabilir (bazı SPI aygıtları 60MHz'in üzerindedir; "resmi" I2C spesifikasyonunun 1MHz'in üzerindeki aygıtlara izin verip vermediğini bilmiyorum). Her iki protokolü kullanarak bir ikincil cihazın uygulanması donanım desteği gerektirirken, her ikisi de "yazılım bit-bang" ustalarının kolay uygulanmasını sağlar. Nispeten minimal donanım ile, bir başka el sıkışma tellerine ihtiyaç duymadan, ana bilgisayar bir anda 500us'a kadar veriyolunu görmezden almaya karar verse bile doğru şekilde çalışacak olan I2C uyumlu bir köle inşa edilebilir. Bununla birlikte, güvenilir SPI işlemi, donanım desteği ile bile , genel olarak, birinin bir el sıkışma kablosu eklemesini veya başka bir konağın, kölenin en kötü durum yanıt süresine eşit her bayttan sonra "elle" bir gecikme eklemesini gerektirir.
Eğer dolandırıcılarıma sahip olsaydım, kontrolörlerin SPI desteği, toplam üç tek yönlü kablo kullanarak el sıkışma ve uyandırma yeteneklerine sahip kontrolörler arasında 8 bitlik saydam çift yönlü veri aktarımı sağlamak için birkaç basit ekstra özellik içerirdi (Clock ve MOSI [master] Master'dan-köle-içinde], köle MISO [köle-içinde-master]. Karşılaştırıldığında, "stok" SPI portlu mikrodenetleyiciler arasında verimli ve güvenilir iletişim, her iki işlemcinin keyfi bir süre boyunca bağımsız olarak ertelenebildiği durumlarda, çok daha fazla kablo kullanılmasını gerektirir (Chip-Select, Clock, MISO ve MOSI) artı, köle tarafından bir tür onay teli. Eğer köle eşzamansız olarak gönderilecek veriyi almaya başlayabilirse (örneğin, birisi bir düğmeye bastığından dolayı), biri "uyandırma" olarak başka bir kablo kullanmalıdır.
I2C, "gelişmiş" SPI’mın sahip olabileceği tüm yetenekleri sağlamaz, ancak SPI’nin sahip olmadığı yerleşik el sıkışma yetenekleri sunar ve çoğu uygulamada, usta bir yazılım bit-bang. İşlemciler arası iletişim için, SPI'nın sağlayabileceğinden daha yüksek hızlara ihtiyaç duyulması ve fazladan pin kullanımı kabul edilebilir olmadıkça, SPI üzerinden I2C'yi şiddetle tavsiye ederim. Düşük pin sayısının gerekli olduğu işlemciler arası iletişim için, UART'lerin bunları önerecek çok şeyi var.
Bu soru, buradaki mükemmel cevaplarda detaylı bir şekilde incelenmiştir, ancak belki de bir çip üreticisinin bakış açısından sunabileceğim I 2 C'ye bir bakış açısı daha var.
I 2 C'nin elektrik arayüzü açık bir kollektördür . Şimdi nefes al ve sonuçları düşün. I 2 C kullanarak , bus çalışma voltajına tamamen agnostik bir çip tasarlayabilirim. Yapmam gereken tek şey, eğer beni memnun ederse, SDA hattını düşük seviyeye çekmek ve SCL ve SDA'nın voltajlarını seçebileceğim yer referanslı bir eşik voltajıyla karşılaştırmak. Ve normal yüksek yan koruma yapılarını dışarıda bırakırsam ve onları diğer yapılarla değiştirirsem, sistemin geri kalanından bağımsız olarak kendi hayatını tamamen yaşayabilecek bir çip yapabilirim - SCL, SDA hiçbir zaman çipime ve herhangi bir akımı beslemiyor. kesinlikle bu pinlere akım beslemeyecek. Bu yüzden gerçek zamanlı saatler ve bunun gibi düşük güç tüketen diğer şeyler için böyle güzel bir otobüs.
Diğer cevaplarda bahsetmediğim bir şey de, I2C'nin aynı veri yolu üzerindeki çoklu ustaları desteklemesidir. İki yönlü iletişime ihtiyacınız varsa ve yoklama tabanlı bir yöntem kullanmak istemiyorsanız, I2C işi halleder.
Uzun mesafelerde, CAN aynı kapasiteye sahiptir ve daha sağlamdır. Ancak CAN, donanım desteği ve bir alıcı-verici gerektiren bir asenkronize bir protokoldür, bu nedenle düşük maliyetli bir sistemde bir seçenek olmayabilir.
SPI protokolünü kullanın ve senkronizasyon saati yükselirken bitlerinizi doğrudan cihaza yazın. Xnor mantık devresi, istenen cihazı bir i2c cihazmış gibi seçmek için bellekteki "ev yapımı" adresiyle eşleştirmek için kullanılabilir.
İ2c, otorite devresini cihazın formatına entegre eder, standart ... vb. Karmaşık ve farklıdır, bir spi ile bir videoyu ekranda göstermek için bir spi belleği kullanabilirsiniz, ancak i2c'yi değil.