پروتکل رابطه وسایل جانبی در آردوینو (SPI) ،  یک رابط سریال است که از ۴ سیم برای ارتباط بین میکروکنترلرها و تراشه ها یا تجهیزات جانبی استفاده می کند. معمولا به جای ۴ سیم از ۳ سیم استفاده می شود. یک سیم برای دریافت داده، یک سیم برای ارسال داده، یک سیم برای همزمان سازی و یک سیم هم برای انتخاب تراشه برای شروع ارسال مورد استفاده قرار می گیرد. ارتباط SPI یک ارتباط تمام دو طرفه (full duplex) است به این معنا که به صورت همزمان هم میتوانیم داده ارسال کنیم و هم داده دریافت کنیم. حداکثر نرخ ارسال بیت یا باود ریت در این پروتکل از I2C بالاتر است.

    پایه های SPI

    در ارتباط SPI از ۴ سیم به شرح زیر استفاده می شود :

    • SCK : سیگنال کلاک که توسط مستر ایجاد می شود.
    • MOSI : سیگنال خروجی از مستر و ورودی به اسلیو که توسط مستر ارسال می شود.
    • MISO : سیگنال خروجی از اسلیو و ورودی به مستر که توسط مستر ارسال می شود.
    • SS : سیگنال انتخاب اسلیو می باشد.

    از توابع زیر برای ارتباط SPI استفاده می شود، قبل از آن نیز باید کتابخانه SPI.h به برنامه اضافه شود :

    • ()begin : انجام تنظیمات اولیه SPI ، تنظیم پایه های SCK ، MOSI و SS به حالت خروجی، صفر کردن پایه های SCK و MOSI ، یک کردن پایه SS
    • (setClockDivider(divider : از این تابع برای تنظیم کلاک ارتباط SPI نسبت به کلاک اصلی میکروکنترلر استفاده می شود. در بردهای مبتنی بر AVR عدد divider میتواند مقادیر ۲, ۴, ۸, ۱۶, ۳۲, ۶۴ و ۱۲۸ باشد. به صورت پیشفرض این عدد روی ثابت SPI_CLOCK_DIV4 تنظیم شده است که باعث می شود یک چهارم کلاک میکروکنترلر به ارتباط SPI اختصاص داده شود. (مثلا در بردهای با فرکانس میکروکنترلر ۲۰MHz فرکانس SPI برابر ۵MHz می شود.)
    • Divider : برای این متغیر میتوان از یکی از ثبات های زیر استفاده نمود :

    SPI_CLOCK_DIV2, SPI_CLOCK_DIV4, SPI_CLOCK_DIV8, SPI_CLOCK_DIV16, SPI_CLOCK_DIV32, SPI_CLOCK_DIV64, SPI_CLOCK_DIV128

    • (transfer(val : از این تابع برای ارسال و دریافت همزمان داده استفاده می شود. مقدار دریافت شده در متغیر receivedVal ذخیره سازی می شود.
    • ((beginTransaction(SPISettings(speedMaximum, dataOrder, dataMode : متغیر speedMaximum برابر کلاک است، dataOrder (دارای دو حالت MSBFIRST یا LSBFIRST  و dataMode (دارای چهار حالت SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3)

    برای ارتباط SPI 4 حالت داریم که عبارت اند از :

    • Mode 0 : (حالت ۰) (به صورت پیشفرض)

    در این حالت کلاک به صورت عادی صفر است CPOL = 0 و از داده ها در لبه بالارونده سیگنال نمونه برداری می شود (لبه صعودی) (CPHA = 0) .

    در این حالت کلاک به صورت عادی صفر است  CPOL = 0 و از داده ها در لبه پایین رونده سیگنال نمونه برداری می شود (لبه نزولی) (CPHA = 1) .

    در این حالت کلاک به صورت عادی یک است  CPOL = 1 و از داده ها در لبه بالارونده سیگنال نمونه برداری می شود (لبه صعودی) (CPHA = 0) .

    در این حالت کلاک به صورت عادی یک است  CPOL = 1 و از داده ها در لبه پایین رونده سیگنال نمونه برداری می شود (لبه نزولی) (CPHA = 1) .

    • (attachInterrupt(handler  : از این تابع در اسلیو برای دریافت داده های ارسال شده از سمت مستر استفاده می شود.

    حال میخواهیم دو برد آردوینو UNO را از طریق ارتباط SPI به یکدیگر وصل کنیم، یکی را به عنوان مستر و دیگری را به عنوان اسلیو تعریف می کنیم.

    • (ss) : پایه ۱۰
    • (MOSI) : پایه ۱۱
    • (MISO) : پایه ۱۲
    • (SCK) : پایه ۱۳

    پایه زمین بین دو برد مشترک است. شکل زیر نحوه اتصال بین دو برد را نشان می دهد :

    پروتکل رابطه وسایل جانبی در آردوینو (SPI)

    مثال زیر کدهای نمونه برای مستر و اسلیو را نشان می دهد :

    SPI به عنوان مستر

    مثال :

    #include <SPI.h>
    
    void setup (void) {
     Serial.begin(115200); //set baud rate to 115200 for usart
     digitalWrite(SS, HIGH); // disable Slave Select
     SPI.begin ();
     SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
    }
    
    void loop (void) {
     char c;
     digitalWrite(SS, LOW); // enable Slave Select
     // send test string
     for (const char * p = "Hello, world!r" ; c = *p; p++) {
     SPI.transfer (c);
     Serial.print(c);
     }
     digitalWrite(SS, HIGH); // disable Slave Select
     delay(2000);
    }

    SPI به عنوان اسلیو

    مثال :

    #include <SPI.h>
    char buff [50];
    volatile byte indx;
    volatile boolean process;
    
    void setup (void) {
     Serial.begin (115200);
     pinMode(MISO, OUTPUT); // have to send on master in so it set as output
     SPCR |= _BV(SPE); // turn on SPI in slave mode
     indx = 0; // buffer empty
     process = false;
     SPI.attachInterrupt(); // turn on interrupt
    }
    ISR (SPI_STC_vect) // SPI interrupt routine { 
     byte c = SPDR; // read byte from SPI Data Register
     if (indx < sizeof buff) {
     buff [indx++] = c; // save data in the next index in the array buff
     if (c == 'r') //check for the end of the word
     process = true;
     }
    }
    
    void loop (void) {
     if (process) {
     process = false; //reset the process
     Serial.println (buff); //print the array on serial monitor
     indx= 0; //reset button to zero
     }
    }
    
    

    خیلی ممنون از اینکه  آموزش پروتکل رابطه وسایل جانبی در آردوینو (SPI) را در میکرو دیزاینر الکترونیک دنبال کردید. برای مشاهده تمامی جلسات آموزش آردوینو اینجا کلیک کنید.

    دیگر جلسات این آموزش

© تمامی حقوق مطالب برای وبسایت آلفا باکس محفوظ است و هرگونه کپی برداری بدون ذکر منبع ممنوع و شرعا حرام می باشد.
قدرت گرفته از : بک لینکس