반응형

라즈베리파이에서 디폴트로 SPI가 비활성화 되어있기 때문에 활성화 시켜주는 작업이 필요합니다. 다음 포스팅을 참고하세요..

[임베디드/Raspberry Pi] - Raspberry Pi 2/3에서 SPI 사용하기


라즈베리파이 보드와 아두이노를 다음처럼 연결해줍니다.

Raspberry Pi 2/3          Arduino UNO 

(MOSI)  19       ------   11(MOSI)

(MISO)  21      ------   12(MISO)

(SCK)   23       ------   13(SCK)

     GND 6       ------    GND


아두이노 IDE에 다음 코드를 복사한 후,  아두이노에 업로드 시켜줍니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <SPI.h>  
   
char buf [100];  
volatile byte pos = 0;  
volatile boolean printIt = false;  
#define   spi_enable()   (SPCR |= _BV(SPE))  
  
  
void setup (void)  
{  
  //시리얼 통신 초기화  
  Serial.begin (9600);  
   
  //Master Input Slave Output 12번핀을 출력으로 설정  
  pinMode(MISO, OUTPUT);  
    
  //slave 모드로 SPI 시작   
  spi_enable();  
   
  //인터럽트 시작  
  SPI.setClockDivider(SPI_CLOCK_DIV64); //250kHz   
  SPI.setDataMode(SPI_MODE0);  
  SPI.attachInterrupt();  
   
}   
   
   
// SPI 인터럽트 루틴  
ISR (SPI_STC_vect)  
{  
  // SPI 데이터 레지스터로부터 한바이트 가져옴  
  byte c = SPDR;    
    
  //버퍼에 자리가 있다면...  
  if (pos < sizeof buf)  
  {  
    buf[pos++= c;  
      
    // 출력을 진행한다.   
     if (c == '\0')  
      printIt = true;        
   }   
}    
   
  
void loop (void)  
{  
  if (printIt)  
    {  
        buf[pos] = 0;    
        Serial.println (buf);  
        pos = 0;  
        printIt = false;  
    }    
      
}  
cs


라즈베리파이에서 다음 코드를 컴파일 시켜 줍니다. 

1
pi@raspberrypi:~ $ gcc spi_test.c -o spi_test
cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include <stdint.h>  
#include <unistd.h>  
#include <stdio.h>  
#include <stdlib.h>  
#include <getopt.h>  
#include <fcntl.h>  
#include <sys/ioctl.h>  
#include <linux/types.h>  
#include <linux/spi/spidev.h>  
  
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))  
  
static void pabort(const char *s)  
{  
    perror(s);  
    abort();  
}  
  
static const char *device = "/dev/spidev0.0";  
static uint8_t mode;  
static uint8_t bits = 8;  
static uint32_t speed = 250000;  
static uint16_t delay;  
  
static void transfer(int fd, char* tx, int len)  
{  
    int ret;  
    uint8_t rx[256];  
    struct spi_ioc_transfer tr = {  
        .tx_buf = (unsigned long)tx,  
        .rx_buf = (unsigned long)rx,  
        .len = len,  
        .delay_usecs = delay,  
        .speed_hz = speed,  
        .bits_per_word = bits,  
    };  
  
    ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr);  
    if (ret < 1)  
        pabort("can't send spi message");  
 
    for (ret = 0; ret < len; ret++)   
        printf("%c", rx[ret]);  
    puts("\n");  
}  
  
  
int main(int argc, char *argv[])  
{  
    int ret = 0;  
    int fd;  
  
  
    fd = open(device, O_RDWR);  
    if (fd < 0)  
        pabort("can't open device");  
  
    /* 
     * spi mode 
     */  
    ret = ioctl(fd, SPI_IOC_WR_MODE, &mode);  
    if (ret == -1)  
        pabort("can't set spi mode");  
  
    ret = ioctl(fd, SPI_IOC_RD_MODE, &mode);  
    if (ret == -1)  
        pabort("can't get spi mode");  
  
    /* 
     * bits per word 
     */  
    ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits);  
    if (ret == -1)  
        pabort("can't set bits per word");  
  
    ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits);  
    if (ret == -1)  
        pabort("can't get bits per word");  
  
    /* 
     * max speed hz 
     */  
    ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);  
    if (ret == -1)  
        pabort("can't set max speed hz");  
  
    ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);  
    if (ret == -1)  
        pabort("can't get max speed hz");  
  
    printf("spi mode: %d\n", mode);  
    printf("bits per word: %d\n", bits);  
    printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000);  
 
    char buf[]="echo test";  
    transfer(fd, buf, ARRAY_SIZE(buf));  
  
    close(fd);  
  
    return ret;  
}
cs


아두이노 IDE의 메뉴에서 도구 - 시리얼 모니터를 선택하여 시리얼 모니터를 실행시켜 놓고 라즈베리파이에서 컴파일한 프로그램을 실행시켜줍니다. 

라즈베리파이에서 실행한 프로그램은  "echo test" 문자열을 spi를 이용해 아두이노로 전송 후, 종료합니다.


시리얼 모니터를 보면 "echo test" 문자열이 출력된 걸 볼 수 있습니다.


라즈베리 파이에서  "echo test" 문자열을 SPI를 이용해서 아두이노로 보내면 ,  아두이노는 해당 문자열을  받아 시리얼로 보내어 시리얼 모니터에 "echo test"가 출력되게 됩니다. 


반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts