질문게시판 > 아두이노 간 SPI 통신 질문

TODAY9,724 TOTAL3,602,222
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

아두이노 센서 ATMEGA128 PWM LED 초음파 AVR 블루투스 LCD UART 모터 적외선


BASIC4MCU | 질문게시판 | 아두이노 간 SPI 통신 질문

페이지 정보

작성자 master 작성일2018-07-02 10:09 조회17,203회 댓글0건

본문

	

아두이노간에 SPI 통신을 이용해서 데이터를 송, 수신 하려고 하는데 master , slave 을 짜봤는데 이 프로그램에서 데이터가 어떻게 송, 수신 되어지는지 궁금합니다 그리고  혹시 잘못된게 있는지 알려주세요 

내공 1000 드립니다
1,2 번째 사진 Slave 3번째 사진 Master첨부 이미지

첨부 이미지

첨부 이미지

//

//
//-----------master code-----------
//
#include <SPI.h>
//
void setup(void){
  SPI.begin();// SPI 통신 초기화
  digitalWrite(SS,HIGH);                // 슬레이브가 선택되지 않은 상태로 유지
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 안정적인 전송을 위해 분주비를 높여 전송 속도를 낮춤
  Serial.begin(9600);
}
//
void loop(void){
  if(Serial.available()){
    char data=Serial.read();         // 데이터 입력 확인
    if(data=='0'){
      digitalWrite(SS,LOW);          // 슬레이브를 선택한다.
      char received=SPI.transfer(0); // 1바이트 데이터 수신을 위해 의미 없는 1바이트 데이터를 전송한다.
      digitalWrite(SS,HIGH);         // 슬레이브 선택을 해제한다.
      Serial.println(received);
    }
  }
}
//-----------slave code-----------
//
#include <SPI.h>
byte num;
//
void setup(void){
  pinMode(MISO,OUTPUT); pinMode(MOSI,INPUT); pinMode(SCK,INPUT); pinMode(SS,INPUT); // SPI 통신을 위한 핀들의 입출력 설정
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 마스터의 전송 속도에 맞추어 통신 속도를 설정한다.
  SPCR|= _BV(SPE);                      // SPI 활성화 // SPI 통신을 위한 레지스터를 설정
  SPCR&=~_BV(MSTR);                     // Slave 모드 선택
  SPCR|= _BV(SPIE);                     // 인터럽트 허용
  num='A';// 카운터 초기화
}
//
ISR(SPI_STC_vect){ // SPI 통신으로 데이터가 수신될 때 발생하는 인터럽트 처리 루틴
  SPDR=num;        // 카운터 값을 ASCII 값으로 전달
}
//
void loop(void){
  num=(num+1); // 카운터 값 증가 'A' ~ 'Z'
  if(num>'Z')num='A';
  delay(1000);
}

 

http://www.makewith.co/page/project/985/story/2338/
질문 예제는 아니지만 비슷한 내용의 예제입니다.
링크와 같은 예제를 여기서 추가적으로 설명하고 있습니다.

이 글에서는 기술적인 내용을 볼 수 있습니다.

Examples

 

아두이노 레퍼런스 사이트에는 두 종류의 예제가 있습니다.
이 예제들은 아두이노끼리 통신하는 예제가 아니고 주변장치를 읽어들이는 예제입니다.


SPI 라이브러리는 슬레이 모드를 지원하지 않습니다.
라이브러리 헤더파일에도 slave 단어가 검색되지 않죠

 

마스터 모드 설정
void setup(void){
  SPI.begin();// SPI 통신 초기화
  digitalWrite(SS,HIGH);                // 슬레이브가 선택되지 않은 상태로 유지
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 안정적인 전송을 위해 분주비를 높여 전송 속도를 낮춤
}
//
슬레이브 모드 설정
void setup(void){
  pinMode(MISO,OUTPUT); pinMode(MOSI,INPUT); pinMode(SCK,INPUT); pinMode(SS,INPUT); // SPI 통신을 위한 핀들의 입출력 설정
  SPI.setClockDivider(SPI_CLOCK_DIV16); // 마스터의 전송 속도에 맞추어 통신 속도를 설정한다.
  SPCR|= _BV(SPE);                      // SPI 활성화 // SPI 통신을 위한 레지스터를 설정
  SPCR&=~_BV(MSTR);                     // Slave 모드 선택
  SPCR|= _BV(SPIE);                     // 인터럽트 허용
}

 

이 때문에 마스터에 비해서 슬레이브 코드가 지저분합니다.

 

//
//-----------master code-----------
//
#include <SPI.h>
//
char received;
//
void setup(void){
  SPI.begin();
  digitalWrite(SS,HIGH);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  Serial.begin(9600);
}
//
void loop(void){
  if(Serial.available()){
    char data=Serial.read();
    if(data=='0'){
      digitalWrite(SS,LOW); received=SPI.transfer(0); digitalWrite(SS,HIGH);
      Serial.println(received);
    }
  }
}
//-----------slave code-----------
//
#include <SPI.h>
//
byte num='A';
//
void setup(void){
  pinMode(MISO,OUTPUT); pinMode(MOSI,INPUT); pinMode(SCK,INPUT); pinMode(SS,INPUT);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPCR=_BV(SPE)|_BV(SPIE); // 슬레이브 모드, 수신인터럽트
}
//
ISR(SPI_STC_vect){
  SPDR=num;
}
//
void loop(void){
  if(++num>'Z')num='A'delay(1000); // 카운터 값 증가 'A' ~ 'Z'
}

 

동작을 이해한다면 주석을 없애는 것이 머리가 덜 복잡해집니다.

 

위 예제는
1. 마스터의 시리얼모니터에서 '0'을 입력하면
2. 마스터에서 아무(쓰레기) 데이터를 1바이트 전송하고
3. 슬레이브에서 알파벳 대문자를 차례대로 증가 시키면서 1바이트 전송합니다.
4. 마스터에서는 이 값을 받아서 시리얼 모니터에 출력합니다.
간단한 내용이죠

마스터에서 데이터를 송신하고 않아도 계속해서 슬레이브가 알파벳을 증가시키는 오류가 있습니다.

 

//
//-----------master code-----------
//
#include <SPI.h>
//
char received;
//
void setup(void){
  SPI.begin();
  digitalWrite(SS,HIGH);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  Serial.begin(9600);
}
//
void loop(void){
  if(Serial.available()){
    char data=Serial.read();
    if(data=='0'){
      digitalWrite(SS,LOW); received=SPI.transfer(0); digitalWrite(SS,HIGH);
      Serial.println(received);
    }
  }
}
//-----------slave code-----------
//
#include <SPI.h>
//
byte num='A';
char flag=0;
//
void setup(void){
  pinMode(MISO,OUTPUT); pinMode(MOSI,INPUT); pinMode(SCK,INPUT); pinMode(SS,INPUT);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPCR=_BV(SPE)|_BV(SPIE); // 슬레이브 모드, 수신인터럽트
}
//
ISR(SPI_STC_vect){
  SPDR=numflag=1;
}
//
void loop(void){
  if(flag){ flag=0if(++num>'Z')num='A'; } // 카운터 값 증가 'A' ~ 'Z'
}

 

flag 변수를 사용해서 데이터를 받았을 때만 알파벳을 증가 시키도록 동기화 시켰습니다.

 

역활을 반대로 바꿔서 시켜보죠
1. 마스터에서 알파벳 대문자를 차례대로 1초에 1바이트씩 전송하면
2. 슬레이브에서 수신한 후
3. 슬레이브의 시리얼 모니터에 출력

 

//
//-----------master code-----------
//
#include <SPI.h>
//
byte num='A';
char received;
//
void setup(void){
  SPI.begin();
  digitalWrite(SS,HIGH);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
}
//
void loop(void){
  delay(1000);
  digitalWrite(SS,LOW); received=SPI.transfer(num); digitalWrite(SS,HIGH);
  if(++num>'Z')num='A'// 카운터 값 증가 'A' ~ 'Z'
}
//-----------slave code-----------
//
#include <SPI.h>
//
byte num;
char flag=0;
//
void setup(void){
  pinMode(MISO,OUTPUT); pinMode(MOSI,INPUT); pinMode(SCK,INPUT); pinMode(SS,INPUT);
  SPI.setClockDivider(SPI_CLOCK_DIV16);
  SPCR=_BV(SPE)|_BV(SPIE); // 슬레이브 모드, 수신인터럽트
  Serial.begin(9600);
}
//
ISR(SPI_STC_vect){
  num=SPDRflag=1;
}
//
void loop(void){
  if(flag){ flag=0Serial.println(num); }
}

 

동작시켜보지 않았으니 돌려보세요​

  • BASIC4MCU 작성글 SNS에 공유하기
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글 0

조회수 17,203

등록된 댓글이 없습니다.

질문게시판HOME > 질문게시판 목록

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
질문 전선 허용 전압 계산 질문 master 18-09-01 10417
질문 아두이노 무선송신 질문 master 18-09-01 10489
질문 아두이노 호환보드 질문 master 18-09-01 11678
질문 아두이노 추가 라이브러리 질문 master 18-09-01 11410
질문 블루투스 단위 질문 master 18-09-01 10123
질문 아두이노 엔코더 해상도와 분해능, 펄스 수 질문 master 18-09-01 12217
질문 C언어 코드 (마찰력코드) 질문 master 18-09-01 11426
질문 아두이노 진동센서와 서보모터 질문 master 18-09-01 11524
질문 적외선 온도 교정 장치(blackbody) 관련 질문 띵인 18-08-30 11921
답변 답변글 답변 : 적외선 온도 교정 장치(blackbody) 관련 질문댓글[2] master 18-08-30 23788
질문 5V 1A~2A 전원공급장치 질문 master 18-08-29 10767
질문 아두이노 질문 하나만 해도될까요?댓글[1] 아두맨 18-08-28 11782
질문 아두이노 개폐연결장치 구동에 대해 질문드립니다.댓글[1] 비공개 18-08-27 15028
질문 서보모터가 찡찡 거리면서 오작동합니다. 비공개 18-08-26 11241
답변 답변글 답변 : 서보모터가 찡찡 거리면서 오작동합니다.댓글[9] 이미지 master 18-08-26 60516
질문 아두이노 블루투스 dc모터 제어댓글[1] 비공개 18-08-24 15309
질문 c언어에서 %2d가 뭔가요? master 18-08-24 36959
질문 ft232r 장치 관리자 master 18-08-24 11619
질문 전기자전거 배터리 전류 질문 이미지 master 18-08-24 10032
질문 C언어 10진수 정수형 변환문자열 질문 master 18-08-24 9744
질문 이 LED는 어디에 어떻게 연결해서 사용해야하는건가요? master 18-08-23 15445
질문 c언어 0과 null 구분 master 18-08-23 12930
질문 8051 ADC 컨버터댓글[1] 디코랩 18-08-23 11305
질문 아두이노 블루투스연결댓글[6] 이미지첨부파일 비공개 18-08-23 39944
질문 8051과 적외선센서와 ADC rohyunge 18-08-22 10951
답변 답변글 답변 : 8051과 적외선센서와 ADC master 18-08-22 10658
질문 온도센서 DS18S20 회로댓글[3] 이미지 rohyunge 18-08-22 20237
질문 EPROM 라이팅 방법 문의 master 18-08-21 10700
질문 PLD 와 MCU의 차이? master 18-08-21 10654
질문 Led smps 회로 질문 master 18-08-20 11650
게시물 검색

2022년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2021년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2020년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2019년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
2018년 1월 2월 3월 4월 5월 6월 7월 8월 9월 10월 11월 12월
Privacy Policy
MCU BASIC ⓒ 2020
모바일버전으로보기