-
SPI의 기본적인 연결하기Arduino/SPI 통신 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'; }