Pengorbanan saat mempertimbangkan SPI atau I2C?

117

Pengorbanan apa yang harus saya pertimbangkan ketika memutuskan untuk menggunakan antarmuka SPI atau I2C?

Papan breakout accelerometer / gyro ini tersedia dalam dua model, satu untuk setiap antarmuka. Apakah salah satu lebih mudah untuk diintegrasikan ke dalam proyek Arduino?

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

masukkan deskripsi gambar di sini

Mark Harrison
sumber
13
I2C dan SPI memiliki kekuatan mereka. I2C lebih rumit untuk diatur, setelah stabil Anda dapat dengan mudah memperpanjang (selama kabel bus Anda tidak terlalu panjang atau besar). SPI mudah diatur. Anda dapat bitbang dengan sangat mudah jika diperlukan. Ekspansi memakan I / O dengan semua chip yang dipilih. Jika saya memiliki kemewahan I / O dan ruang konektor dan tidak perlu bus, saya akan selalu pergi dengan SPI.
Hans
Bagaimana I2C lebih kompleks? Saya telah menggunakan kedua bus pada micros yang berbeda (PIC kecil dan ukuran ARM yang layak) dan dalam setiap kasus setup I2C lebih sederhana (mis. Register yang lebih sedikit untuk ditulis). Jika ada, SPI lebih kompleks karena polaritas jam dan opsi pengambilan sampel data.
Armandas
6
@Armanda - tidak mungkin! SPI memiliki 4 mode yang memungkinkan untuk polaritas jam / data, dan dua di antaranya mendominasi - hampir semua perangkat SPI memperbarui output MISO mereka di tepi jatuh jam dan membaca input MOSI mereka di tepi naik jam. Anda bisa mencari tahu yang mana dalam beberapa menit dengan melihat lembar data, dan kemudian selesai. Jika Anda memilih mode yang salah karena kesalahan, Anda akan mengetahuinya dengan cepat begitu Anda melihat jejak osiloskop. Kesalahan data SPI jarang terjadi dan tidak membuat Anda terjebak dalam kondisi aneh seperti yang dilakukan I2C.
Jason S
6
Saya mengatakan I2c jauh lebih kompleks karena saya pernah harus menulis driver I2C di prosesor ARM. Saya mengikuti mesin negara bagian dokumen NXP, dan panjangnya sekitar 20 negara. Butuh waktu yang layak untuk mencari tahu pengakuannya, ketika byte terakhir dibaca / ditulis, dll. Saya tidak pernah mengalami masalah dengan SPI ini, hanya harus mendapatkan jam & data yang ada.
Hans
1
@ Jon, jujur ​​saja, saya satu-satunya yang memberikan jawaban lengkap sejauh ini, karena saya satu-satunya yang membahas masalah papan breakout khusus yang ingin digunakan OP, dan menunjukkan bahwa itu tidak tersedia di baik SPI dan I2C, tetapi hanya I2C - jadi dia harus menggunakan I2C jika dia ingin menggunakan papan khusus ini. Yang lain hanya berurusan dengan antarmuka mana (SPI atau I2C) yang lebih mudah untuk antarmuka, yang juga saya bahas.
tcrosley

Jawaban:

98

Ringkasan

  • SPI lebih cepat.
  • I2C lebih kompleks dan tidak mudah digunakan jika mikrokontroler Anda tidak memiliki pengontrol I2C.
  • I2C hanya membutuhkan 2 baris.

I2C adalah sistem bus dengan data dua arah pada jalur SDA. SPI adalah koneksi point-to-point dengan data masuk dan data keluar pada jalur terpisah (MOSI dan MISO).

Pada dasarnya SPI terdiri dari sepasang register geser, di mana Anda memasukkan data ke satu register geser sementara Anda mengeluarkan data dari yang lain. Biasanya data ditulis dalam byte dengan setiap kali pulsa 8 jam berturut-turut, tapi itu bukan persyaratan SPI. Anda juga dapat memiliki panjang kata 16 bit atau bahkan 13 bit, jika Anda mau. Sementara dalam sinkronisasi I2C dilakukan oleh urutan mulai di SPI itu dilakukan oleh SS menjadi tinggi (SS aktif rendah). Anda memutuskan sendiri setelah berapa jam pulsa ini. Jika Anda menggunakan kata-kata 13 bit, SS akan mengunci yang terakhir di-bit setelah 13 pulsa.
Karena data dua arah ada di dua jalur yang terpisah, mudah untuk dihubungi.

SPI dalam mode standar membutuhkan setidaknya empat baris: SCLK (jam serial), MOSI (Master Out Slave In), MISO (Master In Slave Out) dan SS (Slave Select). Dalam mode bideroctional memerlukan setidaknya tiga baris: SCLK (jam serial), MIMO (Master In Master Out) yang merupakan salah satu jalur MOSI atau MISO dan SS (Slave Select). Dalam sistem dengan lebih dari satu budak, Anda memerlukan garis SS untuk setiap budak, sehingga untuk budak Anda memiliki baris dalam mode standar dan baris dalam mode dua arah. Jika Anda tidak menginginkan itu, dalam mode standar Anda dapat daisy-chain para budak dengan menghubungkan sinyal MOSI satu budak ke MISO berikutnya. Ini akan memperlambat komunikasi karena Anda harus menggilir semua data budak.N + 3 N + 2NN+3N+2

Seperti kata tcrosley, SPI dapat beroperasi pada frekuensi yang jauh lebih tinggi daripada I2C.

I2C sedikit lebih kompleks. Karena ini adalah bus, Anda perlu cara untuk mengatasi perangkat. Komunikasi Anda dimulai dengan urutan awal yang unik: jalur data (SDA) ditarik rendah sementara jam (SCL) tinggi, untuk sisa data komunikasi hanya diperbolehkan untuk berubah ketika jam rendah. Urutan mulai ini menyinkronkan setiap komunikasi.
Karena komunikasi mencakup pengalamatan, maka hanya dua jalur yang diperlukan untuk sejumlah perangkat (hingga 127).

sunting
Sudah jelas bahwa garis data dua arah, tetapi perlu dicatat bahwa ini juga berlaku untuk garis waktu. Budak dapat meregangkan jam untuk mengontrol kecepatan bus. Ini membuat I2C kurang nyaman untuk level-shifting atau buffering. (Garis SPI dalam mode standar semuanya searah.)

Setelah setiap byte (alamat atau data) dikirim, penerima harus mengakui tanda terima dengan menempatkan pulsa yang diakui pada SDA. Jika mikrokontroler Anda memiliki antarmuka I2C ini secara otomatis akan diurus. Anda masih dapat menggigitnya jika mikrokontroler tidak mendukungnya, tetapi Anda harus mengganti pin I / O dari output ke input untuk setiap data yang diakui atau dibaca, kecuali jika Anda menggunakan pin I / O untuk membaca dan satu untuk menulis.

Pada standar 400kHz I2C jauh lebih lambat daripada SPI. Ada perangkat I2C kecepatan tinggi yang beroperasi pada 1MHz, masih jauh lebih lambat dari 20MHz SPI.

stevenvh
sumber
7
Saya belum pernah bertemu mikrokontroler yang menangani semua kasus sudut I2C perlu menangani deteksi kesalahan dan pemulihan dengan cara yang bisa digunakan tanpa harus menjadi ahli I2C. Saya selalu harus mundur dari periferal I2C "pintar" ke bitbanging sementara waktu untuk menangani kasing yang tidak terjawab saat SDA dipegang rendah, yang merupakan rasa sakit total./
Jason S
(Tapi +1 karena saya setuju dengan sisa jawaban Anda)
Jason S
Bahkan ada perangkat I2C yang bekerja pada 3.4MHz, tetapi saya tidak yakin apakah ini dapat dikombinasikan dengan perangkat yang lebih lambat (karena semua perangkat harus dapat mengikuti pengalamatan bus). Saya juga percaya timing dari 3.4MHz I2C sedikit berbeda.
Hans
@Hans - HS I2C tampaknya kompatibel dengan perangkat 400kbit yang lebih umum. Terus terang, (tanpa riset menyeluruh) saya belum pernah melihat mikrokontroler yang mendukung HS (belum), itu sebabnya saya tidak ingin menyebutkannya.
stevenvh
@stevenvh: Implementasi dua-kawat beberapa pengendali (mis. Cypress PSOC) mensyaratkan bahwa SCK rendah untuk setidaknya satu atau dua siklus jam internal sebelum mereka akan mengunci, dan akan berfungsi buruk tidak. Saya tidak tahu mengapa mereka tidak dapat mendeteksi dan memperpanjang kondisi awal I2C tanpa pulsa jam sistem, tetapi perilaku seperti itu berarti bahwa ketika chip seperti itu berjalan pada kecepatan jam sistem yang rendah, semua transaksi I2C di bus harus dijalankan perlahan). Bahkan operasi 400Khz terlalu cepat untuk menjalankan PSOC pada 3MHz.
supercat
39

(sunting: Agar jelas, banyak dari keprihatinan berikut ini berkaitan dengan integritas sinyal yang disebabkan oleh penggunaan perangkat I2C / SPI dari papan ke papan, seperti yang ditunjukkan Olin dengan benar.)

Kecuali Anda memiliki kendala yang sangat mendorong Anda ke arah kabel yang lebih sedikit (kami memiliki satu proyek dengan konektor yang tertutup rapat sehingga setiap kontak tambahan agak mahal), hindari I2C jika memungkinkan, dan tetap menggunakan SPI.

SPI cukup mudah untuk ditangani berdasarkan perangkat keras dan perangkat lunak. Dalam perangkat keras, ada dua jalur data bersama, Master In Slave Out (MISO atau SOMI) dan Master Out Slave In (MOSI atau SIMO), clock bersama yang dihasilkan oleh master, dan satu chip pilih per perangkat. Garis CS menjadi rendah, clock cycle dan pada dasarnya menggeser bit input dan menggeser bit output, sampai transaksi selesai, pada titik mana garis CS menjadi tinggi. Ketika garis CS mereka tinggi, perangkat slave tidak berkomunikasi: mereka mengabaikan garis CLK dan MOSI, dan menempatkan pin MISO mereka ke keadaan impedansi tinggi untuk membiarkan orang lain menggunakannya.

Jika Anda memiliki mikrokontroler menggunakan beberapa perangkat SPI, dan memiliki perangkat SPI bawaan, kirim output CS mikrokontroler ke demultiplexer (mis. 74HC138) dan kendalikan garis alamat untuk memilih perangkat di antara transaksi SPI; Anda menulis kata-kata ke register untuk membuat antrian untuk output, dan membacanya kembali setelah pin CS dinaikkan tinggi.

Karena sinyal SPI semuanya searah, mereka dapat disangga, digunakan melintasi penghalang isolasi dengan isolator digital, dan dapat dikirim dari papan ke papan menggunakan driver garis seperti LVDS. Satu-satunya hal yang harus Anda khawatirkan adalah penundaan propagasi bolak-balik, yang akan membatasi frekuensi maksimum Anda.


I2C adalah cerita yang sangat berbeda. Meskipun jauh lebih sederhana dari sudut pandang pemasangan kabel, dengan hanya dua kabel SCL dan SDA, kedua saluran ini adalah saluran dua arah bersama yang menggunakan perangkat saluran terbuka dengan pullup eksternal. Ada protokol untuk I2C yang dimulai dengan mengirimkan alamat perangkat, sehingga beberapa perangkat dapat digunakan jika masing-masing memiliki alamat mereka sendiri.

Dari sudut pandang perangkat keras, sangat sulit untuk menggunakan I2C dalam sistem yang memiliki noise yang signifikan. Untuk buffer atau mengisolasi jalur I2C, Anda harus menggunakan IC eksotis - ya, mereka ada, tetapi tidak ada banyak: kami menggunakan satu pada satu proyek dan menyadari bahwa Anda bisa menggunakan satu isolator, tetapi Anda tidak bisa gunakan dua seri - menggunakan tetesan voltase kecil untuk mengetahui sisi mana yang menjadi ujung penggerak, dan dua tetes seri dua.

Ambang level logika I2C bergantung pada Vcc sehingga Anda harus sangat berhati-hati jika menggunakan perangkat 3V / 3.3V dan 5V dalam sistem yang sama.

Setiap sinyal yang menggunakan kabel lebih dari satu atau dua kaki harus khawatir tentang kapasitansi kabel. Kapasitansi 100pf / meter tidak biasa untuk kabel multikonduktor. Ini menyebabkan Anda harus memperlambat bus, atau menggunakan resistor pullup yang lebih rendah, untuk dapat menangani kapasitansi tambahan dengan benar dan memenuhi persyaratan waktu naik.

Jadi katakanlah Anda memiliki sistem yang Anda pikir telah Anda rancang dengan baik, dan Anda dapat menangani sebagian besar masalah integritas sinyal, dan kebisingan jarang terjadi (tetapi masih ada). Apa yang harus kamu khawatirkan?

Ada banyak kondisi kesalahan yang harus siap Anda tangani:

  • Perangkat slave tidak mengakui byte tertentu. Anda harus mendeteksi ini dan menghentikan dan memulai kembali urutan komunikasi. (Dengan SPI, Anda biasanya dapat membaca kembali data yang Anda kirim jika Anda ingin memastikan itu diterima tanpa kesalahan.)

  • Anda membaca byte data dari perangkat slave, dan perangkat "terhipnotis" karena noise pada garis jam: Anda telah mengirim 8 jam yang diperlukan untuk membaca byte itu, tetapi karena noise, perangkat slave menganggapnya telah menerima 7 jam, dan masih mentransmisikan 0 pada baris data. Jika perangkat menerima clock ke-8, itu akan melepaskan jalur data tinggi sehingga master dapat menaikkan atau menurunkan jalur data untuk mengirimkan bit ACK atau NACK, atau master dapat mengirimkan kondisi stop (P). Tapi budak itu masih menahan garis data rendah, menunggu sia-sia untuk jam lain. Jika master tidak siap untuk mencoba jam tambahan, bus I2C akan macet. Sementara saya telah menggunakan beberapa mikrokontroler yang menangani kondisi ACK / NACK normal,

  • Kasus yang sangat mengerikan adalah ketika master menulis data ke satu perangkat slave, dan slave lain mengartikan alamat perangkat secara salah dan berpikir bahwa data yang dikirimkan dimaksudkan untuk itu. Kami memiliki perangkat I2C (I / O ekspander) yang terkadang memiliki register yang salah karena hal ini. Hampir tidak mungkin untuk mendeteksi kasus ini, dan agar kuat terhadap noise, Anda harus mengatur semua register secara berkala, sehingga jika Anda mengalami kesalahan ini, setidaknya itu akan diperbaiki setelah periode waktu yang singkat. (SPI tidak pernah memiliki masalah ini - jika Anda memiliki kesalahan pada saluran CS, itu tidak akan pernah bertahan lama dan Anda tidak akan mendapatkan data yang tidak sengaja terbaca oleh perangkat budak yang salah.)

Banyak dari kondisi ini dapat ditangani dengan benar dalam protokol jika ada deteksi kesalahan (kode CRC), tetapi beberapa perangkat memilikinya.


Saya menemukan bahwa saya harus membangun perangkat lunak yang kompleks di perangkat master I2C saya untuk menangani kondisi ini. Menurut pendapat saya, itu tidak layak kecuali kendala pada kabel memaksa kita untuk menggunakan I2C dan bukan SPI.

Jason S
sumber
5
Ketidaksukaan religius Anda terhadap IIC tidak ada artinya di sini. Baik IIC dan SPI baik dalam apa yang mereka lakukan dan masing-masing memiliki tempat masing-masing. Sebagian besar keberatan Anda terhadap IIC berasal dari penggunaannya yang tidak tepat. IIC harus dianggap sebagai on-board saja, meskipun digunakan secara rutin di industri catu daya untuk mengendalikan pasokan cerdas. Jika Anda mendapati diri Anda menginginkan buffer IIC, maka itu indikasi kuat bahwa IIC bukanlah solusi yang tepat. Namun, IIC bekerja sangat baik untuk perangkat kecepatan rendah semua di papan yang sama.
Olin Lathrop
2
Ambang level logika I2C bergantung pada Vcc sehingga Anda harus benar-benar berhati-hati jika menggunakan perangkat 3V / 3.3V dan 5V dalam sistem yang sama . Tidak, ini salah. Ambang logika IIC berada pada tegangan tetap. Anda dapat dengan mudah mencampur sistem 5 V dan 3.3 V dengan menarik garis ke hanya 3.3 V.
Olin Lathrop
5
Ini bukan ketidaksukaan religius terhadap I2C, ini adalah ketidaksukaan praktis terhadap I2C. Anda benar tentang hal itu menjadi lebih mudah dengan sistem on-board; Saya akan menggunakannya ketika itu masuk akal, tetapi itu menambah biaya perangkat lunak, dan terlalu banyak insinyur perangkat keras hanya menempelkan perangkat I2C di papan tanpa mendiskusikan pengorbanan yang menyebabkan lebih banyak sakit kepala perangkat lunak.
Jason S
3
IIC sedikit lebih mudah diimplementasikan secara elektrik, dan SPI mungkin sedikit lebih mudah dalam firmware. Namun keduanya cukup mudah dan lurus ke depan dalam kedua hal.
Olin Lathrop
2
@ Olin - ambang batas tetap 1,5 V tampaknya digunakan di masa lalu, tetapi menurut versi terbaru dari ambang spesifikasi memang 0,3 Vcc dan 0,7 Vcc. Kutipan dari spesifikasi ini menyebutkan 1.5 V untuk perangkat legacy.
stevenvh
16

Papan breakout untuk perangkat di SparkFun sebenarnya hanya untuk versi I2C (MPU-6500). Versi MPU-6000 memiliki antarmuka SPI dan I2C pada chip yang sama, dan saya tidak melihat bahwa SparkFun memiliki papan dengan chip itu. Jadi saya yakin Anda terbatas untuk menggunakan I2C jika Anda ingin menggunakan papan khusus itu. Tapi saya tetap akan merekomendasikan menggunakan I2C dalam situasi Anda karena alasan berikut.

Secara umum, Anda akan menemukan bahwa bus I2C lebih mudah digunakan dari sudut pandang perangkat keras daripada bus SPI. I2C adalah bus 2 kawat (SCL / SDA):

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

SPI adalah bus 4 kawat (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.

Anda dapat memiliki beberapa perangkat yang terhubung ke satu bus I2C. Setiap perangkat memiliki set alamat bawaan untuk chip tersebut. Alamat sebenarnya disiarkan melalui bus sebagai byte pertama dari setiap perintah (bersama dengan bit baca / tulis). Ini, bersama dengan beberapa overhead lainnya, membutuhkan lebih banyak bit untuk dikirim melalui bus I2C vs SPI untuk fungsi yang sama.

Kelas perangkat yang berbeda (memori, I / O, LCD, dll.) Memiliki rentang alamat yang berbeda. Beberapa perangkat, yang biasa digunakan lebih dari satu kali dalam suatu sistem (seperti PCF8574 I / O expander), menggunakan satu atau lebih garis alamat (AD0-2 untuk PCF8574) yang dapat diikat tinggi atau rendah untuk menentukan bit rendah dari alamat. MPU-6500 memiliki satu baris alamat seperti itu (AD0), sehingga dua di antaranya dapat digunakan dalam sistem yang sama.

Anda juga dapat memiliki banyak perangkat di bus SPI, tetapi setiap perangkat harus memiliki jalur pilih chip (CS) sendiri. Oleh karena itu deskripsi 4-kawat sedikit keliru - itu benar-benar antarmuka tiga kawat + satu kawat tambahan per perangkat. Saya tidak berpengalaman dengan seri papan Arduino, tapi saya percaya ini akan membuat menggunakan SPI lebih sulit pada Arduino, karena jika Anda membutuhkan banyak garis pilih chip ini akan mulai menjadi rumit dengan penugasan pin umum yang digunakan oleh berbagai perisai .

Saya percaya sebagian besar papan Arduino berjalan pada 5 volt, dengan beberapa yang lebih baru berjalan pada 3.3V. MPU-6500 beroperasi pada 3.3v. Jika tegangan input "tinggi" minimum untuk bus I2C pada CPU 5v adalah 3v atau di bawah, Anda dapat menghindari masalah konversi level dengan hanya menyediakan resistor penarik 10K hingga 3,3v pada jalur SCL dan SDA, karena bus terbuka pengumpul. Pastikan 5v internal pullup pada CPU dinonaktifkan.

Namun saya memeriksa datasheet untuk ATmega2560 (menggunakan ADK 5v Arduino sebagai contoh), dan tegangan minimum input 'tinggi "adalah 0,7 * Vcc, atau 3,5v yang lebih besar dari 3,3 v. Jadi, Anda perlu semacam level aktif Konversi. TI PCA9306 , yang membutuhkan resistor pullup pada sisi 5v dan 3.3v chip, harganya hanya 78 sen dalam jumlah tunggal.

Lalu mengapa memilih SPI daripada I2C? Terutama karena SPI dapat berjalan jauh lebih cepat - hingga 10-an MHz dalam beberapa kasus. I2C umumnya dibatasi hingga 400 KHz. Tapi ini bukan masalah untuk accelerometer MPU-6050/6000, karena beroperasi pada 400 KHz untuk I2C, dan hanya 1 MHz untuk SPI - tidak banyak perbedaan.

tcrosley
sumber
3
Alasan lain untuk memilih SPI daripada I2C: Semua baris searah, yang membuat hal-hal seperti pemindah level sedikit lebih mudah.
markrages
3
I2C lebih mudah daripada SPI ?! Satu-satunya hal tentang I2C yang lebih mudah adalah konektivitas jika Anda bisa menyatukan semuanya. Kalau tidak, integritas sinyal lebih keras di I2C, dan implementasi perangkat lunak yang kuat adalah cara yang lebih keras di I2C.
Jason S
2
@JasonS, saya telah menyelesaikan puluhan proyek perangkat lunak tertanam menggunakan I2C, dan tidak pernah mengalami masalah penguncian yang Anda sebutkan di pos Anda. Saya bisa mengerti Anda tidak menyukainya karena pengalaman buruk Anda. Saat ini saya memiliki produk di pasar menggunakan I2C DAC untuk output audio, sementara secara bersamaan membaca buffer data berikutnya dari kartu SD melalui SPI. Bagus sekali. Saya tidak bisa menggunakan SPI untuk kartu DAC dan SD karena saya mendapatkan pertengkaran bus dan audionya putus. Mikro (yang low-end) hanya memiliki satu SPI dan satu port I2C.
tcrosley
1
Saya terkesan bahwa Anda dapat menampilkan audio ke I2C DAC! (apa clock rate maks?) Jika Anda menggunakan IC onboard dengan jangka pendek, probabilitas berlari ke dalam penguncian sangat kecil, tetapi masih ada. (Juga Anda tidak akan pernah mengalami hal itu jika Anda hanya menulis data ke I2C. Ini mengharuskan Anda membaca dari perangkat yang bersedia menunggu selamanya untuk apa yang dianggapnya sebagai jam yang hilang / ekstra.)
Jason S
1
@JasonS, audio hanya kualitas suara, 8KHz - Saya menggunakan 128 us interrupt untuk output setiap sampel 16-bit. I2C juga berjalan dengan interupsi sendiri. Waktu luang digunakan untuk membaca data dari kartu SD. Poin bagus tentang penguncian tidak pernah terjadi pada penulisan. Kecuali untuk ADC, saya biasanya menggunakan I2C untuk perangkat output. Namun - tahukah Anda antarmuka baca-saja (2 tombol, akselerometer, dan joystick) antara remote Wii dan Wii Nunchuck (yang lebih dari kabel 3 ') adalah I2C pada 400 KHz? Banyak info di web meretas antarmuka perangkat ini.
tcrosley
15

Secara umum, SPI adalah bus yang lebih cepat - frekuensi clock dapat berada dalam kisaran MHz. Namun, SPI membutuhkan setidaknya 3 jalur untuk komunikasi dua arah dan tambahan budak yang dipilih untuk setiap perangkat di bus.

I2C hanya membutuhkan 2 baris, terlepas dari berapa banyak perangkat yang Anda miliki (dalam batas, tentu saja). Kecepatannya, bagaimanapun, adalah dalam kisaran kHz (100-400kHz khas).

Sebagian besar mikrokontroler, saat ini, memiliki dukungan perangkat keras untuk kedua bus, sehingga keduanya sama-sama mudah digunakan.

Armanda
sumber
4
@Jason: Anda tampaknya memiliki beberapa prasangka terhadap IIC, tetapi tidak adil untuk menyalahkan orang lain karena itu. Baik IIC dan SPI "mudah", dengan masing-masing memiliki kerutan sendiri. SPI membutuhkan saluran tambahan, yang tidak mudah. IIC sedikit lebih rumit, tetapi masih mudah untuk melakukan semua implementasi firmware, yang telah saya lakukan berkali-kali. Tidak perlu terlalu banyak kode. Keduanya memiliki tempat masing-masing dan keduanya cukup mudah untuk tidak menjadi faktor bagi siapa pun yang tahu apa yang mereka lakukan.
Olin Lathrop
5
@Jason: Saya baru saja memeriksa, dan kode IIC generik saya untuk implementasi firmware IIC pada PIC 8 bit hanya 311 baris, dan mungkin lebih dari setengahnya adalah komentar. Itu membuat Anda antarmuka prosedural ke bus IIC di tingkat rutinitas untuk memulai, meletakkan, mendapatkan, berhenti, dll. Masalah besar. Modul yang memanggil untuk menggerakkan EEPROM sederhana adalah 272 baris, sekali lagi 1/2 komentar mungkin, dan itu termasuk beberapa manajemen tingkat tinggi seperti data default, antarmuka debug UART, dll. Ini semua sangat sepele sehingga berdebat apakah perlu 10 instruksi kurang dari SPI tidak ada gunanya.
Olin Lathrop
2
@Andrew Kohlsmith - I2C is designed for on-board applications.- Rupanya produsen perangkat I2C tidak setuju dengan Anda. Ambil TMP100 . Halaman produk secara eksplisit menyatakan: The TMP100 and TMP101 are ideal for extended temperature measurement in a variety of communication, computer, consumer, environmental, industrial, and instrumentation applications.Hal yang sama berlaku untuk TMP75
Connor Wolf
5
@FakeName Anda salah; Saya menghabiskan 13 tahun mengerjakan elektronik tenaga industri. (Memulai dan memantau Mtors tiga fase BESAR adalah lingkungan yang SANGAT berisik) Ini bukan tentang SPI yang lebih dapat diandalkan, ini tentang merancang sistem dengan semua mode kegagalan yang direncanakan dan diperhitungkan, dan memiliki opsi pemulihan yang dibangun ke dalam sistem di mana diperlukan. Saya tidak pernah, pernah mengalami lonjakan suara, membunuh I2C saya (atau SPI dalam hal ini), tetapi saya juga tidak pernah bergantung secara eksklusif pada pengontrol I2C untuk melakukan segalanya untuk saya. Ini masalah perencanaan dan desain, bukan satu bus yang lebih baik.
akohlsmith
2
@akohlsmith: Single-master single-slave I2C harus kuat dengan master "bit-bang". Jika ada banyak budak dan dua secara bersamaan "bingung" dengan cara yang berbeda, bus mungkin terkunci secara tidak dapat diperbaiki (misalnya jika dua atau lebih chip memori yang diisi dengan nol keduanya berpikir bahwa master sedang mencoba untuk membacanya, tetapi bit counter mereka tidak sinkron, maka masing-masing hanya akan merilis SDA pada saat-saat ketika yang lain menyatakan itu, dan tidak ada yang dapat dilakukan master akan membebaskan bus kecuali dapat mengendarai "tinggi" yang cukup kuat untuk overdrive semua budak
supercat
12

SPI dapat berjalan jauh lebih cepat daripada I2C (beberapa perangkat SPI melebihi 60MHz; Saya tidak tahu apakah "IHS" spec resmi memungkinkan perangkat lebih dari 1MHz). Implementasi perangkat budak menggunakan protokol mana pun membutuhkan dukungan perangkat keras, sementara keduanya memungkinkan implementasi master "software bit-bang" yang mudah. Dengan perangkat keras yang relatif minimal, seseorang dapat membangun budak yang sesuai dengan I2C yang akan beroperasi dengan benar bahkan jika tuan rumah dapat secara sewenang-wenang memutuskan untuk mengabaikan bus hingga 500 us pada suatu waktu, tanpa perlu kabel handshaking tambahan. Namun, operasi SPI yang andal, bahkan dengan dukungan perangkat keras , umumnya mengharuskan seseorang untuk menambahkan kawat jabat tangan, atau jika tuan rumah "secara manual" menambahkan penundaan setelah setiap byte sama dengan waktu respons kasus terburuk budak.

Jika saya memiliki pemabuk saya, dukungan SPI controller akan berisi beberapa fitur tambahan sederhana untuk memberikan transfer data dua arah transparan 8-bit antara controller dengan kemampuan handshaking dan wake-up, menggunakan total tiga kabel searah (Clock dan MOSI [master -out-slave-in] dari master; MISO [master-in-slave-out] dari slave). Sebagai perbandingan, komunikasi yang efisien dan andal antara mikrokontroler dengan port SPI "stock", ketika kedua prosesor mungkin secara independen ditunda untuk jangka waktu yang sewenang-wenang, membutuhkan penggunaan lebih banyak kabel (Pilih Chip, Clock, MISO, dan MOSI untuk memulai) dengan, ditambah semacam kawat yang diakui dari budak. Jika budak tersebut secara asinkron mulai mengirim data (misalnya karena seseorang menekan tombol), maka seseorang harus menggunakan kabel lain sebagai "bangun"

I2C tidak menyediakan semua kemampuan yang dimiliki SPI "ditingkatkan" saya, tetapi ia menawarkan kemampuan handshaking bawaan yang tidak dimiliki SPI, dan dalam banyak implementasi dapat dikompilasi untuk menyediakan bangun juga, bahkan jika masternya adalah seorang perangkat lunak bit-bang. Untuk komunikasi antar-prosesor, oleh karena itu saya akan sangat merekomendasikan I2C lebih dari SPI kecuali ketika kecepatan yang lebih tinggi diperlukan daripada yang dapat disediakan SPI, dan penggunaan pin tambahan dapat diterima. Untuk komunikasi antar-prosesor di mana jumlah pin rendah diperlukan, UART harus banyak merekomendasikannya.

supercat
sumber
Ada versi I2C kecepatan tinggi yang memungkinkan 1MHz; I2C normal adalah 400kHz.
The Resistance
@TheResistance: Saya tahu bahwa I2C normal adalah 400kHz, tetapi versi dispesifikasikan hingga 1MHz. Yang tidak saya ketahui adalah apakah versi yang lebih cepat telah ditentukan.
supercat
Menurut spesifikasi 400kbps (bukan kHz, saya menggunakan unit yang salah di sana) adalah Fast-mode, 1Mbps adalah Fast-mode Plus, dan ada mode kecepatan tinggi hingga 3.4Mbps. Ultra-cepat berjalan hingga 5Mbps, tetapi searah.
The Resistance
@TheResistance: Terima kasih. Saya belum pernah mendengar versi-versi selanjutnya. Apa sebenarnya yang Anda maksud dengan 'searah'? Saya tahu bahwa kecepatan komunikasi sli-ke-master SPI bisa lebih cepat daripada master-ke-budak karena budak dijamin mendapatkan jamnya setelah master, tetapi saya tidak yakin konsep yang setara untuk I2C. Punya linky?
supercat
Temukan spek di sini . Pada halaman 23 dikatakan bahwa Ultra-fast dapat digunakan untuk perangkat yang tidak mengirim kembali data (hanya menulis), bahkan ACK.
The Resistance
8

Pertanyaan ini telah sepenuhnya dieksplorasi dalam jawaban yang sangat baik di sini, tetapi mungkin ada satu sudut pandang lagi untuk I 2 C yang bisa saya tawarkan dari sudut pandang pembuat chip.

Antarmuka listrik I 2 C adalah kolektor terbuka . Sekarang bernafas dan pikirkan implikasinya. Dengan menggunakan I 2 C, saya dapat merancang chip yang benar-benar agnostik terhadap tegangan pengoperasian bus. Yang perlu saya lakukan hanyalah menarik garis SDA rendah jika itu menyenangkan saya, dan membandingkan tegangan SCL dan SDA dengan beberapa tegangan ambang batas tanah yang direferensikan, yang dapat saya pilih. Dan jika saya meninggalkan struktur perlindungan sisi tinggi normal dan menggantinya dengan struktur lain, saya dapat membuat chip yang benar-benar dapat hidup sendiri tanpa tergantung dari sisa sistem - SCL, SDA tidak pernah memberi makan arus ke chip saya dan saya tentu tidak akan memberi makan arus ke pin tersebut. Itu sebabnya bus yang bagus untuk jam waktu nyata dan hal-hal berdaya rendah lainnya seperti itu.

PkP
sumber
4

Satu hal yang belum saya lihat disebutkan dalam jawaban lain adalah bahwa I2C mendukung banyak master di bus yang sama. Jika Anda memerlukan komunikasi dua arah dan tidak ingin menggunakan metode berbasis polling, I2C akan menyelesaikan pekerjaan.

Jarak yang lebih jauh, CAN memiliki kemampuan yang sama dan lebih kuat. Tetapi CAN adalah protokol asinkron yang memerlukan dukungan perangkat keras dan transceiver, sehingga mungkin bukan opsi dalam sistem berbiaya rendah.

Adam Haun
sumber
Poin bagus (pada multi master), saya juga melihat perangkat SPI dengan pin interupsi, sementara satu perangkat masih merupakan master, keduanya dapat instantiate (bi-directional) komunikasi. Untuk perangkat jarak jauh di sana, tentu saja ada opsi yang lebih solid dan lebih baik (seperti CAN).
Paul
0

Gunakan protokol SPI dan tulis bit Anda langsung ke perangkat setiap kali jam sinkronisasi naik. Rangkaian logika xnor dapat digunakan untuk mencocokkan alamat "buatan sendiri" dari memori untuk memilih perangkat yang diinginkan seolah-olah itu adalah perangkat i2c.

I2c mengintegrasikan sirkuit authorial di dalam format perangkat, standar ... dll yang kompleks dan berbeda, dengan spi Anda dapat menggunakan memori spi untuk menampilkan video di layar, tetapi tidak i2c.

lansuperman
sumber