Bagaimana Anda menggunakan SPI pada Arduino?

45

Dengan mengacu pada Arduino Uno, Mega2560, Leonardo dan papan serupa:

  • Bagaimana cara kerja SPI?
  • Seberapa cepat SPI?
  • Bagaimana saya menghubungkan antara master dan slave?
  • Bagaimana cara membuat budak SPI?

Harap dicatat: Ini dimaksudkan sebagai pertanyaan referensi.

Nick Gammon
sumber
Bisakah Anda menjawab pertanyaan terkait ini arduino.stackexchange.com/questions/60703/…
qwr

Jawaban:

81

Pengantar SPI

The Peripheral Interface Serial Bus (SPI) antarmuka digunakan untuk komunikasi antara beberapa perangkat jarak pendek, dan pada kecepatan tinggi.

Biasanya ada perangkat "master" tunggal, yang memulai komunikasi dan memasok jam yang mengontrol laju transfer data. Mungkin ada satu atau lebih budak. Untuk lebih dari satu budak, masing-masing memiliki sinyal "pilih budak" sendiri, dijelaskan nanti.


Sinyal SPI

Dalam sistem SPI full-blown Anda akan memiliki empat jalur sinyal:

  • Master Out, Slave In ( MOSI ) - yang merupakan data dari master ke slave
  • Master In, Slave Out ( MISO ) - yang merupakan data dari slave ke master
  • Serial Clock ( SCK ) - saat ini mengaktifkan master dan sampel budak bit berikutnya
  • Pilih Budak ( SS ) - ini memberitahu budak tertentu untuk "aktif"

Ketika banyak budak terhubung ke sinyal MISO, mereka diharapkan melakukan tri-state (tetap pada impedansi tinggi) garis MISO sampai mereka dipilih oleh Slave Select. Normally Slave Select (SS) menjadi rendah untuk menegaskannya. Artinya, aktif rendah. Setelah budak tertentu dipilih, ia harus mengkonfigurasi garis MISO sebagai output sehingga dapat mengirim data ke master.

Gambar ini menunjukkan cara pertukaran data saat satu byte dikirim:

Protokol SPI menampilkan 4 sinyal

Perhatikan bahwa tiga sinyal adalah output dari master (MOSI, SCK, SS) dan satu adalah input (MISO).


Pengaturan waktu

Urutan acara adalah:

  • SS pergi rendah untuk menegaskannya dan mengaktifkan budak
  • The SCKgaris matikan untuk menunjukkan ketika garis data harus sampel
  • Data sampel oleh kedua master dan slave pada terkemuka tepi SCK(menggunakan clock phase default)
  • Baik master maupun slave bersiap untuk bit berikutnya pada trailing edge SCK(menggunakan fase clock default), dengan mengubah MISO/ MOSIjika perlu
  • Setelah transmisi selesai (mungkin setelah beberapa byte telah dikirim) kemudian SSpergi tinggi untuk menegaskan kembali itu

Perhatikan bahwa:

  • Bit paling signifikan dikirim terlebih dahulu (secara default)
  • Data dikirim dan diterima pada saat yang sama (dupleks penuh)

Karena data dikirim dan diterima pada pulsa clock yang sama, tidak mungkin bagi budak untuk segera menanggapi master. Protokol SPI biasanya mengharapkan master untuk meminta data pada satu transmisi, dan mendapatkan respons pada transmisi berikutnya.

Menggunakan perpustakaan SPI di Arduino, melakukan satu transfer terlihat seperti ini dalam kode:

 byte outgoing = 0xAB;
 byte incoming = SPI.transfer (outgoing);

Kode sampel

Contoh pengiriman saja (mengabaikan data yang masuk):

#include <SPI.h>

void setup (void)
  {
  digitalWrite(SS, HIGH);  // ensure SS stays high
  SPI.begin ();
  } // end of setup

void loop (void)
  {
  byte c;

  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10

  // send test string
  for (const char * p = "Fab" ; c = *p; p++)
    SPI.transfer (c);

  // disable Slave Select
  digitalWrite(SS, HIGH);

  delay (100);
  } // end of loop

Pengkabelan untuk SPI khusus keluaran

Kode di atas (yang hanya mengirim) dapat digunakan untuk mendorong register shift serial keluaran. Ini adalah perangkat keluaran saja, jadi kami tidak perlu khawatir tentang data yang masuk. Dalam kasus mereka, pin SS mungkin disebut pin "store" atau "latch".

Protokol SPI menampilkan 3 sinyal

Contoh dari ini adalah register geser serial 74HC595, dan berbagai strip LED, hanya untuk menyebutkan beberapa. Misalnya, tampilan LED 64 piksel yang digerakkan oleh chip MAX7219:

Tampilan LED 64 piksel

Dalam hal ini Anda dapat melihat bahwa pembuat papan telah menggunakan nama sinyal yang sedikit berbeda:

  • DIN (Data Masuk) adalah MOSI (Master Out, Slave In)
  • CS (Chip Select) adalah SS (Slave Select)
  • CLK (Jam) adalah SCK (Serial Clock)

Sebagian besar papan akan mengikuti pola yang sama. Terkadang DIN hanya DI (Data In).

Berikut adalah contoh lain, kali ini papan display LED 7-segmen (juga didasarkan pada chip MAX7219):

Tampilan LED 7-segmen

Ini menggunakan nama sinyal yang persis sama dengan papan lainnya. Dalam kedua kasus ini Anda dapat melihat bahwa papan hanya membutuhkan 5 kabel untuk itu, tiga untuk SPI, ditambah daya dan ground.


Fase jam dan polaritas

Ada empat cara Anda dapat mencicipi jam SPI.

Protokol SPI memungkinkan variasi pada polaritas pulsa clock. CPOL adalah polaritas jam, dan CPHA adalah fase jam.

  • Mode 0 (standar) - jam biasanya rendah (CPOL = 0), dan data diambil sampelnya pada transisi dari rendah ke tinggi (tepi depan) (CPHA = 0)
  • Mode 1 - jam biasanya rendah (CPOL = 0), dan data diambil sampel pada transisi dari tinggi ke rendah (trailing edge) (CPHA = 1)
  • Mode 2 - jam biasanya tinggi (CPOL = 1), dan data diambil sampelnya pada transisi dari tinggi ke rendah (leading edge) (CPHA = 0)
  • Mode 3 - jam biasanya tinggi (CPOL = 1), dan data diambil sampel pada transisi dari rendah ke tinggi (trailing edge) (CPHA = 1)

Ini diilustrasikan dalam grafik ini:

Fase clock SPI dan polaritas

Anda harus merujuk ke lembar data untuk perangkat Anda agar fase dan polaritasnya benar. Biasanya akan ada diagram yang menunjukkan cara mengambil sampel jam. Misalnya, dari datasheet untuk chip 74HC595:

Jam 74HC595

Seperti yang Anda lihat, jam biasanya rendah (CPOL = 0) dan disampel di tepi terdepan (CPHA = 0) sehingga ini adalah mode SPI 0.

Anda dapat mengubah polaritas jam dan fase dalam kode seperti ini (pilih satu saja, tentu saja):

SPI.setDataMode (SPI_MODE0);
SPI.setDataMode (SPI_MODE1);
SPI.setDataMode (SPI_MODE2);
SPI.setDataMode (SPI_MODE3);

Metode ini sudah usang dalam versi 1.6.0 dan seterusnya dari Arduino IDE. Untuk versi terbaru, Anda mengubah mode jam dalam SPI.beginTransactionpanggilan, seperti ini:

SPI.beginTransaction (SPISettings (2000000, MSBFIRST, SPI_MODE0));  // 2 MHz clock, MSB first, mode 0

Pesanan data

Standarnya adalah bit yang paling signifikan terlebih dahulu, namun Anda dapat memberitahu perangkat keras untuk memproses bit yang paling signifikan terlebih dahulu seperti ini:

SPI.setBitOrder (LSBFIRST);   // least significant bit first
SPI.setBitOrder (MSBFIRST);   // most significant bit first

Sekali lagi, ini sudah usang dalam versi 1.6.0 dan seterusnya dari Arduino IDE. Untuk versi terbaru, Anda mengubah urutan bit dalam SPI.beginTransactionpanggilan, seperti ini:

SPI.beginTransaction (SPISettings (1000000, LSBFIRST, SPI_MODE2));  // 1 MHz clock, LSB first, mode 2

Kecepatan

Pengaturan default untuk SPI adalah menggunakan kecepatan jam sistem dibagi dengan empat, yaitu, satu pulsa clock SPI setiap 250 ns, dengan asumsi jam CPU 16 MHz. Anda dapat mengubah pembagi jam dengan menggunakan setClockDividerseperti ini:

SPI.setClockDivider (divider);

Di mana "pembagi" adalah salah satu dari:

  • SPI_CLOCK_DIV2
  • SPI_CLOCK_DIV4
  • SPI_CLOCK_DIV8
  • SPI_CLOCK_DIV16
  • SPI_CLOCK_DIV32
  • SPI_CLOCK_DIV64
  • SPI_CLOCK_DIV128

Laju tercepat adalah "bagi 2" atau satu pulsa clock SPI setiap 125 ns, dengan asumsi clock CPU 16 MHz. Oleh karena itu, diperlukan 8 * 125 ns atau 1 μs untuk mengirimkan satu byte.

Metode ini sudah usang dalam versi 1.6.0 dan seterusnya dari Arduino IDE. Untuk versi terbaru, Anda mengubah kecepatan transfer dalam SPI.beginTransactionpanggilan, seperti ini:

SPI.beginTransaction (SPISettings (4000000, MSBFIRST, SPI_MODE0));  // 4 MHz clock, MSB first, mode 0

Namun pengujian empiris menunjukkan bahwa perlu memiliki dua pulsa clock antara byte, sehingga tingkat maksimum di mana byte dapat clocked adalah masing-masing 1,125 μs masing-masing (dengan pembagi jam 2).

Untuk meringkas, setiap byte dapat dikirim pada tingkat maksimum satu per 1,125 μs (dengan clock 16 MHz) memberikan laju transfer maksimum teoritis 1 / 1,125 μs, atau 888.888 byte per detik (tidak termasuk overhead seperti pengaturan SS rendah dan sebagainya) di).


Menghubungkan ke Arduino

Arduino Uno

Menghubungkan melalui pin digital 10 hingga 13:

Pin Arduino Uno SPI

Menghubungkan melalui header ICSP:

Pinout ICSP - Uno

Header ICSP

Arduino Atmega2560

Menghubungkan melalui pin digital 50 hingga 52:

Pin Arduino Mega2560 SPI

Anda juga dapat menggunakan header ICSP, mirip dengan Uno di atas.

Arduino Leonardo

Leonardo dan Micro tidak mengekspos pin SPI pada pin digital, tidak seperti Uno dan Mega. Satu-satunya pilihan Anda adalah menggunakan pin header ICSP, seperti yang diilustrasikan di atas untuk Uno.


Banyak budak

Seorang master dapat berkomunikasi dengan banyak budak (namun hanya satu per satu). Itu melakukan ini dengan menyatakan SS untuk satu budak dan membatalkannya untuk yang lain. Budak yang memiliki SS menegaskan (biasanya ini berarti RENDAH) mengkonfigurasi pin MISO sebagai output sehingga budak, dan budak itu sendiri, dapat menanggapi master. Budak lainnya mengabaikan pulsa clock yang masuk jika SS tidak ditegaskan. Dengan demikian Anda memerlukan satu sinyal tambahan untuk setiap budak, seperti ini:

Beberapa budak SPI

Dalam grafik ini Anda dapat melihat bahwa MISO, MOSI, SCK dibagi di antara kedua budak, namun masing-masing budak memiliki sinyal SS (pemilihan budak) sendiri.


Protokol

SPI spec tidak menentukan protokol seperti itu, jadi terserah pada pasangan master / slave individual untuk menyetujui apa artinya data. Sementara Anda dapat mengirim dan menerima byte secara bersamaan, byte yang diterima tidak bisa menjadi respons langsung ke byte yang dikirim (karena mereka sedang dirangkai secara bersamaan).

Jadi akan lebih logis bagi salah satu ujung untuk mengirim permintaan (mis. 4 mungkin berarti "daftar direktori disk") dan kemudian melakukan transfer (mungkin hanya mengirim nol ke luar) hingga menerima respons lengkap. Respons mungkin berakhir dengan baris baru, atau karakter 0x00.

Baca datasheet untuk perangkat budak Anda untuk melihat urutan protokol apa yang diharapkannya.


Cara membuat budak SPI

Contoh sebelumnya menunjukkan Arduino sebagai master, mengirimkan data ke perangkat slave. Contoh ini menunjukkan bagaimana Arduino bisa menjadi budak.

Pengaturan perangkat keras

Hubungkan dua Arduino Unos bersama-sama dengan pin berikut yang terhubung satu sama lain:

  • 10 (SS)
  • 11 (MOSI)
  • 12 (MISO)
  • 13 (SCK)

  • + 5v (jika diperlukan)

  • GND (untuk pengembalian sinyal)

Pada Arduino Mega, pinnya adalah 50 (MISO), 51 (MOSI), 52 (SCK), dan 53 (SS).

Bagaimanapun, MOSI di satu ujung terhubung ke MOSI di sisi lain, Anda tidak bertukar sekitar (yaitu Anda tidak memiliki MOSI <-> MISO). Perangkat lunak mengkonfigurasi salah satu ujung MOSI (master end) sebagai output, dan ujung lainnya (slave end) sebagai input.

Contoh utama

#include <SPI.h>

void setup (void)
{

  digitalWrite(SS, HIGH);  // ensure SS stays high for now

  // Put SCK, MOSI, SS pins into output mode
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  SPI.begin ();

  // Slow down the master a bit
  SPI.setClockDivider(SPI_CLOCK_DIV8);

}  // end of setup


void loop (void)
{

  char c;

  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10

  // send test string
  for (const char * p = "Hello, world!\n" ; c = *p; p++)
    SPI.transfer (c);

  // disable Slave Select
  digitalWrite(SS, HIGH);

  delay (1000);  // 1 seconds delay
}  // end of loop

Contoh budak

#include <SPI.h>

char buf [100];
volatile byte pos;
volatile bool process_it;

void setup (void)
{
  Serial.begin (115200);   // debugging

  // turn on SPI in slave mode
  SPCR |= bit (SPE);

  // have to send on master in, *slave out*
  pinMode (MISO, OUTPUT);

  // get ready for an interrupt
  pos = 0;   // buffer empty
  process_it = false;

  // now turn on interrupts
  SPI.attachInterrupt();

}  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
{
byte c = SPDR;  // grab byte from SPI Data Register

  // add to buffer if room
  if (pos < sizeof buf)
    {
    buf [pos++] = c;

    // example: newline means time to process buffer
    if (c == '\n')
      process_it = true;

    }  // end of room available
}  // end of interrupt routine SPI_STC_vect

// main loop - wait for flag set in interrupt routine
void loop (void)
{
  if (process_it)
    {
    buf [pos] = 0;
    Serial.println (buf);
    pos = 0;
    process_it = false;
    }  // end of flag set

}  // end of loop

Budak sepenuhnya didorong oleh interupsi, sehingga dapat melakukan hal-hal lain. Data SPI yang masuk dikumpulkan dalam buffer, dan sebuah flag ditetapkan ketika "byte signifikan" (dalam hal ini baris baru) tiba. Ini memberitahu budak untuk memulai dan mulai memproses data.

Contoh menghubungkan master ke slave menggunakan SPI

Master dan budak Arduino SPI


Cara mendapatkan respons dari seorang budak

Sebagai lanjutan dari kode di atas yang mengirimkan data dari master SPI ke slave, contoh di bawah ini menunjukkan pengiriman data ke slave, setelah itu melakukan sesuatu dengannya, dan mengembalikan respons.

Masternya mirip dengan contoh di atas. Namun poin penting adalah bahwa kita perlu menambahkan sedikit keterlambatan (sekitar 20 mikrodetik). Kalau tidak, budak tidak memiliki kesempatan untuk bereaksi terhadap data yang masuk dan melakukan sesuatu dengannya.

Contoh ini menunjukkan pengiriman "perintah". Dalam hal ini "a" (tambahkan sesuatu) atau "s" (kurangi sesuatu). Ini untuk menunjukkan bahwa budak benar-benar melakukan sesuatu dengan data.

Setelah menyatakan slave-select (SS) untuk memulai transaksi, master mengirim perintah, diikuti oleh sejumlah byte, dan kemudian menaikkan SS untuk mengakhiri transaksi.

Poin yang sangat penting adalah bahwa slave tidak dapat menanggapi byte yang masuk pada saat yang sama. Responsnya harus dalam byte berikutnya. Ini karena bit yang dikirim, dan bit yang diterima, sedang dikirim secara bersamaan. Jadi untuk menambahkan sesuatu ke empat angka kita perlu lima transfer, seperti ini:

transferAndWait ('a');  // add command
transferAndWait (10);
a = transferAndWait (17);
b = transferAndWait (33);
c = transferAndWait (42);
d = transferAndWait (0);

Pertama kami meminta tindakan pada nomor 10. Tapi kami tidak mendapatkan jawaban sampai transfer berikutnya (yang untuk 17). Namun "a" akan ditetapkan ke balasan ke 10. Akhirnya kami akhirnya mengirim "dummy" nomor 0, untuk mendapatkan balasan sebesar 42.

Master (contoh)

  #include <SPI.h>

  void setup (void)
    {
    Serial.begin (115200);
    Serial.println ();

    digitalWrite(SS, HIGH);  // ensure SS stays high for now
    SPI.begin ();

    // Slow down the master a bit
    SPI.setClockDivider(SPI_CLOCK_DIV8);
    }  // end of setup

  byte transferAndWait (const byte what)
    {
    byte a = SPI.transfer (what);
    delayMicroseconds (20);
    return a;
    } // end of transferAndWait

  void loop (void)
    {

    byte a, b, c, d;

    // enable Slave Select
    digitalWrite(SS, LOW);

    transferAndWait ('a');  // add command
    transferAndWait (10);
    a = transferAndWait (17);
    b = transferAndWait (33);
    c = transferAndWait (42);
    d = transferAndWait (0);

    // disable Slave Select
    digitalWrite(SS, HIGH);

    Serial.println ("Adding results:");
    Serial.println (a, DEC);
    Serial.println (b, DEC);
    Serial.println (c, DEC);
    Serial.println (d, DEC);

    // enable Slave Select
    digitalWrite(SS, LOW);

    transferAndWait ('s');  // subtract command
    transferAndWait (10);
    a = transferAndWait (17);
    b = transferAndWait (33);
    c = transferAndWait (42);
    d = transferAndWait (0);

    // disable Slave Select
    digitalWrite(SS, HIGH);

    Serial.println ("Subtracting results:");
    Serial.println (a, DEC);
    Serial.println (b, DEC);
    Serial.println (c, DEC);
    Serial.println (d, DEC);

    delay (1000);  // 1 second delay
    }  // end of loop

Kode untuk slave pada dasarnya melakukan hampir semua hal dalam rutinitas interupsi (dipanggil ketika data SPI yang masuk tiba). Dibutuhkan byte yang masuk, dan menambah atau mengurangi sesuai "byte perintah" yang diingat. Perhatikan bahwa respons akan "dikumpulkan" lain kali melalui loop. Inilah sebabnya mengapa master harus mengirim satu "dummy" transfer terakhir untuk mendapatkan jawaban akhir.

Dalam contoh saya, saya menggunakan loop utama untuk hanya mendeteksi ketika SS tinggi, dan menghapus perintah yang disimpan. Dengan begitu, ketika SS ditarik rendah lagi untuk transaksi berikutnya, byte pertama dianggap sebagai byte perintah.

Lebih dapat dipercaya, ini akan dilakukan dengan interupsi. Artinya, Anda akan secara fisik menghubungkan SS ke salah satu input interupsi (misalnya, pada Uno, hubungkan pin 10 (SS) ke pin 2 (input interupsi), atau gunakan pin-change interrupt pada pin 10.

Kemudian interupsi dapat digunakan untuk melihat ketika SS ditarik rendah atau tinggi.

Budak (contoh)

// what to do with incoming data
volatile byte command = 0;

void setup (void)
  {

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);

  // turn on SPI in slave mode
  SPCR |= _BV(SPE);

  // turn on interrupts
  SPCR |= _BV(SPIE);

  }  // end of setup


// SPI interrupt routine
ISR (SPI_STC_vect)
  {
  byte c = SPDR;

  switch (command)
    {
    // no command? then this is the command
    case 0:
      command = c;
      SPDR = 0;
      break;

    // add to incoming byte, return result
    case 'a':
      SPDR = c + 15;  // add 15
      break;

    // subtract from incoming byte, return result
    case 's':
      SPDR = c - 8;  // subtract 8
      break;

    } // end of switch

  }  // end of interrupt service routine (ISR) SPI_STC_vect

void loop (void)
  {

  // if SPI not active, clear current command
  if (digitalRead (SS) == HIGH)
    command = 0;
  }  // end of loop

Contoh output

Adding results:
25
32
48
57
Subtracting results:
2
9
25
34
Adding results:
25
32
48
57
Subtracting results:
2
9
25
34

Keluaran penganalisis logika

Ini menunjukkan waktu antara mengirim dan menerima dalam kode di atas:

Master SPI dan timing budak


Fungsionalitas baru di IDE 1.6.0 dan seterusnya

Versi 1.6.0 dari IDE telah mengubah cara SPI bekerja, sampai batas tertentu. Anda masih perlu melakukannya SPI.begin() sebelum menggunakan SPI. Itu mengatur perangkat keras SPI. Namun sekarang, ketika Anda akan memulai berkomunikasi dengan budak Anda juga lakukan SPI.beginTransaction()untuk mengatur SPI (untuk budak ini) dengan benar:

  • Kecepatan jam
  • Pesanan sedikit
  • Fase jam dan polaritas

Ketika Anda selesai berkomunikasi dengan budak, Anda menelepon SPI.endTransaction(). Sebagai contoh:

SPI.beginTransaction (SPISettings (2000000, MSBFIRST, SPI_MODE0));
digitalWrite (SS, LOW);        // assert Slave Select
byte foo = SPI.transfer (42);  // do a transfer
digitalWrite (SS, HIGH);       // de-assert Slave Select
SPI.endTransaction ();         // transaction over

Mengapa menggunakan SPI?

Saya akan menambahkan satu pertanyaan awal: kapan / mengapa Anda menggunakan SPI? Kebutuhan untuk konfigurasi multi-master atau jumlah budak yang sangat besar akan memiringkan skala menuju I2C.

Ini adalah pertanyaan yang sangat bagus. Jawaban saya adalah:

  • Beberapa perangkat (beberapa) hanya mendukung metode transfer SPI. Misalnya register shift keluaran 74HC595, register shift input 74HC165, driver LED MAX7219, dan beberapa strip LED yang telah saya lihat. Jadi, Anda mungkin menggunakannya karena perangkat target hanya mendukungnya.
  • SPI benar-benar metode tercepat yang tersedia pada chip Atmega328 (dan sejenisnya). Tingkat tercepat yang dikutip di atas adalah 888.888 byte per detik. Menggunakan I 2 C Anda hanya bisa mendapatkan sekitar 40.000 byte per detik. Overhead dari I 2 C cukup besar, dan jika Anda mencoba antarmuka sangat cepat, SPI adalah pilihan yang lebih disukai. Cukup banyak keluarga chip (mis. MCP23017 dan MCP23S17) sebenarnya mendukung I 2 C dan SPI sehingga Anda sering dapat memilih antara kecepatan, dan kemampuan untuk memiliki beberapa perangkat pada satu bus.
  • Perangkat SPI dan I 2 C keduanya didukung dalam perangkat keras pada Atmega328 sehingga Anda dapat melakukan transfer melalui SPI secara bersamaan dengan I 2 C yang akan memberi Anda dorongan kecepatan.

Kedua metode memiliki tempat masing-masing. I 2 C memungkinkan Anda menghubungkan banyak perangkat ke satu bus (dua kabel, ditambah arde) sehingga akan menjadi pilihan yang lebih disukai jika Anda perlu menginterogasi sejumlah besar perangkat, mungkin cukup jarang. Namun kecepatan SPI bisa lebih relevan untuk situasi di mana Anda perlu membuat output dengan cepat (mis. Strip LED) atau input dengan cepat (mis. Konverter ADC).


Referensi

Nick Gammon
sumber
Apakah Anda akan membahas keanehan yang merupakan SPI Due? Di mana konfigurasi port SPI terkait dengan pin SS yang digunakan, dan ada (IIRC) 4 pin SS perangkat keras yang ditetapkan untuk port SPI?
Majenko
Poin lain tentang pemilihan: kadang-kadang Anda benar-benar tidak punya pilihan karena sensor yang ingin / perlu Anda gunakan hanya tersedia sebagai I2C.
Igor Stoppa
Are you going to cover the weirdness that is the Due's SPI?- Saya tidak tahu apa-apa tentang SPI Due (selain menganggap protokol keseluruhan sama). Anda dapat menambahkan balasan yang mencakup aspek itu.
Nick Gammon
Kapan buku audio jawaban ini keluar, dan apakah Anda akan membacanya sendiri;)
AMADANON Inc.
1
@AMADANONInc. Mungkin video musik? Atau animasi? Saya tidak yakin apakah aksen Australia saya dapat dimengerti. : P
Nick Gammon