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

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

پایه های SPI

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

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

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

  • ()begin : انجام تنظیمات اولیه SPI ، تنظیم پایه های SCK ، MOSI و SS به حالت خروجی، صفر کردن پایه های SCK و MOSI ، یک کردن پایه SS
  • (setClockDivider(divider : از این تابع برای تنظیم کلاک ارتباط SPI نسبت به کلاک اصلی میکروکنترلر استفاده می شود. در بردهای مبتنی بر AVR عدد divider میتواند مقادیر 2, 4, 8, 16, 32, 64 و 128 باشد. به صورت پیشفرض این عدد روی ثابت SPI_CLOCK_DIV4 تنظیم شده است که باعث می شود یک چهارم کلاک میکروکنترلر به ارتباط SPI اختصاص داده شود. (مثلا در بردهای با فرکانس میکروکنترلر 20MHz فرکانس SPI برابر 5MHz می شود.)
  • 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 : (حالت 0) (به صورت پیشفرض)

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

  • Mode 1 : (حالت 1)

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

  • Mode 2 : (حالت  2)

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

  • Mode 3 : (حالت  3)

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

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

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

  • (ss) : پایه 10
  • (MOSI) : پایه 11
  • (MISO) : پایه 12
  • (SCK) : پایه 13

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

پروتکل رابطه وسایل جانبی در آردوینو (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) را در میکرو دیزاینر الکترونیک دنبال کردید. برای مشاهده تمامی جلسات آموزش آردوینو اینجا کلیک کنید.

مطلب پیشنهادی:  نصب بوت لودر روی ATmega328 با آردوینو UNO

اگر این نوشته‌ برایتان مفید بود لطفا کامنت بنویسید.

مطالعه دیگر جلسات این آموزش<< جلسه قبلی                    

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

4 دیدگاه

  1. با دورود بشما مهندس عزیز
    خیلی خیلی عالی

  2. سلام وقت بخیر
    آیا استفاده همزمان از پروتکل SPI و I2C امکان پذیر نیست؟