Arduino Uno kartında SPI haberleşme için kullanacağımız pinler; 10, 11, 12 ve 13. pinlerdir. 11🡪 MOSI, 12 🡪 MISO, 13 🡪 SCK, 10 🡪 SS ‘dir. Atmega328 entegresinde ise SPI pinleri; 16, 17, 18 ve 19. bacaklardır. 16 🡪 SS, 17 🡪 MOSI, 18 🡪 MISO, 19 🡪SCK ‘dır.
Bu pinler, kullanılan Arduino türüne göre değişiklik göstermektedir. Arduino türlerine göre MOSI, MISO, SCK ve SS pinleri aşağıdaki tabloda gösterilmiştir.
Arduino Türü | MOSI | MISO | SCK | SS (Slave) | SS (Master) |
Arduino UNO | 11 veya ICSP4 | 12 veya ICSP1 | 13 veya ICSP3 | 10 | - |
Arduino Mega | 51 veya ICSP4 | 50 veya ICSP1 | 52 veya ICSP3 | 53 | - |
Arduino Leonardo | ICSP-4 | ICSP-1 | ICSP-3 | - | - |
Arduino Due | ICSP-4 | ICSP-1 | ICSP-3 | - | - |

Arduino SPI Komutları
Arduino'nun SPI haberleşmesini yapabilmesi için kullanılması gereken komutlar vardır. Bu komutlar Arduino'nun "SPI.h" kütüphanesi içerisinde bulunmaktadır. Bu yüzden öncelikle #include <SPI.h> komutu ile “SPI” kütüphanemizi projemize dahil etmeliyiz.
SPI kütüphanesi, Arduino'nun her zaman master konumunda olacağı düşünülerek hazırlanmıştır. Eğer iki adet Arduino’yu SPI ile haberleştireceksek slave Arduino için kütüphane dışında kendi komutlarımızı yazmamız gerekir. Master olan Arduino için SPI kütüphanesi yeterli olacaktır.
Saat Hızı
SPI protokolünün hızı genellikle SPI veri yolundaki cihazların yetenekleriyle sınırlı olacaktır. Hepsinin kaldırabileceği maksimum hızı bulmak için cihazlarınızın özelliklerini kontrol etmeniz gerekecektir. SPI hızı 16Mhz Arduino için; 16/2=8 Mhz ile 16/128=125 kHz arasında olur.
Veri alma
Bir slave cihaz, master cihaza veri iletmeye hazır olsa bile, master cihazın yardımı olmadan bunu yapamaz. Slave’nin master’a veri gönderebilmesi için, master’ın slave’e veri göndermesi gerekir ve böylece veri transferi için gerekli clock sinyali üretilmiş olur. Sahte veri kullandığımız yer burasıdır. Slave bir bayt veri iletmeye hazır olduğunda, master slave’e bir bayt değersiz(sahte) veri iletir (MOSI). Slave’e her bir sahte veri biti gönderildiğinde, slave master’a bir bit gerçek veri gönderir (MISO).
Daha detaylandıracak olursak; master cihaz slave cihaza veri gönderdiğinde, slave cihaz, içinde bulunan SPDR(SPI Data Register)’ye veri yazar ve master cihaz bu veriyi okur. Veri alma işlemi bu şekilde gerçekleşir.
SPI.begin();
SPI haberleşmesini başlatır. Bu fonksiyon, SCK ve MOSI'yi düşük voltaj seviyesine, SS'yi ise yüksek voltaj seviyesine çekerek SPI veri yolunu başlatır. Varsayılan SPI yapılandırması, Mod-0'da 4MHz baud hızındadır.
SPI.end();
Bu fonksiyon pin modlarını değiştirmeden SPI veri yolunu devre dışı bırakır.
SPI.beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode));
NOT: SPI veri yolunu başlatır. Bunu çağırmadan önce SPI.begin();'i çağırmak gerekir.
Bazen farklı cihazlar için farklı SPI ayarları kullanmamız gerekebilir. Örneğin; bir cihaz SPI_MODE0 kullanırken başka bir cihazın SPI_MODE3 kullanması gibi bir durum olabilir. Ya da cihazlardan biri yalnızca 1MHz'de çalışabilirken aynı veri yolundaki bir bellek yongası 12MHz'de çalışabilir. Bellek yongasına giden ve bellek yongasından gelen veri miktarı çok büyük olabileceğinden tüm işlemlerimizi 1MHz hızda sınırlamak istemeyebiliriz. Bu durumlarda, her işlemi SPI.beginTransaction(); ve SPI.endTransaction(); komutlarını kullanarak kendi kurulumuyla çalıştırabiliriz.
speedMaximum : Maksimum SPI hızını belirler. 15 MHz'de bir çip kullanıyorsanız, 15000000 olarak yazılır. Arduino, SPISettings ile kullandığınız sayıya eşit veya daha düşük olan en iyi hızı otomatik olarak kullanacaktır.
dataOrder : Verilerin önce MSB’den başlayıp LSB’de bitecek şekilde mi gönderileceğini ya da tam tersi şeklinde mi gönderileceğini belirler. Bu kısma MSBFIRST veya LSBFIRST ifadesi yazılır.
dataMode : SPI iletişim modunu belirler. Clock sinyalinin düşük seviyede mi yüksek seviyede mi boşta olduğunun, verinin yükselen kenarda mı düşen kenarda mı alınıp/gönderileceğinin belirlendiği modlardan biri seçilir. Bu modlar; SPI_MODE0, SPI_MODE1, SPI_MODE2 veya SPI_MODE3’tür.
Örnek:
SPI.beginTransaction(SPISettings(15000000, MSBFIRST, SPI_MODE0));
SPI.endTransaction();
Bu fonksiyon SPI veri yolunun kullanımını durdurmak için kullanılır. Bu fonksiyon, diğer kütüphanelerin SPI veri yolunu kullanmasına izin vermek için çip seçimini devre dışı bıraktıktan sonra çağrılır.
SPI.setClockDivider();
Clock sinyali bölücüsüdür. Kartın, yani sistem frekansını bölerek, SPI iletişimindeki clock sinyalini belirler. AVR tabanlı kartlarda bu bölme işlemi 2, 4, 8, 16, 32, 64 veya 128'e kadar yapılabilir. Varsayılan SPI bölme ayarı 4’tür. Yani 16 MHz'deki kartlar için 4 Mhz’dir.
SPI.setClockDivider(bölme);
“bölme” parametresi sadece AVR tabanlı kartlarda aşağıdaki ifadeleri alabilir:
SPI_CLOCK_DIV2
SPI_CLOCK_DIV4
SPI_CLOCK_DIV8
SPI_CLOCK_DIV16
SPI_CLOCK_DIV32
SPI_CLOCK_DIV64
SPI_CLOCK_DIV128
SPI.transfer():
Bu fonksiyon master ve slave arasında eş zamanlı veri gönderip almak için kullanılır. Eş zamanlı bir gönderme ve alma işlemi olduğu için, bir bayt veri gönderdiğimizde, bir bayt veri de alırız. Alınan veriler receivedVal'da döndürülür.
receivedVal = SPI.transfer(deger); //1 baytlık veri gönderir-alır.
receivedVal16 = SPI.transfer16(deger2); //2 baytlık veri gönderir-alır.
SPI.transfer(dizi, size); //veri dizisi gönderir.
Örnek:
SPI.transfer(36);
SPI.transfer(0x12);
SPI.transfer(0b01101101);
SPI.attachInterrupt(fonksiyon);
SPI kesmesini etkinleştirir. Master cihazdan slave cihaza veri transferi tamamlandığında, slave cihazda çalışacak fonksiyonu belirler.
SPI.usingInterrupt(kesme_numarası)
Program bir kesme içinde SPI işlemleri gerçekleştirecekse, kesme numarasını veya adını SPI kütüphanesine kaydetmek için bu işlev çağrılır. Bu, SPI.beginTransaction()'ın kullanım çakışmalarını önlemesini sağlar. usingInterrupt(); çağrısında belirtilen kesmenin beginTransaction(); çağrısında devre dışı bırakılacağını ve endTransaction()'da yeniden etkinleştirileceğini unutmayın.
SPI Kayıtçıları
AVR tabanlı kartlar, SPI iletişimini yapılandırmak için; SPI Kontrol Kayıtçısı (SPCR), SPI Durum Kayıtçısı (SPSR) ve SPI Veri Kayıtçısı (SPDR) olmak üzere üç adet kayıtçı kullanır.
1. SPI Kontrol Kayıtçısı (SPCR)
SPCR Kaydının varsayılan değeri 0x00'dır.

Bit 7 - SPIE : SPI kesme etkinleştirme bitidir. 1 ise etkin 0 ise pasiftir.
Bit 6 - SPE : SPI Etkinleştirme bitidir. 1 ise etkin 0 ise pasiftir.
Bit 5 - DORD : Veri Sırası bitidir. 1 ise önce LSB iletilir. 0 ise önce MSB iletilir.
Bit 4 - MSTR : Master/Slave modu seçim bitidir. 1 ise Master modu, 0 ise Slave modudur.
Bit 3 - CPOL : Saat polaritesi seçim bitidir. Saat sinyalinin boşta kalma durumu seçim bitidir. 0 ise; saat düşük voltaj seviyesinde boştadır. 1 ise; saat yüksek voltaj seviyesinde boştadır.
Bit 2 - CPHA : Saat fazı seçim bitidir. Verilerin saat sinyalinin kenarlarına göre ne zaman alınacağını ve gönderileceğini belirler. 0 ise; veriler yükselen kenarda alınır, düşen kenarda gönderilir. 1 ise; veriler düşen kenarda alınır, yükselen kenarda gönderilir.
SPI Modu | CPOL | CPHA | Saat Boştayken Mantık Durumu | Alma/Gönderme Saat Fazı |
0 | 0 | 0 | Düşük voltaj | Yükselen kenarda alma, düşen kenarda gönderme |
1 | 0 | 1 | Düşük voltaj | Düşen kenarda alma, yükselen kenarda gönderme |
2 | 1 | 0 | Yüksek voltaj | Düşen kenarda alma, yükselen kenarda gönderme |
3 | 1 | 1 | Yüksek voltaj | Yükselen kenarda alma, düşen kenarda gönderme |
Bit 1:0 - SPR1 ve SPR0 : Saat frekansı bölme bitleridir. Bu kayıtçıdaki iki bitle birlikte SPSR kayıtçısında bulunan SPI2X bitiyle birlikte bölme miktarı belirlenir. Aşağıdaki tablodaki gibi:
SPI2X | SPR1 | SPR0 | Saat frekansı |
0 | 0 | 0 | F/4 |
0 | 0 | 1 | F/16 |
0 | 1 | 0 | F/64 |
0 | 1 | 1 | F/128 |
1 | 0 | 0 | F/2 |
1 | 0 | 1 | F/8 |
1 | 1 | 0 | F/32 |
1 | 1 | 1 | F/64 |
SPI Durum Kaydı (SPSR)
Kayıtçıdaki bitlere yazma komutları:
SPCR |= _BV(SPE); // Enable SPI mode.
SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); // Enable SPI mode, Enable master mode, Set clock rate fck/16
SPCR = 0b11010000; // SPIE, SPE, MSTR 1 olarak ayarlandı
2. SPI Durum Kayıtçısı (SPSR)

Bit 7 – SPIF: SPI kesme işareti biti. Seri veri transferi tamamlandığında bu bayrak set edilir. Master modunda SS pini düşük voltaja sürüldüğünde de aynı durum gerçekleşir.
Bit 6 – WCOL: Data transferi sırasında SPDR kayıtçısına veri yazma işlemi olduğunda bu bit 1 olur.
Bit 5:1 – Ayrılmış Bitler. Bu bitler ayrılmış bitlerdir ve her zaman sıfır olarak okunurlar.
Bit 0 – SPI2X: Çift SPI Hızı biti. Bu bit ayarlandığında SPI hızı (SCK Frekansı) iki katına çıkar.
3. SPI Veri Kayıtçısı (SPDR)

Bu kayıtçı okuma/yazma kayıtçısıdır. Data transferi için kullanılır. Master’dan slave’ye veri gönderildiğinde veri, slave cihazın SPDR’sine kaydolur ve slave cihaz veriyi buradan okuyarak gerekli işlemi yapar. Master cihaz, slave cihaza veri göndereceği zaman ise, veriyi kendi SPDR’sine gönderir ve master cihaz veriyi buradan okur.