Hallo, ich bin noch ziemlich am Anfang was uC angeht und habe Probleme mit einer SPI Verbindung zwischen einem Atmega8(Master) und einem Attiny2313(Slave). Eigentlich sollte der Master immer eine 0 oder 1 senden und eine LED am Slave ein- bzw. ausschalten, leider passiert nichts. Den Slave Select nutze ich noch nicht und auf das ACK soll in meinem Beispiel auch nicht reagiert werde. Die Beispiele unten habe ich abgewandelt. Anregungen zum Code hatte ich mir hier geholt: http://maxembedded.com/2013/11/the-spi-of-the-avr/#Master_Slave PS: Ich habe keine Fuses oder ähnliches verändert und verwende nur den internen Quarz. Master:
1 | #define F_CPU 1000000UL // 1 MHz
|
2 | |
3 | #define DDR_SPI DDRB
|
4 | #define PORT_SPI PORTB
|
5 | #define DD_MOSI DDB3
|
6 | #define DD_MISO DDB4
|
7 | #define DD_SCK DDB5
|
8 | #define DD_SS DDB0
|
9 | #define LED DDD5
|
10 | |
11 | #include <avr/io.h> |
12 | #include <util/delay.h> |
13 | #include <avr/interrupt.h> |
14 | |
15 | #define ACK 0x7E
|
16 | |
17 | //Initialize SPI Master Device
|
18 | void spi_init_master (void) |
19 | {
|
20 | |
21 | DDR_SPI = (1<<DD_SCK)|(1<<DD_MOSI); //Set MOSI, SCK as Output |
22 | PORT_SPI = (1<<DD_MISO); // Set pull ups |
23 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); //Enable SPI, Set as Master |
24 | }
|
25 | |
26 | //Function to send and receive data
|
27 | unsigned char spi_tranceiver (unsigned char data) |
28 | {
|
29 | SPDR = data; //Load data into the buffer |
30 | while(!(SPSR & (1<<SPIF) )); //Wait until transmission complete |
31 | return(SPDR); //Return received data |
32 | }
|
33 | |
34 | |
35 | int main(void) |
36 | {
|
37 | spi_init_master(); //Initialize SPI Master |
38 | DDRD |= 0x01; //PD0 as Output |
39 | |
40 | unsigned char data; //Received data stored here |
41 | |
42 | while(1) |
43 | {
|
44 | data = 0x00; //Reset ACK in "data" |
45 | data = spi_tranceiver('0'); //Send "0", receive ACK |
46 | _delay_ms(500); |
47 | data = 0x00; |
48 | data = spi_tranceiver('1'); //Send "1", receive ACK |
49 | _delay_ms(500); |
50 | }
|
51 | }
|
Slave:
1 | #define F_CPU 1000000UL // 1 MHz
|
2 | |
3 | #include <avr/io.h> |
4 | #include <avr/interrupt.h> |
5 | #include <util/delay.h> |
6 | |
7 | #define DDR_SPI DDRB
|
8 | #define PORT_SPI PORTB
|
9 | #define DD_MOSI DDB5 //DI
|
10 | #define DD_MISO DDB6 //DO
|
11 | #define DD_SCK DDB7
|
12 | #define DD_SS DDB4
|
13 | #define LED DDD5
|
14 | |
15 | #define ACK 0x7E
|
16 | |
17 | void spi_init_slave (void) |
18 | {
|
19 | DDR_SPI |= (1<<DD_MISO); // MISO output |
20 | DDR_SPI &= ~(1<<DD_SCK)|~(1<<DD_MOSI); // SCK and MOSI input |
21 | PORT_SPI = (1<<DD_SCK)|(1<<DD_MOSI); // Set pull ups |
22 | USICR = (1<<USIWM0)|(1<<USICS1); // Enable USI as SPI Slave |
23 | }
|
24 | |
25 | unsigned char spi_tranceiver (unsigned char data) |
26 | {
|
27 | USIDR = data; |
28 | while(!(USISR&(1<<USIOIF))); |
29 | return(USIDR); |
30 | }
|
31 | |
32 | int main(void) |
33 | {
|
34 | DDRD = (1<<LED); |
35 | spi_init_slave(); //Initialize slave SPI |
36 | unsigned char data; |
37 | |
38 | while(1) |
39 | {
|
40 | data = spi_tranceiver(ACK); //Receive data, send ACK |
41 | if (data == '0') |
42 | {
|
43 | //set port PD5 HIGH
|
44 | PORTD &= ~(1<<LED); |
45 | _delay_ms(100); |
46 | }
|
47 | if (data == '1') |
48 | {
|
49 | //set port PD5 LOW
|
50 | PORTD |= (1<<LED); |
51 | _delay_ms(100); |
52 | }
|
53 | _delay_ms(20); |
54 | }
|
55 | }
|
Danke!