[마이크로 프로세서] SPI 통신

이현준·2020년 11월 25일
0

SPI 통신

설명

• SPI는 1:N 통신을 지원하는 동기식 통신 방식이다
• SPI 통신을 위해서는 반드시 하나의 마스터와 하나 이상의 슬레이브 기기가 존재해야 한다.
• 통신을 위해서는 최소 4개의 선이 필요하다.
• MOSI : Master Out, Slave In – 마스터에서 데이터를 출력하기 위한 신호 선
• MISO : Master In, Slave Out – 슬레이브에서 데이터를 출력하기 위한 신호 선
• SCK : Clock 신호 선
• SS : Slave Select – 데이터를 송수신할 슬레이브를 선택하기 위한 신호 선
• 데이터를 전송하고 수신하는 선이 따로 있기 때문에 전송과 수신이 동시에 이루어질 수 있어서 송수신이 하나의 선으로 이루어
지는 I2C 통신에 비해 속도가 빠르다.
• 마스터에서 출력하는 선과 슬레이브에서 출력하는 선이 정해져 있다.
• 속도가 빠르다는 장점 때문에 SPI는 주로 빠른 데이터 전송 속도를 필요로 하는 데에 많이 사용된다. 대표적으로 이더넷 통신이
나 SD 쉴드.
• SPI 통신 역시 I2C 통신처럼 하나의 마스터에 여러 개의 슬레이브가 연결될 수 있기 때문에, 슬레이브를 선택하기 위한 솔루션
이 필요하게 되는데, SPI는 그 방법으로 SS 신호를 사용하고 있다.
• SS는 Slave Select라는 뜻 그대로 슬레이브를 선택하는 선으로, 하나의 슬레이브에 하나의 SS 선을 사용한다

SCK와 MOSI, MISO 신호 선은 공통으로 사용한다. 
여러 개의 슬레이브 기기가 마스터에 연결될 수 있지만, 슬레이브 개수만큼 SS 신호 선이 늘어나게 되므로 여러 개의 슬레이브가 존재할 때에는 물리적으로 비효율적이다.  
동기화 통신 방식이므로 통신에는 클럭 신호가 사용되며, 클럭 신호는 마스터에서만 출력된다. 

데이터 송수신을 위해 먼저 SS 신호로 슬레이브를 선택한 후 클럭 신호를 생성하고, 클럭 신호에 맞춰 데이터를 전송한다.
데이터를 전송하는 중에도 MISO 신호 선으로 슬레이브의 데이터가 수신될 수 있다. 
전송과 수신이 동시에 이루어질 수 있다는 것이 SPI의 가장 큰 장점
SPI 통신에서는 HIGH로 바뀔 때 데이터를 읽을 지 LOW로 바뀔 때 데이터를 읽을 지 지정할 수 있다. 
클럭 신호가 HIGH로 먼저 시작하는지, LOW로 먼저 시작하는지 결정할 수 있다 . 
슬레이브와 방식이 동일해야 한다.

주의사항

SPI통신은 Thinker cad에서는 시뮬레이션이 안된다. 시도하지 말것

master 아두이노

#include<SPI.h>                             //Library for SPI 
#define LED 7           
#define ipbutton 2
int buttonvalue;
int x;
void setup (void){
  Serial.begin(115200);                   //Starts Serial Communication at Baud Rate 115200 
  pinMode(ipbutton,INPUT);                //Sets pin 2 as input 
  pinMode(LED,OUTPUT);                    //Sets pin 7 as Output
   SPI.begin();                            //Begins the SPI commnuication
  SPI.setClockDivider(SPI_CLOCK_DIV8);    //Sets clock for SPI communication at 8 (16/8=2Mhz)
  digitalWrite(SS,HIGH);                  // Setting SlaveSelect as HIGH (So master doesnt connnect with slave)
}
void loop(void){
  byte Mastersend,Mastereceive;          
  buttonvalue = digitalRead(ipbutton);   //Reads the status of the pin 2
  if(buttonvalue == HIGH)                //Logic for Setting x value (To be sent to slave) depending upon input from pin 2
  {
    x = 1;
  } else {
    x = 0;
  }
    digitalWrite(SS, LOW);                  //Starts communication with Slave connected to master
    Mastersend = x;                            
  Mastereceive=SPI.transfer(Mastersend); //Send the mastersend value to slave also receives value from slave
    if(Mastereceive == 1)                   //Logic for setting the LED output depending upon value received from slave
  {
    digitalWrite(LED,HIGH);              //Sets pin 7 HIGH
    Serial.println("Master LED ON");
  }
  else
  {
   digitalWrite(LED,LOW);               //Sets pin 7 LOW
   Serial.println("Master LED OFF");
  }
  delay(1000);
}

slave 아두이노

#include<SPI.h>
#define LEDpin 7
#define buttonpin 2
volatile boolean received;
volatile byte Slavereceived,Slavesend;
int buttonvalue;
int x;
void setup()

{
  Serial.begin(115200);
  
  pinMode(buttonpin,INPUT);               // Setting pin 2 as INPUT
  pinMode(LEDpin,OUTPUT);                 // Setting pin 7 as OUTPUT
  pinMode(MISO,OUTPUT);                  //Sets MISO as
  SPCR |= _BV(SPE);                       //Turn on SPI in Slave Mode
  received = false;

  SPI.attachInterrupt();                  //Interuupt ON is set for SPI commnucation
  
}

ISR (SPI_STC_vect)                        //Inerrrput routine function 
{
  Slavereceived = SPDR;         // Value received from master if store in variable slavereceived
  received = true;                        //Sets received as True 
}

void loop()
{ if(received)                            //Logic to SET LED ON OR OFF depending upon the value recerived from master
   {
      if (Slavereceived==1) 
      {
        digitalWrite(LEDpin,HIGH);         //Sets pin 7 as HIGH LED ON
        Serial.println("Slave LED ON");
      }else
      {
        digitalWrite(LEDpin,LOW);          //Sets pin 7 as LOW LED OFF
        Serial.println("Slave LED OFF");
      }
      
      buttonvalue = digitalRead(buttonpin);  // Reads the status of the pin 2
      
      if (buttonvalue == HIGH)               //Logic to set the value of x to send to master
      {
        x=1;
        
      }else
      {
        x=0;
      }
      
  Slavesend=x;                             
  SPDR = Slavesend;                           //Sends the x value to master via SPDR 
  delay(1000);
}
}

0개의 댓글