Hallo und schönen Sonntag allerseits,
ich versuche eine SPI Kommunikation zwischen einem Atmel ATMEGA32L (als
Master) und einem bzw später mehreren Slaves zu implementieren.
Leider tat sich lt. Oszilloskop nicht das was ich mir erhofft habe. Habe
ich etwas vergessen, übersehen oder falschgemacht?
Anbei mein C - Code mit der Bitte um Hilfe, Anregung und
Lösungsvorschläge.
1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <stdbool.h>
|
4 | #include <avr/interrupt.h>
|
5 |
|
6 | // Prototypen
|
7 |
|
8 | void SPI_MasterInit(void);
|
9 | void SPI_MasterTransmit( int cData);
|
10 | unsigned char SPI_MasterReceive(void);
|
11 |
|
12 |
|
13 |
|
14 |
|
15 | int main(void)
|
16 | {
|
17 | // Interrupts erlauben
|
18 | sei();
|
19 | //TestPin wechselt Zustand bei erfolgreichem Funktionsdurchlauf
|
20 | DDRD |= (1<<DDD7);
|
21 |
|
22 | unsigned char test= 0x54;
|
23 | unsigned char back;
|
24 | unsigned char end = false;
|
25 |
|
26 | while(end!=true)
|
27 | {
|
28 | SPI_MasterTransmit(test);
|
29 | back = SPI_MasterReceive();
|
30 |
|
31 | }
|
32 |
|
33 |
|
34 | return 0; /* never reached */
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 | void SPI_MasterInit(void)
|
40 |
|
41 | {
|
42 |
|
43 | /* Set MOSI and SCK output, all others input */
|
44 | DDRB |= (1<<DDB5)|(1<<DDB7);
|
45 | // SET MISO als Eingang
|
46 | //DDRB &= ~(1<<DDB6);
|
47 | // MOSI, MISO und Takt auf LOW
|
48 | //PORTB &= ~((1<<PB5)|(1<<PB6)|(1<<PB7));
|
49 | // slave select als Ausgang
|
50 | DDRD |= (1<<DDD4);
|
51 | // SS auf High
|
52 | PORTD |= (1<<PD4);
|
53 |
|
54 | /* SPI Kontrollregister */
|
55 |
|
56 | // SPI Interrupt enable , SPI aktivieren, Mastermode
|
57 | SPCR |= ((1<<SPE)|(1<<MSTR));
|
58 |
|
59 | //Taktbasis low, steigende flanke MO, fallende flanke MI, SPI Takt = /4 -> 1 MHz / 4 = 250 KHZ = 250.000 Hz
|
60 | //SPCR &= ~((1<<SPIE)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0)|(1<<SPR1));
|
61 |
|
62 | /*SPI Status Register*/
|
63 |
|
64 | //Kontrollflag setzen
|
65 |
|
66 | PORTD |= (1 <<PD7);
|
67 |
|
68 | }
|
69 |
|
70 | void SPI_MasterTransmit( int cData)
|
71 |
|
72 | {
|
73 | //testflag löschen
|
74 | PORTD &= ~(1<<PD7);
|
75 |
|
76 | //Slaveselect auf Masse
|
77 | PORTD &= ~(1<<PD4);
|
78 |
|
79 |
|
80 | /* Start transmission */
|
81 | SPDR = cData;
|
82 | /* Wait for transmission complete */
|
83 | while(!(SPSR & (1<<SPIF)));
|
84 |
|
85 | PORTD |= (1<<PD4);
|
86 |
|
87 | //testflag setzen
|
88 | PORTD |= (1 <<PD7);
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | }
|
94 |
|
95 | unsigned char SPI_MasterReceive(void)
|
96 | {
|
97 | //testflag löschen
|
98 | PORTD &= ~(1<<PD7);
|
99 |
|
100 | _delay_ms(10);
|
101 | //testflag setzen
|
102 | PORTD |= (1 <<PD7);
|
103 | //
|
104 | return SPDR;
|
105 |
|
106 |
|
107 | }
|
1 | Fuse high byte:
|
2 | # 0xB9 = 1 0 1 1 1 0 0 1
|
3 | Fuse low byte:
|
4 | # 0x81 = 1 0 0 0 0 0 0 1
|