Arduino/SPI 통신
SPI의 기본적인 연결하기
DesignatedRoom
2020. 11. 5. 18:12
채널은 Address로, Level은 값으로 사용한다.
하드웨어의 연결은 두 아두이노 간의 D10 ~ D13까지 핀들을 각 각 연결한다.
Master 소스 코드
더보기
// MOSI D11
// MISO D12 Master In Slave Out
// SCK D13
// SS D10 칩 셀렉트
// SPI Master : Sender
// 마스터는 데이터를 읽는 입장이다.
#include <SPI.h>
#define CHIP_SELECT 10 // HIGH면 칩 셀렉트가 선택 안된 상태. LOW이면 선택된 상태
void setup() {
// put your setup code here, to run once:
SPI.begin();
pinMode(CHIP_SELECT,OUTPUT);
digitalWrite(CHIP_SELECT,HIGH); // 슬레이브 선택이 안 된 상태
SPI.setClockDivider(SPI_CLOCK_DIV16); // 분주비 설정. DIV16는 16Mhz
}
void loop() {
// put your main code here, to run repeatedly:
if (Serial.available())
{
char data = Serial.read();
// Master가 Slave에게 데이터를 보내야 한다.
// 누구한테 줄지 select를 해야한다. chip select
digitalWrite(CHIP_SELECT,LOW);
// 전송 코드가 들어올 코드 시작
char recv = SPI.transfer(0);
// 전송 코드가 들어올 코드 끝
digitalWrite(CHIP_SELECT,HIGH); // 다시 HIGH로 변경
Serial.println(recv);
}
}
Slave 소스 코드
더보기
// SPI Slave
#include <SPI.h>
#define CHIP_SELECT 10 // HIGH면 칩 셀렉트가 선택 안된 상태. low이면 선택된 상태
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(MOSI,INPUT); // Digital 11번 핀
pinMode(MISO,OUTPUT); // Digital 12번 핀
pinMode(SCK,OUTPUT); // Digital 13번 핀
pinMode(CHIP_SELECT, INPUT); // 선택은 슬레이브에서 해야 한다. 마스터는 받아들이는 입장
SPI.setClockDivider(SPI_CLOCK_DIV16); // 분주비 설정. DIV16는 16Mhz
// SPI통신에서 레지스터의 설정 하기
// SPI를 활성화
SPCR |= _BV(SPE); // _BV는 함수
// Slave모드로 변경
SPCR &= _BV(MSTR);
// 인터럽트를 허용해야 한다.
SPCR |= _BV(SPIE);
}
void loop() {
// put your main code here, to run repeatedly:
//delay(1000);
}
// SPI통신은 인터럽트를 이용해서 데이터를 수신한다.
ISR(SPI_STC_vect)
{
SPDR = '0';
}
위의 내용은 잘 되지 않는다. 아래의 소스는 검증이 끝났다.
마스터 슬레이브 쪽의 시리얼 통신의 시리얼 모니터로 각 자 모두 hello가 뜬다.
두 아두이노의 전원을 각 자 공급만 하고 서로 D10~D13번핀만 서로 연결한다.
Master 소스 코드
더보기
// SPI통신 master 10~13핀 그대로 연결한다.
// 선은 그대로 한다.
// 슬레이브에 아예 전원을 공급하지 않고 해보자.
#include <SPI.h>
#define chipSelect 10//HIGH 슬레이버 선택되지 않은 상태, LOW 선택된 상태
void setup() {
Serial.begin(9600);
SPI.begin();
pinMode(chipSelect, OUTPUT);
digitalWrite(chipSelect,HIGH);//슬레이브 선택 안된 상태
SPI.setClockDivider(SPI_CLOCK_DIV16); //DIV16=16Mhz DIV8=8Mhz
}
byte data;
void loop() {
char p[10]="hello\n";
//master->slave chip select
digitalWrite(chipSelect,LOW);
//master->slave전송코드
for(int i=0;i<6;i++)
{
data=SPI.transfer(p[i]);
Serial.print((char)data);
//SPI.transfer(p[i]);
}
digitalWrite(chipSelect,HIGH);
//delay(1000);
}
Slave 소스 코드
더보기
// spi slaver
#include <SPI.h>
#define chipSelect 10
void setup() {
pinMode(MOSI,INPUT);//D11번 핀
pinMode(MISO,OUTPUT);//D12번 핀
pinMode(SCK,OUTPUT);//D13번 핀
pinMode(chipSelect,INPUT); // CHIP SELECT
SPI.setClockDivider(SPI_CLOCK_DIV16);
//SPI통신 레지스터 설정
//SPI 활성화
SPCR |=_BV(SPE);
//슬레이브모드 변경
SPCR &=~_BV(MSTR);
//인터럽트 허용
SPCR |=_BV(SPIE);
Serial.begin(9600);
}
volatile byte c;
void loop() {
if(c!='_'){
Serial.print((char)c);
c='_';
}
//delay(1000);
}
//spi통신은 인터럽트를 이용해서 데이터 수신
ISR(SPI_STC_vect){
c=SPDR;
//SPDR='a';
}