반응형






아래 처럼 두 보드를 연결해주었습니다..


raspberry pi 2/3         Atmega128 

(MOSI)  19       ------ PB2(MOSI)

(MISO)  21      ------ PB3(MISO)

(SCK)   23       ------ PB1(SCK) 

(CS0)   24        ------ PB0    

      GND 6      ------ GND



라즈베리파이에서 SPI를 활성화 시키기 위해서는 다음 포스팅을 참고하세요..

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


라즈베리파이에서 데이터를 보내면... 



AVR과 연결된 피시의 시리얼 터미널에서 데이터가 들어온 것을 볼 수 있습니다.. 



다음은 각각 Atmega128을 위한 슬레이브 SPI 코드 및 라즈베리파이에서의 SPI 코드입니다..

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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
 * spi_slave.c
 *
 * Created: 2016-06-28
 * Author : webnautes
 */ 
 
 #define F_CPU 16000000UL
 
 //1. baud rate를 선택
 #define USART_BAUDRATE 9600
 
 //2.시스템 클록과 원하는 baud rate를 이용하여 UBRR 값을 계산한다.
 #define UBRR_VALUE (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)
 
#include <avr/io.h>
#include <avr/interrupt.h>
 
 
void usartInit()
{
    //3. UBRR0은 16비트 레지스터이기 때문에 8비트씩 나누어서 넣어야 한다.
    UBRR0H = (uint8_t)(UBRR_VALUE>>8);
    UBRR0L = (uint8_t) UBRR_VALUE;
    
    //4. USART 설정
    UCSR0C |= (1<<UCSZ00)|(1<<UCSZ01); //Charecter size : 8비트
    UCSR0C &= ~(1<<USBS0); //stop  bit : 1비트
    UCSR0C &= ~((1<<UPM01)|(1<<UPM00)); // no parity mode
    
    //5. 송수신을 가능하게 한다.
    UCSR0B=(1<<RXEN0)|(1<<TXEN0);
}
 
void transmitByte(uint8_t data) {
    
    //이전 전송이 끝나기를 기다림
    while(!(UCSR0A&(1<<UDRE0))){};
    
    UDR0 = data;                                            /* send data */
}
 
uint8_t receiveByte(void) {
    // 수신 되기를 기다림
    while(!(UCSR0A&(1<<RXC0))){};
    return UDR0;                                /* return register value */
}
 
 
void printString(volatile unsigned char str[]) {
    uint8_t i = 0;
    while (str[i]!='\0') {
        transmitByte(str[i]);
        i++;
    }
}
 
void readString(char str[], uint8_t maxLength) {
    char response;
    uint8_t i;
    i = 0;
    while (i < (maxLength - 1)) {                   /* prevent over-runs */
        response = receiveByte();
        transmitByte(response);                                    /* echo */
        if (response == '\r') {                     /* enter marks the end */
            break;
        }
        else {
            str[i] = response;                       /* add in a letter */
            i++;
        }
    }
    str[i] = 0;                          /* terminal NULL character */
}
 
void  init_SPI( ) {
    
    DDRB &= ~((1<<PB1)|(1<<PB2)|(1<<PB0)); // SCK, MOSI, SS --> inputs
    DDRB |= (1<<PB3);                  // MISO --> output
    
    //slave mode
    SPCR &= ~(1<<MSTR);
    
    //16000KHz / 16 
    SPCR  |= (1<<SPR0);
    
    //enable SPI
    SPCR |= ((1<<SPE)|(1<<SPIE));
 
}
 
 
 
 
unsigned char SPI_write(unsigned char cData) {
    SPDR = cData;
    while ( !(SPSR & (1<<SPIF))) ;
    return SPDR;
}
 
unsigned char SPI_read( void ) {
    SPDR = 0x0;
    while ( !(SPSR & (1<<SPIF))) ;
    return SPDR;
}
 
 
 
volatile unsigned char str[100];
 
 
ISR(SPI_STC_vect)
{
    static uint8_t idx=0;
    unsigned char ch = SPDR;
 
    if ( ch == '\0' )
    {
        str[idx]='\0';
        printString(str);
        idx=0;
    }
    else {
            str[idx]=ch;
            idx++;
    }    
 
 
}
 
int main (void)
{
    init_SPI();
    usartInit();
    sei();
    
    while(1)
    {
 
 
    }
}
 
 
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
102
#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 = 1000000;
static uint16_t delay=0;
 
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 test0";
    transfer(fd, buf, ARRAY_SIZE(buf));
 
    close(fd);
 
 
    return ret;
}
cs


반응형

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

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


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

+ Recent posts