Arduino - SPI Haberleşme - Elektrik Elektronik Projeleri

Post Top Ad

4 Mayıs 2015 Pazartesi

Arduino - SPI Haberleşme

Bu yazıda cihazlar arası SPI haberleşmesinden, SPI protokolünden ve SPI.h kütüphanesinden bahsedeceğim. Örnek olarak iki arduinonun birbirleriyle SPI protokolünde haberleşmesini gerçekleştireceğim.
Devre:
Arduino Uno için SCK pini 13 nolu pindir, MISO pini 12 nolu pindir, MOSI pini 11 nolu pindir ve SS pini 10 nolu pindir. Arduino MEGA 2560 için ise SCK 52, MISO 50, MOSI 51 ve SS 53 nolu pinlerdir.

Arduino Uno ve Arduino Mega arasında yapılacak haberleşme için bağlantı şeması:

SPI Haberleşmesi:
Motorola firması tarafından geliştirilmiş bir senkron seri haberleşme protokolüdür. Kısa mesafelerde, hızlı veri alışverişi için kullanılmaktadır. İsmini Serial Perihpheral Interface kelimelerinin baş harflerinden almaktadır. Veri iletimi çift yönlü olarak sağlanmaktadır. Veriler byte’lar halinde gönderilir / alınır. Verilerin gönderilmesi ve alınması clock sinyali ile senkronize bir şekilde gerçekleşir.

SPI haberleşmede aygıtlar birbirleriyle master – slave ilişkisi içerisinde haberleşirler. Haberleşme master’ın kontrolünde gerçekleşir. Master aygıt haberleşme yapacağı aygıtı seçer ve ikisi arasındaki haberleşmeyi başlatır.

SPI, 4 sinyal hattından oluşur. Bunlar:
  • MISO / SDO – Master Input Slave Output / Serial Data Out
  • MOSI / SDI – Master Output Slave Input / Serial Data In
  • SCK (SCLK) – Serial Clock
  • SS / CS – Slave Select Pin / Chip Select
Master ve slave’ler arasındaki bağlantı aşağıdaki gibidir:
MISO, verinin slave’den master’a doğru aktığı hattır. MOSI ise verinin master’dan slave’e doğru aktığı hattır. SS pini master’ın veri alışverişinde bulunacağı slave’i seçtiği pindir. Master’ın haberleşeceği slave’i seçmesi, slave’in bağlı olduğu SS pininin master tarafından lojik-0 yapılması ile olur. SCK clock sinyallerinin geçtiği hattır. Clock’lar master tarafından üretilir. MISO ve MOSI hatlarından veri akışı bu clock sinyallerine senkronize olarak gerçekleşir.
SPI haberleşmede, veri iletiminin clock sinyalinin düşen kenarında mı yoksa yükselen kenarında mı olacağını ve veri iletiminin olmadığı durumlarda clock sinyalinin lojik-0 mı yoksa lojik-1 mi olarak bekleyeceğini belirlediğimiz 4 tane mod bulunmaktadır. Bu modları tanımlarken CPOL ve CPHA ifadeleri kullanılır. CPOL (clock polarity), clock sinyalinin polaritesini belirtir. CPOL =0 ise, veri iletimi olmadığında clock sinyali lojik-0 konumundadır, CPOL = 1 ise veri iletimi yokken clock sinyali lojik-1 konumundadır. CPHA (clock phase) ifadesi ise clock sinyalinin fazını belirler. CPHA, CPOL değeriyle birlikte, veri iletiminin clock sinyalinin düşen kenarında mı yoksa yükselen kenarında mı olacağını ifade eder. Eğer CPOL = 0 iken, CPHA = 0 ise, veri iletimi clock sinyalinin yükselen kenarında olacaktır, CPHA = 1 ise veri iletimi clock sinyalinin düşen kenarındadır. Eğer CPOL = 1 iken CPHA = 0 ise, veri iletimi clock sinyalinin düşen kenarındadır, CPHA = 1 ise, veri iletimi clock sinyalinin yükselen kenarındadır.
Microchip PIC ve ARM tabanlı mikrodenetleyiciler için SPI mod tablosu:
Motorola firması ve diğer mikrodenetleyiciler için SPI mod tablosu:
SPI.h Kütüphanesi
Arduinoda SPI haberleşmeyi gerçekleştirmemizi sağlayan kütüphanedir. Bu kütüphanenin bazı fonksiyonlarını tanımlayacak olursak:

SPI.begin()

SPI iletişimini başlattığımız komuttur.

SPI.setClockDivider()

SPI clock’unu ayarladığımız fonksiyondur. Normalde SPI_CLOCK_DIV4 değerindedir. Bunu, fonksiyonun içine yazdığımız parametre ile değiştirebiliriz. Aldığı parametre değerleri:
  • SPI_CLOCK_DIV4
  • SPI_CLOCK_DIV8
  • SPI_CLOCK_DIV16
  • SPI_CLOCK_DIV32
  • SPI_CLOCK_DIV64
  • SPI_CLOCK_DIV128
SPI.transfer()

SPI hattına veri gönderip, aldığımız komuttur. Parametre olarak göndereceğimiz veriyi gireriz. Tek seferinde bir byte veri gönderebiliriz. Bir byte’tan fazla büyüklükteki verileri tek tek göndeririz.

SPI.attachInterrupt()

SPI veri transferinde meydana gelecek kesmeyi aktif ettiğimiz ifadedir.

SPI haberleşmede kullandığımız bazı register’lar:
  • SPCR (SPI Control Register) : SPI haberleşme için başlangıç ayarlarını yaptığımız register’dir. Master – Slave başlatma ayarı bu register’den yapılır.
  • SPDR (SPI Data Register) : Yazılan ve okunan verinin tutulduğu register’dir.
Master’dan slave’e veri gönderme:

int x = 10; 
SPI.transfer(x);

Slave’in master’dan gelen veriyi alması:

SPI.attachInterrupt(); 
ISR (SPI_STC_vect)
{
  byte x = SPDR;
}
     
Kodlar:

  • Master olarak seçilen arduino’nun kodları:
#include <SPI.h>

void setup (void)
{
  digitalWrite(SS, HIGH);
  SPI.begin ();
  SPI.setClockDivider(SPI_CLOCK_DIV8);
}

void loop (void)
{
  char c;
  const char * p = "Merhaba!\n" ;

  digitalWrite(SS, LOW);

  for (*p; c = *p; p++) {
    SPI.transfer (c);
  }

  digitalWrite(SS, HIGH);

  delay (1000);
}

  • Slave olarak seçilen arduinonun kodları:
#include <SPI.h>

char gelenVeri [100];
volatile byte i;
volatile boolean veriGelmisse;

void setup (void)
{
  Serial.begin (9600);

  pinMode(MISO, OUTPUT); // master in slave out

  SPCR |= _BV(SPE); // slave mod için register ayarı

  i = 0;
  veriGelmisse = false;

  SPI.attachInterrupt(); // SPI veri geldiğinde oluşacak kesme
}

ISR (SPI_STC_vect)
{
  byte c = SPDR; //SPI data register'ine kaydedilen veriler alınıyor
  if (i < sizeof gelenVeri)
  {
    gelenVeri [i++] = c;
    if (c == '\n')
      veriGelmisse = true;
  }
}

void loop (void)
{
  if (veriGelmisse)
  {
    gelenVeri [i] = 0; 
    Serial.println (gelenVeri);
    i = 0;
    veriGelmisse = false;
  }
}

4 yorum:

  1. Elinize Sağlık. Bir konu bu kadar güzel ve açık anlatılır.
    Teşekkürler...

    YanıtlaSil
  2. hocam bunun çıktısı girdiğiniz metin tamamı br satırı yazıldıktan sonra alt satıra mı iniyor, yoksa her harfi tek tek bastıktan sonra her harften sonra bi alt satıra mı iniyor

    YanıtlaSil

Post Top Ad