Jakie kompromisy należy wziąć pod uwagę, decydując się na interfejs SPI lub I2C?
Ta tablica akcelerometru / żyroskopu jest dostępna w dwóch modelach, po jednym dla każdego interfejsu. Czy jedno z nich byłoby łatwiejsze do zintegrowania z projektem Arduino?
Odpowiedzi:
Podsumowanie
I2C to system magistrali z dwukierunkowymi danymi na linii SDA. SPI to połączenie typu punkt-punkt z danymi wchodzącymi i wychodzącymi na osobnych liniach (MOSI i MISO).
Zasadniczo SPI składa się z pary rejestrów przesuwnych, w których dane są rejestrowane w jednym rejestrze przesuwnym, a dane w drugim. Zwykle dane zapisywane są w bajtach, za każdym razem po 8 impulsów zegara, ale nie jest to wymóg SPI. Możesz także mieć długość słowa 16 bitów, a nawet 13 bitów, jeśli chcesz. Podczas gdy w I2C synchronizacja odbywa się poprzez sekwencję startową w SPI, robi się to przez SS idące w górę (SS jest aktywne w stanie niskim). Sam decydujesz po ilu impulsach zegara. Jeśli użyjesz 13 bitowych słów, SS zatrzaśnie ostatni taktowany bitami po 13 impulsach zegarowych.
Ponieważ dane dwukierunkowe znajdują się w dwóch osobnych wierszach, interfejs jest łatwy do skonfigurowania.
SPI w trybie standardowym wymaga co najmniej czterech linii: SCLK (zegar szeregowy), MOSI (Master Out Slave In), MISO (Master In Slave Out) i SS (Slave Select). W trybie dwuwymiarowym potrzebne są co najmniej trzy linie: SCLK (zegar szeregowy), MIMO (Master In Master Out), która jest jedną z linii MOSI lub MISO i SS (Slave Select). W systemach z więcej niż jednym urządzeniem podrzędnym potrzebna jest linia SS dla każdego urządzenia podrzędnego, aby dla podrzędnych było linie w trybie standardowym i linie w trybie dwukierunkowym. Jeśli nie chcesz tego, w trybie standardowym możesz połączyć łańcuchowo urządzenia slave, podłączając sygnał MOSI jednego urządzenia podrzędnego do MISO następnego. Spowolni to komunikację, ponieważ musisz przełączać wszystkie dane slave.N + 3 N + 2N N+3 N+2
Jak twierdzi tcrosley, SPI może działać na znacznie wyższej częstotliwości niż I2C.
I2C jest nieco bardziej skomplikowany. Ponieważ jest to autobus, potrzebujesz sposobu na adresowanie urządzeń. Twoja komunikacja rozpoczyna się od unikalnej sekwencji początkowej: linia danych (SDA) jest ciągnięta nisko, podczas gdy zegar (SCL) jest wysoki, ponieważ reszta danych komunikacyjnych może się zmieniać tylko wtedy, gdy zegar jest niski. Ta sekwencja startowa synchronizuje każdą komunikację.
Ponieważ komunikacja obejmuje adresowanie, tylko dwie linie są wymagane dla dowolnej liczby urządzeń (do 127).
Po wysłaniu każdego bajtu (adresu lub danych) odbiornik musi potwierdzić odbiór poprzez umieszczenie impulsu potwierdzającego na SDA. Jeśli twój mikrokontroler ma interfejs I2C, zostanie to automatycznie załatwione. Nadal możesz go bit-bang, jeśli twój mikrokontroler go nie obsługuje, ale będziesz musiał przełączyć pin we / wy z wyjścia na wejście dla każdego potwierdzenia lub odczytu danych, chyba że używasz pinu we / wy do odczytu i jeden do pisania.
Przy 400 kHz standardowy I2C jest znacznie wolniejszy niż SPI. Istnieją szybkie urządzenia I2C, które działają z częstotliwością 1 MHz, wciąż znacznie wolniej niż SPI 20 MHz.
źródło
(edytuj: Żeby było jasne, wiele z poniższych obaw dotyczy integralności sygnału spowodowanej używaniem urządzeń I2C / SPI z płyty na płytę, jak słusznie zauważa Olin).
O ile nie masz ograniczeń, które silnie popychają cię w kierunku mniejszej liczby przewodów (mieliśmy jeden projekt z hermetycznie zamkniętym złączem, że każdy dodatkowy styk był dość drogi), unikaj I2C, jeśli to możliwe, i trzymaj się SPI.
SPI jest dość łatwe w obsłudze pod względem sprzętowym i programowym. W sprzęcie istnieją dwie współdzielone linie danych: Master In Slave Out (MISO lub SOMI) i Master Out Slave In (MOSI lub SIMO), wspólny zegar generowany przez urządzenie master i jeden układ na urządzenie. Linia CS przechodzi w stan niski, zegar cyklicznie i zasadniczo przesuwa bity wejściowe i przesuwa bity wyjściowe, aż do zakończenia transakcji, w którym to momencie linia CS przechodzi w stan wysoki. Gdy ich linia CS jest wysoka, urządzenia podrzędne nie komunikują się: ignorują linie CLK i MOSI i ustawiają pin MISO w stan wysokiej impedancji, aby pozwolić komuś innemu z niego korzystać.
Jeśli masz mikrokontroler korzystający z kilku urządzeń SPI i ma on wbudowane urządzenie peryferyjne SPI, wyślij wyjście CS mikrokontrolera do demultipleksera (np. 74HC138) i kontroluj linie adresowe, aby wybrać urządzenie między transakcjami SPI; piszesz słowa do rejestru, aby umieścić je w kolejce do wyjścia, i odczytujesz je po podniesieniu szpilki CS.
Ponieważ wszystkie sygnały SPI są jednokierunkowe, mogą być buforowane, używane przez barierę izolacyjną z cyfrowymi izolatorami i mogą być przesyłane z płyty na kartę za pomocą sterowników liniowych, takich jak LVDS. Jedyne, o co musisz się martwić, to opóźnienie propagacji w obie strony, które ograniczy Twoją maksymalną częstotliwość.
I2C to zupełnie inna historia. O ile jest to znacznie prostsze z punktu widzenia okablowania, z tylko dwoma przewodami SCL i SDA, obie te linie są wspólnymi liniami dwukierunkowymi, które wykorzystują urządzenia typu open-drain z zewnętrznym podciąganiem. Istnieje protokół dla I2C, który zaczyna się od przesłania adresu urządzenia, dzięki czemu można używać wielu urządzeń, jeśli każde ma własny adres.
Z punktu widzenia sprzętowego bardzo trudno jest używać I2C w systemach, w których występuje znaczny hałas. Aby buforować lub izolować linie I2C, musisz uciekać się do egzotycznych układów scalonych - tak, istnieją, ale nie ma ich wielu: wykorzystaliśmy jeden na jeden projekt i zdaliśmy sobie sprawę, że możesz użyć jednego izolatora, ale nie możesz użyj dwóch w szeregu - użył małych spadków napięcia, aby dowiedzieć się, po której stronie był napędzający koniec rzeczy, a dwa szeregi spadły o dwa razy.
Progi poziomu logicznego I2C zależą od Vcc, więc musisz być bardzo ostrożny, jeśli używasz urządzeń 3 V / 3,3 V i 5 V w tym samym systemie.
Wszelkie sygnały korzystające z kabla dłuższego niż dwa lub dwa stopy muszą martwić się o pojemność kabla. Pojemność 100pf / metr nie jest niczym niezwykłym w przypadku kabla wielożyłowego. Powoduje to, że musisz spowolnić magistralę lub użyć niższych rezystorów podciągających, aby móc odpowiednio obsłużyć dodatkową pojemność i spełnić wymagania dotyczące czasu narastania.
Powiedzmy, że masz system, który Twoim zdaniem dobrze zaprojektowałeś i możesz poradzić sobie z większością problemów z integralnością sygnału, a szum jest rzadki (ale nadal obecny). O co musisz się martwić?
Istnieje kilka warunków błędów, które należy przygotować:
Urządzenie podrzędne nie potwierdza określonego bajtu. Musisz to wykryć, zatrzymać i ponownie uruchomić sekwencję komunikacji. (Dzięki SPI zwykle możesz odczytać przesłane dane, jeśli chcesz mieć pewność, że zostały one odebrane bez błędów).
Odczytujesz bajt danych z urządzenia podrzędnego, a urządzenie jest „zahipnotyzowane” z powodu szumu na linii zegara: Wysłano wymagane 8 zegarów, aby odczytać ten bajt, ale z powodu szumu urządzenie podrzędne uważa, że to odebrał 7 zegarów i nadal przesyła zero na linii danych. Gdyby urządzenie otrzymało ósmy zegar, zwolniłoby linię danych wysoko, aby master mógł podnieść lub obniżyć linię danych, aby przesłać bit ACK lub NACK, lub master mógłby przesłać warunek zatrzymania (P). Ale slave wciąż utrzymuje linię danych na niskim poziomie, na próżno czekając na kolejny zegar. Jeśli urządzenie nadrzędne nie jest przygotowane do wypróbowania dodatkowych zegarów, magistrala I2C utknie w martwym punkcie. Chociaż użyłem kilku mikrokontrolerów, które obsługują normalne warunki ACK / NACK,
Naprawdę okropny jest przypadek, gdy master zapisuje dane do jednego urządzenia slave, a inny slave nieprawidłowo interpretuje adres urządzenia i uważa, że przesyłane dane są do niego przeznaczone. Mieliśmy urządzenia I2C (ekspandery I / O), które czasami mają niepoprawnie ustawione rejestry z tego powodu. Wykrywanie tego przypadku jest prawie niemożliwe, a aby być odpornym na zakłócenia, należy okresowo ustawiać wszystkie rejestry, aby jeśli wystąpił ten błąd, przynajmniej zostanie on naprawiony po krótkim czasie. (SPI nigdy nie ma tego problemu - jeśli zdarzy się, że masz usterkę w linii CS, to nigdy nie utrzyma się długo i nie dostaniesz danych przypadkowo odczytanych przez niewłaściwe urządzenie podrzędne.)
Wiele z tych warunków można by poprawnie obsłużyć w protokole, gdyby wykryto błąd (kody CRC), ale ma to kilka urządzeń.
Uważam, że muszę zbudować złożone oprogramowanie w moim urządzeniu głównym I2C, aby poradzić sobie z tymi warunkami. Moim zdaniem po prostu nie warto, chyba że ograniczenia okablowania zmuszają nas do używania I2C, a nie SPI.
źródło
Płyta Breakout dla urządzenia w SparkFun jest w rzeczywistości tylko dla wersji I2C (MPU-6500). Wersja MPU-6000 ma interfejsy SPI i I2C na tym samym układzie i nie widzę, że SparkFun ma płytkę z tym układem. Więc uważam, że jesteś ograniczony do używania I2C, jeśli chcesz korzystać z tej konkretnej płyty. Ale i tak zamierzam zalecać używanie I2C w twojej sytuacji z następujących powodów.
Ogólnie rzecz biorąc, przekonasz się, że magistrala I2C jest łatwiejsza w użyciu ze sprzętowego punktu widzenia niż magistrala SPI. I2C to 2-przewodowa magistrala (SCL / SDA):
SPI to czteroprzewodowa magistrala (SCLK / MOSI / MISO / CS):
Możesz mieć kilka urządzeń podłączonych do jednej magistrali I2C. Każde urządzenie ma własny zestaw adresów wbudowany w mikroukład. Adres jest faktycznie rozgłaszany przez magistralę jako pierwszy bajt każdego polecenia (wraz z bitem odczytu / zapisu). To, wraz z niektórymi innymi kosztami, wymaga wysłania większej liczby bitów przez magistralę I2C w porównaniu z SPI dla tej samej funkcjonalności.
Różne klasy urządzeń (pamięć, I / O, LCD itp.) Mają różne zakresy adresów. Niektóre urządzenia, które są często używane więcej niż jeden raz w systemie (takie jak ekspander we / wy PCF8574), używają jednej lub więcej linii adresowych (AD0-2 dla PCF8574), które można powiązać z wartością wysoką lub niską w celu określenia niskich bitów adresu. MPU-6500 ma jedną taką linię adresu (AD0), więc dwie z nich mogą być używane w tym samym systemie.
Możesz także mieć wiele urządzeń na magistrali SPI, ale każde urządzenie musi mieć własną linię wyboru chipów (CS). Dlatego opis 4-żyłowy jest trochę mylący - tak naprawdę jest to interfejs trzyprzewodowy + jeden dodatkowy przewód na urządzenie. Nie mam doświadczenia z serią tablic Arduino, ale wierzę, że utrudniłoby to używanie SPI na Arduino, ponieważ gdybyś potrzebował wielu linii wyboru chipów, zaczynałoby się to nieporęczne z powodu wspólnych przypisań pinów używanych przez różne osłony .
Wierzę, że większość płyt Arduino działa przy napięciu 5 woltów, a niektóre nowsze na 3,3 V. MPU-6500 działa na 3,3 V. Jeśli minimalne „wysokie” napięcie wejściowe dla magistrali I2C na procesorze 5 V wynosi 3 V lub mniej, można uniknąć problemów z konwersją poziomu, po prostu zapewniając rezystory podciągające 10 K do 3,3 V na liniach SCL i SDA, ponieważ magistrala jest otwarta - kolektor. Upewnij się, że wszelkie wewnętrzne podciągnięcia 5 V na procesorze są wyłączone.
Jednak sprawdziłem arkusz danych dla ATmega2560 (na przykładzie ADK 5v Arduino), a jego minimalne napięcie wejściowe „wysokie” wynosi 0,7 * Vcc lub 3,5 V, które jest większe niż 3,3 V. Tak więc potrzebujesz jakiegoś aktywnego poziomu konwersja TI PCA9306 , który wymaga rezystorów podciągających zarówno po stronie 5 V, jak i 3,3 V układu, kosztuje zaledwie 78 centów w pojedynczych ilościach.
Dlaczego więc kiedykolwiek wybrałeś SPI zamiast I2C? Głównie dlatego, że SPI może działać znacznie szybciej - w niektórych przypadkach do wielu 10 MHz. I2C jest ogólnie ograniczony do 400 kHz. Ale tak naprawdę nie stanowi to problemu w przypadku akcelerometru MPU-6050/6000, ponieważ działa on z częstotliwością 400 KHz dla I2C i tylko 1 MHz dla SPI - nie jest to duża różnica.
źródło
Ogólnie SPI jest szybszą magistralą - częstotliwość zegara może mieścić się w zakresie MHz. Jednak SPI wymaga co najmniej 3 linii do komunikacji dwukierunkowej i dodatkowego wyboru urządzenia podrzędnego dla każdego urządzenia w magistrali.
I2C wymaga tylko 2 linii, niezależnie od tego, ile masz urządzeń (oczywiście w określonych granicach). Prędkość mieści się jednak w zakresie kHz (typowo 100–400 kHz).
Obecnie większość mikrokontrolerów ma wsparcie sprzętowe dla obu magistral, więc oba są równie proste w użyciu.
źródło
I2C is designed for on-board applications.
- Najwyraźniej producenci urządzeń I2C nie zgadzają się z tobą. Weź TMP100 . Strona produktu wyraźnie stwierdza:The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.
to samo dotyczy TMP75SPI można uruchomić znacznie szybciej niż I2C (niektóre urządzenia SPI przekraczają 60 MHz; nie wiem, czy „oficjalna” specyfikacja I2C zezwala na urządzenia powyżej 1 MHz). Implementacja urządzenia podrzędnego za pomocą dowolnego protokołu wymaga wsparcia sprzętowego, a oba umożliwiają łatwą implementację wzorców „oprogramowania bit-bang”. Przy względnie minimalnym sprzęcie można zbudować urządzenie podrzędne zgodne z I2C, które będzie działać poprawnie, nawet jeśli host może arbitralnie zdecydować się zignorować magistralę nawet do 500us na raz, bez potrzeby stosowania dodatkowych przewodów uzgadniania. Jednak niezawodne działanie SPI, nawet przy wsparciu sprzętowym , zazwyczaj wymaga dodania drutu uścisk dłoni, albo host „ręcznie” dodaje opóźnienie po każdym bajcie równe najgorszemu czasowi reakcji urządzenia podrzędnego.
Gdybym miał moje druty, obsługa SPI kontrolerów zawierałaby kilka prostych dodatkowych funkcji zapewniających 8-bitowy, dwukierunkowy dwukierunkowy transfer danych między kontrolerami z możliwością uzgadniania i budzenia, przy użyciu łącznie trzech przewodów jednokierunkowych (Clock i MOSI [master -out-slave-in] od master; MISO [master-in-slave-out] od slave). Dla porównania, wydajna i niezawodna komunikacja między mikrokontrolerami z „zapasowymi” portami SPI, kiedy oba procesory mogą być niezależnie opóźnione o dowolnie długi czas, wymaga użycia znacznie większej liczby przewodów (Chip-Select, Clock, MISO i MOSI do uruchomienia z, plus jakiś rodzaj potwierdzenia z urządzenia podrzędnego. Jeśli urządzenie podrzędne może asynchronicznie zacząć mieć dane do wysłania (np. ponieważ ktoś nacisnął przycisk), należy albo użyć innego przewodu jako „wybudzanie”
I2C nie zapewnia wszystkich możliwości, jakie posiadałby mój „ulepszony” SPI, ale oferuje wbudowane możliwości uzgadniania, których brakuje w SPI, aw wielu implementacjach można go również zakłócać, aby zapewnić budzenie, nawet jeśli master jest oprogramowanie bit-bang. W przypadku komunikacji między procesorami zdecydowanie zaleciłbym I2C zamiast SPI, chyba że potrzebne są wyższe prędkości niż SPI może dostarczyć, a użycie dodatkowych pinów jest dopuszczalne. Do komunikacji między procesorami, gdzie potrzebna jest niska liczba pinów, UART mają wiele do ich polecania.
źródło
To pytanie zostało dokładnie zbadane w doskonałych odpowiedziach tutaj, ale być może jest jeszcze jeden punkt widzenia dla I 2 C, który mógłbym zaoferować z punktu widzenia twórcy układów.
Interfejs elektryczny I 2 C to otwarty kolektor . Teraz oddychaj i pomyśl o implikacjach. Korzystając z I 2 C, mogę zaprojektować układ, który jest całkowicie niezależny od napięcia roboczego magistrali. Wszystko, co muszę zrobić, to obniżyć linię SDA, jeśli mi się to podoba, i porównać napięcia SCL i SDA z niektórymi napięciami progowymi, które mogę wybrać. A jeśli pominę normalne konstrukcje zabezpieczające po stronie wysokiego poziomu i zastąpię je innymi konstrukcjami, mogę stworzyć układ, który może całkowicie żyć własnym życiem, niezależnie od reszty systemu - SCL, SDA nigdy nie dostarcza prądu do mojego układu, a ja na pewno nie doprowadzi prądu do tych pinów. Dlatego jest to tak fajny autobus do zegarów czasu rzeczywistego i innych podobnych rzeczy o niskiej mocy.
źródło
Jednej rzeczy, o której nie wspomniałem w innych odpowiedziach, jest to, że I2C obsługuje wiele masterów na tej samej magistrali. Jeśli potrzebujesz komunikacji dwukierunkowej i nie chcesz używać metody opartej na sondowaniu, I2C wykona zadanie.
Na dłuższych dystansach CAN ma te same możliwości i jest bardziej wytrzymały. Ale CAN to protokół asynchroniczny, który wymaga wsparcia sprzętowego i urządzenia nadawczo-odbiorczego, więc może nie być opcją w niedrogim systemie.
źródło
Użyj protokołu SPI i zapisz swoje bity bezpośrednio do urządzenia, gdy podnosi się zegar synchronizacji. Obwód logiczny xnor może być użyty do dopasowania „domowego” adresu z pamięci, aby wybrać żądane urządzenie tak, jakby to było urządzenie i2c.
I2c integruje autorski obwód w formacie urządzenia, standardowe ... itd. Są złożone i różne, dzięki spi możesz użyć pamięci spi do wyświetlenia wideo na ekranie, ale nie i2c.
źródło