SPI (Serial Peripheral Interface), 1980'lerin ortalarında Motorola (günümüzde NXP) tarafından geliştirilmiş, senkron, tam çift yönlü (full-duplex) ve ana cihaz / ikincil cihaz (Master / Slave) mimarisine dayanan yüksek hızlı bir seri haberleşme protokolüdür. Ekranlar (TFT, OLED), SD kartlar, Ethernet modülleri (W5500 gibi) ve yüksek hızlı sensörlerin mikrokontrolcülerle haberleşmesinde yaygın olarak kullanılır.

SPI protokolü temel olarak 4 adet dijital sinyal hattı (ve ortak GND) üzerinden çalışır. I2C'nin aksine hatlar Push-Pull yapısındadır ve harici Pull-Up dirençlerine ihtiyaç duymaz:

SPI'da verinin saat sinyalinin neresinde örneklenip (sample) neresinde değiştirileceğini (shift) belirleyen iki temel parametre vardır:
| SPI Modu | CPOL (Polarite) | CPHA (Faz) | Saat Boşta Seviyesi | Veri Örnekleme Kenarı |
|---|---|---|---|---|
| Mode 0 | 0 | 0 | LOW (0) | Yükselen Kenar (Leading Edge) |
| Mode 1 | 0 | 1 | LOW (0) | Düşen Kenar (Trailing Edge) |
| Mode 2 | 1 | 0 | HIGH (1) | Düşen Kenar (Leading Edge) |
| Mode 3 | 1 | 1 | HIGH (1) | Yükselen Kenar (Trailing Edge) |
0xFF) veri yazılması gerekir.
Çoklu cihaz bulunan ortamlarda SPI ayarlarının (hız, mod, bit sırası) çakışmaması için SPISettings ve beginTransaction yapısı kullanılır:
#include <SPI.h>
const int CS_PIN = 10; // Slave Select Pini
// 4 MHz Saat Hızı, MSBFIRST (Önce En Yüksek Bit), SPI Mode 0 Yapılandırması
SPISettings spiAyarlari(4000000, MSBFIRST, SPI_MODE0);
void setup() {
Serial.begin(115200);
pinMode(CS_PIN, OUTPUT);
digitalWrite(CS_PIN, HIGH); // CS pasif (HIGH)
SPI.begin(); // Donanımsal SPI Veryolunu Başlat
}
// SPI Register Yazma Fonksiyonu
void registerYaz(uint8_t regAdres, uint8_t veri) {
SPI.beginTransaction(spiAyarlari); // SPI Oturumunu Başlat
digitalWrite(CS_PIN, LOW); // Cihazı Seç (CS = 0)
SPI.transfer(regAdres); // Register Adresini Gönder
SPI.transfer(veri); // Veriyi Gönder
digitalWrite(CS_PIN, HIGH); // Cihaz Seçimini Kaldır (CS = 1)
SPI.endTransaction(); // SPI Oturumunu Kapat
}
// SPI Register Okuma Fonksiyonu (Full-Duplex Mantığı)
uint8_t registerOku(uint8_t regAdres) {
uint8_t okunanVeri = 0;
SPI.beginTransaction(spiAyarlari);
digitalWrite(CS_PIN, LOW);
SPI.transfer(regAdres | 0x80); // Okuma Biti (Örn: MSB bitini 1 yapma kuralı)
okunanVeri = SPI.transfer(0x00); // Dummy Veri Göndererek Gelen Yanıtı Oku
digitalWrite(CS_PIN, HIGH);
SPI.endTransaction();
return okunanVeri;
}
void loop() {
registerYaz(0x20, 0x55);
delay(500);
uint8_t val = registerOku(0x20);
Serial.printf("Okunan Register Değeri: 0x%02X\n", val);
delay(2000);
}
| Avantajları (+) | Dezavantajları (−) |
|---|---|
| Yüksek Hız: 10 MHz - 80 MHz+ bant genişliklerine kolayca ulaşabilir. | Fazla Pin Kullanımı: Her yeni cihaz için ek bir CS pini gerektirir. |
| Tam Çift Yönlü (Full-Duplex): Veri aynı anda hem gönderilebilir hem alınabilir. | Donanımsal Onay (ACK) Yok: Verinin karşı tarafa ulaşıp ulaşmadığı protokol seviyesinde denetlenmez. |
| Basit Donanım Yapısı: Adresleme karmaşası yoktur, transistör ve protokol işleme yükü düşüktür. | Çoklu Master Zorluğu: Çoklu Master desteği resmi olarak zayıftır, hat çakışmaları riski yüksektir. |
| Düşük Güç Tüketimi: Hatlarda sürekli Pull-Up üzerinden akım çekilmez (Push-Pull mimari). | Kısa Mesafe: Sinyaller yükselen hat kapasitansından etkilenir, uzun mesafelere taşınamaz. |
Henüz yorum yapılmamış. İlk yorumu siz yapın!