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

TODAY654 TOTAL2,927,075
사이트 이용안내
Login▼/회원가입
최신글보기 질문게시판 기술자료 동영상강좌

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


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

페이지 정보

작성자 master 작성일2018-07-02 10:09 조회15,043회 댓글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

조회수 15,043

등록된 댓글이 없습니다.

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

MCU, AVR, 아두이노 등 전자공학에 관련된 질문을 무료회원가입 후 작성해주시면 전문가가 답변해드립니다.
ATMEGA128PWMLED초음파
아두이노AVR블루투스LCD
UART모터적외선ATMEGA
전체 스위치 센서
질문게시판 목록
제목 작성자 작성일 조회
답변 답변글 답변 : 아두이노 시리얼 통신 질문 master 18-07-13 8549
질문 자동차 PID제어 질문 master 18-07-13 7843
질문 아두이노 외부전압 질문 master 18-07-13 9159
질문 아두이노 코드 질문입니다 zxxuxvmau 18-07-12 8315
답변 답변글 답변 : 아두이노 코드 질문입니다 master 18-07-12 8405
질문 아두이노 키트 질문드립니다.댓글[4] 밥솥 18-07-12 16799
질문 모터 제어 질문 뽕보 18-07-11 7916
답변 답변글 답변 : 모터 제어 질문 master 18-07-11 7786
답변 답변글 답변 : 답변 : 모터 제어 질문댓글[1] 뽕보 18-07-11 9855
질문 아두이노와 라즈베리파이 중 어떤 것을 하는것이 좋을까요? master 18-07-11 7999
질문 pic16f877a 외부 인터럽트 질문 master 18-07-11 7754
질문 아두이노 코딩 합치기 질문 master 18-07-11 10158
질문 아두이노 코딩 질문입니다댓글[1] 비공개 18-07-10 8616
질문 스탭모터 제어 뽕보 18-07-10 7848
답변 답변글 답변 : 스탭모터 제어댓글[2] master 18-07-10 11133
질문 아두이노 컴파일 오류 질문 master 18-07-10 8676
질문 for문에서 i++와 ++i의 차이 질문 master 18-07-10 8907
질문 동화 bhs-800/s 자외선살균소독기 램프가없어서 알수가 없어요 master 18-07-10 9809
질문 아두이노 블루투스 모터제어 질문 master 18-07-10 8956
질문 아두이노 LED 쉬프트 코드 질문 master 18-07-10 9485
질문 리눅스 두가지질문입니다댓글[1] 찐찐형 18-07-09 10575
질문 아두이노 메가보드 스텝모터 6개 연결, usb 유선 연결, 스마트폰 앱으로 스텝모터 구동 질문 master 18-07-09 12017
질문 피에조 센서 질문 master 18-07-09 9159
질문 ATmega 128코드비전 스위치 질문 master 18-07-09 10996
질문 아두이노 delay말고 count 변수나 다른방법을 사용해서 반복하게 할 수 있나요? master 18-07-09 12291
질문 아두이노 센서 질문 master 18-07-09 8996
질문 아두이노 네오픽셀 2개 동시 구동 질문 master 18-07-09 10651
질문 UART 통신 질문합니다댓글[3] 비공개 18-07-09 14630
질문 아두이노 조명 체크 네오픽셀 구동 질문 master 18-07-08 9342
질문 아두이노 펄스의 개수를 세는 코드 질문 master 18-07-08 11186
게시물 검색

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
모바일버전으로보기