ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 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';
     }

     

    댓글

Designed by Tistory.