Arduino

아두이노 간 SPI 통신하기 - 마스터 슬레이브 통신

작성자 임베디드코리아 작성일25-05-16 00:42 조회173회 댓글0건

첨부파일

● SPI(Serial Peripheral Interface)
• SPI는 1:N 통신을 지원하는 동기식 통신 방식이다
• SPI 통신을 위해서는 반드시 하나의 마스터와 하나 이상의 슬레이브 기기가 존재해야 한다.
• 통신을 위해서는 최소 4개의 선이 필요하다.
• MOSI : Master Out, Slave In – 마스터에서 데이터를 출력하기 위한 신호 선
• MISO : Master In, Slave Out – 슬레이브에서 데이터를 출력하기 위한 신호 선
• SCK : Clock 신호 선
• SS : Slave Select – 데이터를 송수신할 슬레이브를 선택하기 위한 신호 선
• 데이터를 전송하고 수신하는 선이 따로 있기 때문에 전송과 수신이 동시에 이루어지므로 속도가 빠르다.

----- < SPI 마스터 소스 코드 > ------------------------------
#include <SPI.h>
void setup (void)
{
  SPI.begin (); // SPI 통신 초기화
  digitalWrite(SS, HIGH); // 슬레이브가 선택되지 않은 상태로 유지
  // 안정적인 전송을 위해 분주비를 높여 전송 속도를 낮춤
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  Serial.begin(9600);
}
void loop (void)
{
  byte Mastersend,Mastereceive;
  if(Serial.available()){
    char data = Serial.read(); // 데이터 입력 확인
    if(data == 'K'){
      digitalWrite(SS, LOW); // 슬레이브를 선택한다.
      Mastersend = 0;
      // 1바이트 데이터 수신을 위해 의미 없는 1바이트 데이터를 전송한다.
      Mastereceive = SPI.transfer(Mastersend);
      digitalWrite(SS, HIGH); // 슬레이브 선택을 해제한다.
      Serial.println(Mastereceive);
    }
  }
}
#include <SPI.h>
void setup (void)
{
  SPI.begin (); // SPI 통신 초기화
  digitalWrite(SS, HIGH); // 슬레이브가 선택되지 않은 상태로 유지
  // 안정적인 전송을 위해 분주비를 높여 전송 속도를 낮춤
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  Serial.begin(9600);
}
void loop (void)
{
  byte Mastersend,Mastereceive;
  if(Serial.available()){
    char data = Serial.read(); // 데이터 입력 확인
    if(data == 'K'){
      digitalWrite(SS, LOW); // 슬레이브를 선택한다.
      Mastersend = 0;
      // 1바이트 데이터 수신을 위해 의미 없는 1바이트 데이터를 전송한다.
      Mastereceive = SPI.transfer(Mastersend);
      digitalWrite(SS, HIGH); // 슬레이브 선택을 해제한다.
      Serial.println(Mastereceive);
    }
  }
}

▶ 마스터에서 보내고, 슬레이브로 부터 받는다.



----- < SPI 슬레이브 소스 코드 > ------------------------------
▶ 마스터로 부터 받으면, 바로 보내 짐
#include <SPI.h>
byte count;

void setup (void)
{
  // SPI 통신을 위한 핀들의 입출력 설정
  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);
  pinMode(SCK, INPUT);
  pinMode(SS, INPUT);
  // 마스터의 전송 속도에 맞추어 통신 속도를 설정한다.
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  // SPI 통신을 위한 레지스터를 설정
  SPCR |= _BV(SPE); // SPI 활성화
  SPCR &= ~_BV(MSTR); // Slave 모드 선택
  SPCR |= _BV(SPIE); // 인터럽트 허용
  count = '0'; // 카운터 초기화
}
// SPI 통신으로 데이터가 수신될 때 발생하는 인터럽트 처리 루틴
ISR (SPI_STC_vect)
{
  SPDR = count;  // 카운터 값을 ASCII 값으로 전달
}
void loop (void)
{
  count = (count + 1) ; // 카운터 값 증가

  delay(1000);
}