● 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) ; // 카운터 값 증가