Hallo zusammen,
ich bin neu in MSP430 Programmierung und tue mich grade mit SPI
Kommunkation etwas schwer. Ich habe zwei Boards und möchte einfach mit
char Zeichen Leds steuern. Ich habe einen MSP430 als Master und einen
als Slave. Derzeit schaut der Code so aus:
Master:
Ich kann Daten vom Masteraus senden. Der Slave reagiert wie programmiert
darauf und die LEDs toggelen auch. Der Master empfängt jedoch nichts.
Die Abfrage in der main Funktion auf 'A' wird nie erfüllt. Im Debugger
erscheint der Receive Buffer des Masters mit einem Konstanten Wert von
0x66...
Kann mir jemand vielleicht einen kleinen Tipp geben?
lg M430
Beim Master hast du das Interface nicht resettet, beim Slave aber schon:
UCA0CTLW0 |= UCSWRST; // **Put state machine in
reset**
Sollte beim Master in der Initialisierung auch rein.
Vielen Dank an alle, die sich die Zeit genommen haben. Leider gehts bei
mir immer noch nicht...
Ich habe was ihr geschrieben habt eingefügt. Sofort gesendet und mich
nach der Funktion uint8_t spi_transfer_byte(uint8_t data) gerichtet.
Ich bekomme leider noch immer nichts zurück. Manchmal klappt das Senden
auch nicht mehr. Man muss oft komplett alles resetten bis vlt was mal
funktioniert.
Ich habe den Code nochmal raufgeladen. Was mache ich noch immer falsch?
Master
M430 schrieb:> Ich bekomme leider noch immer nichts zurück.
Du bekommst was zurück, nur nicht das, was Du erwartest.
Das, was Dein Master zurückbekommt, kann nicht das Resultat dessen sein,
was der Slave aufgrund der empfangenen Daten zurücksendet, denn der
Slave sendet --wie auch der Master-- genau dann, wenn er auch empfängt.
Das bedeutet, daß er das Empfangene erst dann auswerten kann, wenn der
Sendevorgang bereits abgeschlossen ist.
Obendrein darf Deine Interruptroutine das Empfangsregister nur genau
einmal auslesen, Du aber liest es bis zu dreimal aus.
Ändere das von
1
if(UCA0RXBUF=='a')
2
{
3
flag=1;
4
}
5
elseif(UCA0RXBUF=='c')
6
{
7
flag=2;
8
}
9
elseif(UCA0RXBUF=='e')
10
{
11
flag=3;
12
}
zu
1
charc;
2
3
c=UCA0RXBUF;
4
5
if(c=='a')
6
{
7
flag=1;
8
}
9
elseif(c=='c')
10
{
11
flag=2;
12
}
13
elseif(c=='e')
14
{
15
flag=3;
16
}
oder
1
charc;
2
3
c=UCA0RXBUF;
4
5
switch(c)
6
{
7
case'a':
8
flag=1;
9
break;
10
11
case'c':
12
flag=2;
13
break;
14
15
case'e':
16
flag=3;
17
break;
18
}
(Und was geschieht, wenn was anderes als a, c oder e empfangen wird?)
Aber das ist nicht das ganze Problem, nehmen wir für die folgende
Betrachtung mal an, Deine Interruptroutine würde das tun, was Du
beabsichtigst.
Was passiert?
1. Master sendet 'a' und empfängt X
2. Slave empfängt 'a' und setzt danach "flag" auf 1.
Da das Senderegister des Slaves zum Zeitpunkt des Empfangens nicht
initialisiert war, hat der Slave also irgendwas gesendet, und dieses
irgendwas ist X.
Der Master empfängt also ziemlich sicher kein 'b', und schaltet
deswegen seine LED nicht ein.
In der Hauptschleife des Slaves wird, weil "flag" auf 1 gesetzt wurde,
'b' in das Senderegister geschrieben.
3. Master sendet 'b' ... und empfängt 'b'
4. Der Slave empfängt 'b' und hat derweil 'b' gesendet, "flag" verändert
er nicht.
Also wird in der Hauptschleife des Slaves wieder ein 'b' in das
Senderegister geschrieben.
5. Master sendet 'c' ... und empfängt 'b'
6. Der Slave empfängt 'c' und hat derweil (wieder) 'b' gesendet; danach
setzt er "flag" auf 2.
In der Hauptschleife des Slaves wird daraufhin 'd' in das Senderegister
geschrieben.
7. Master sendet 'd' ... und empfängt 'd'
Der Slave empfängt 'd' und hat 'd' gesendet, "flag" ändert er nicht.
Wird's allählich klar?
SPI ist eine synchrone Kommunikation, jeder Sendevorgang liefert
zwangsweise auch empfangene Daten, die aber den Zustand vor dem Senden
wiedergeben.
Eine eigene Frage?
Dieser Thread ist über 11 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.