orgsi1990 schrieb:
> while(1)
> {
> data = SPI_SlaveReceive();
> SPI_SlaveSend(data);
> }
Du hast da einen Denkfehler.
Ein Slave kann von sich aus überhaupt nichts senden!
SPI wird komplett vom Master angeleiert. Er hat zu jedem Zeitpunkt das
sagen.
SPI funktioniert so, wie wenn du und dein Kumpel sich am Tisch gegenüber
sitzen. Du bist der Master und er ist der Slave.
Jeder hat vor sich einen Zettel liegen, auf den er das zu übermittelnde
aufschreibt (was bei einem µC natürlich lediglich 1 Byte ist).
Auf dein(!) Kommando nehmt ihr beide den Zettel jeweils mit der rechten
Hand und schiebt ihn zum Gegenüber rüber während jeder mit der linken
Hand jeweils den Zettel vom Gegenüber in Empfang nimmt.
SPI ist also ein gleichzeitig ablaufender Datenaustausch zwischen Master
und Client. Die Initiative liegt dabei ausschliesslich beim Master! Von
sich aus kann ein Slave überehaupt nichts tun. Er kann nur reagieren
wenn vom Master ein Datenaustausch initiert wird.
Ein Slave schreibt den zu übermittelnden Wert ganz einfach ins SPDR
Register. Bei der nächsten Übertragung, die vom Master angeleiert wird,
wird dann dieser Inhalt an den Master übertragen, während gleichzeitig
das Byte vom Master in den Slave übertragen wird und als neuer Wert im
SPDR Register landet. Das bedeutet aber auch: der Wert, den der Slave zu
Master übertragen will, der muss schon im SPDR stehen, noch bevor der
Master die nächste Übertragung machen wird.
Hier
1 | char SPI_SlaveReceive(void)
|
2 | { char data;
|
3 | while(!(SPSR & (1<<SPIF)))
|
4 | {}
|
5 | data = SPDR;
|
6 | SPDR = 0;
|
7 | return data;
|
8 | }
|
laufen 2(!) Vorgänge ab. Auf der einen Seite findet eine Übertragung vom
Master zum Slave ins SPDR Register statt. Auf der anderen Seite findet
aber auch eine Übertragung vom Slave zu Master statt.
Probier mal folgendes
1 | int main()
|
2 | {
|
3 | SPI_SlaveInit();
|
4 | char data;
|
5 |
|
6 | SPDR = 0xFF;
|
7 | while(1)
|
8 | {
|
9 | data = SPI_Exchange();
|
10 | }
|
11 | }
|
12 |
|
13 | void SPI_SlaveInit(void)
|
14 | { DDRB |= (1<<PORTB4);
|
15 | SPCR = (1<<SPE);
|
16 | }
|
17 |
|
18 | char SPI_Exchange(void)
|
19 | {
|
20 | char data;
|
21 |
|
22 | while(!(SPSR & (1<<SPIF)))
|
23 | {}
|
24 |
|
25 | data = SPDR;
|
26 | SPDR = data + 2; // einen größeren Wert bereit stellen. Der Master
|
27 | // holt sich den dann bei der nächsten Übertragung ab
|
28 | return data;
|
29 | }
|