SPI Haberleşme ve Arduino ile SPI Ağ Kurma

Merhabalar…

Bu konuda SPI haberleşmenin ne olduğuna ve 3 Arduino arasında SPI haberleşme protokolü ile ağ kurup haberleştirmeye değineceğiz.

Öncelik SPI haberleşmenin ne olduğuna bakalım.

Açılımı Serial Peripheral Interface olan ve full dublex olarak çalışan bir haberleşme tekniğidir. Buradaki Full dublex’ in anlamı veri alma ve gönderme işlemini eş zamanlı olarak gerçekleştirebilmesidir. İletişim Master ve slave cihalar arasında gerçekleşir. Master cihaz iletişim kurmak istediği cihazı seçer ve o cihazla iletişime geçer. Bu seçme işini SPI donanımı dahilinde olan SS(Slave Select) pini ile yapar. Master cihazda SS pini kendimiz belirlememiz mümkün ancak slave cihazların SPI donanımında dahil olan SS pini kullanılmalıdır. Bunun sebebini ve nasıl yapıldığını aşağıda değineceğiz.

  SPI iletişimi iki cihaz arası basit olarak şekildeki gibidir. Donanım dahilinde olan pinlerin ne oldukları tablodaki gibidir.

 

 

Adsız  SCK haberleşme için kare dalga oluşturur. İletişim bu sinyalin farklı konumlarında  gerçekleşebilir. Master cihaz kare dalgayı oluşturması gereken cihazdır.

MOSI haberleşme de Master cihazdan Slave cihazlara giden  veri yolunu oluşturur.

MISO haberleşme de Slave cihazdan Master cihaza giden veri yolunu oluşturur.

SS yukarıda da belirttiğimiz gibi Master cihazın Slave cihazları seçmesine yarar. 2 cihaz iletişimi için tek SS pini yeterlidir. Burada dikkat edilmesi gereken donanımda SS pinin üzeri çizgi olmasıdır. Bu çizgi slave seçimi için pinin Ljik-0′ a çekilmesi gerektiğini gösterir.

SPI, I2C gibi iletişim tekniklerine göre daha hızlıdır. 2 den fazla cihaz için bile olsa adresleme gibi işlemler gerektirmez(I2C’ den ayıran özellik). Aynı kablo üzerinden farklı cihazlara farklı verileri aktarabilir (RS-232 den ayıran özellik).

Şimdi gelelim SPI ile birden fazla cihaz arasında iletişim kurmaya.

 Artık Slave cihazlarımızın sayısı arttı. Bu yüzden Slave Select Pin sayımızı da arttırmamız gerekir. Yadaki resimde 1 Master ve 3 Slave cihaz arası iletişim gösterilmiştir. 3 Slave cihaz olduğu için 3 SS pini toplamda 6 pin kullandık. Bunu basit bir formülle N tane cihaz için 3 + N tane pin kullanılması gerekir şeklinde düşünebiliriz.

Şekildeki tüm cihazlarda tek SPI donanımı olduğunu farz edelim. Bu durumda master cihaz tek SS pinine sahip demektir. Ancak 3 cihaz ile iletişime geçmemiz gerektiğinden kendimiz SS pinleri belirlemeli ve onları Slave cihazların SPI donanımında bulunan SS pinlerine bağlamamız gerekir. Bu işlem için denetleyicimizin herhangi bir dijital pinini çıkış olarak tanımlayıp, Lojik durumunu veri aktarmak istediğimiz cihaza bağlı olana göre değiştirmemiz yeterlidir. Ancak Slave cihazların bu çağrıya cevap verebilmeleri için kesinlikle donanımsal SS pinleri kullanılmalıdır. Aksi taktirde iletişim gerçekleşmez.

İletişimin Arduino kısmına gelelim. SPI iletişim için Arduino hazır bir kütüphane bulunmakta. Ancak bu kütüphane Arduino her zaman master konumda olacağı düşünülerek hazırlanmış ve iki Arduino arası iletişim için yeterli değildir. Bizde bu yüzden slave cihazlar için yazılımda kütüphanenin içine girmemiz gerekecek.

Ağmızı basit şekilde kuracağız Serial Monitörden yazdığımız veriyi SPI diğer Arduino’ lara aktaracak onlarda belirlediğimiz sıra ile bize veriyi geri döndürecekler. Ağda bulunması gereken Master cihaz için gerekli kod şu şekilde..

#include <SPI.h>

byte gidenVeri;
byte gelenVeri;

int ssPin1 = 8;  //Slave Select1 LOW seviyede aktif eder
int ssPin2 = 9;  //Slave Select2 LOW seviyede aktif eder

void setup()
{
  Serial.begin(115200);   //Seri haberlşemeyi başlattık
  
  //SS leri çıkış ayarladık
  pinMode(ssPin1, OUTPUT);
  pinMode(ssPin2, OUTPUT);
  digitalWrite(ssPin1, HIGH);
  digitalWrite(ssPin2, HIGH);
  //SPI başlatıldı
  SPI.begin();
}

void loop()
{
  //seri haberleşme varken SPI ile veri gönderildi
  while(Serial.available() > 0)
  {
    gidenVeri = Serial.read();
    gelenVeri = spiVeriOkuYaz(gidenVeri, ssPin1);
    Serial.write(gelenVeri);
    gelenVeri = spiVeriOkuYaz(gidenVeri, ssPin2);
    Serial.write(gelenVeri);
  }
}

//spi veriyi göndermek için fonksiyon
//parametre olarak gönderilecek veriyi ve SS pini verilir
byte spiVeriOkuYaz(byte dout, int pin)
{
  byte din;
  digitalWrite(pin, LOW);
  delay(1);
  din = SPI.transfer(dout);
  digitalWrite(pin, HIGH);
  return din;
}

 

Şimdi gelelim Slave cihazlara. Önceden de belirttiğimiz gibi Arduino’ yu Slave olarak kullanabilmek için SPI kütüphanesinin içerisine girmemiz gerekli. SPI kütüphanesinin veri aktarımı için kullandığımız register’ lere bi bakalım.

SPDR(SPI Data Register): Bu register  SPI hattında aktarılacak veriyi tutar.

SPSR(SPI Status Register): SPI durumunu belirten register. Bit kaydırma işlemi ile sırada aktarılacak veri olup olmadığı kontrol edilebilir.

SPCR(SPI Control Register): SPI başlangıç ayarlarının yapıldığı register’ dir. İnterrupt setleme ve master slave ayarı bu register üzerinden yapılır. Aşağıdaki resimde bu registerin bitlerini görebilirsiniz.Adsız

 

 

Slave cihaz veri göndermek için Master cihazdan SS pinin aktif etmesini bekleyecektir. Bu pinin aktif olması durumunda da SPI Interreupt’ u devreye girip veriyi kaydedecek sonraki iletişimde geri gönderecektir. Burdan da anlaşılacağı gibi ilk iletişim denemesi NULL değer döndürecektir.

Şimdide Slave cihazların Kodları..

byte gonderilenVeri;
byte dataToPc;

void setup()
{
  Serial.begin(115200);
  
  pinMode(MISO, OUTPUT);
  pinMode(SS , INPUT);
  
  //SPI Control Register
  
  //İnterreupt setlenip Slave mod ayarlanır///////
  
  SPCR  |= 0b11000000;
  //SPI status register
  SPSR  |= 0b00000000;
  
  gonderilenVeri = 0;
  dataToPc = 0;
  
  sei();    //interreupt lar aktif edilir
}  

void loop()
{
  if(dataToPc != 0)
  {
    Serial.write(dataToPc);
    dataToPc = 0;
  }
}

ISR(SPI_STC_vect)
{
  cli();    //interreuplar sıfırlarınır
  
  //SS pinin LOW iken yaz
  while(digitalRead(SS) == 0)
  {
      SPDR = gonderilenVeri;
      
      //SPI aktarımı bitene kadar bekle
      while(!(SPSR & (1 << SPIF)));
      
      gonderilenVeri = SPDR;
  }
  
  sei();
}

 

 

spi

Bağlantı şemamız basit. herhangi bir ek elemana ihtiyaç yok. Sadece 3 adet Arduino ile iletişimi gerçekleştireceğiz. Bu konuda az kaynak bulunmakta ve bende yeniyim eksiğimiz veya hatamız varsa affola ..

Teşekkürler..

19 Comments

Add a Comment

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir