Hallo,
Ich programmiere mit CoIDE einen LPC11C24(Master) und will über SPI mit
einem Freescale MC33972(Slave) kommunizieren. An den MC33972 sind
Schalter angeschlossen, von denen er ermittelt, ob sie offen oder
geschlossen sind. Ich kann den MC33972 programmieren, indem ich ihm 24
Bit über SPI sende und als Antwort ich müsste laut Datenblatt immer die
Zustände der Schalter bekommen.
Ich habe das versenden in eine Funktion gepackt, die immer wieder
aufgerufen wird. Mein Problem ist, dass ich sehr unregelmäßig Antworten
bekommen(z.T. erst nach dem 15000 mal aufrufen der Funktion), und diese
meist verschieden sind, obwohl sich an den Zuständen der Schalter nichts
geändert hat. Hat jemand eine Idee, woran das liegen könnte??
Vielen Dank schon mal
Meine Funktion sieht so aus:
1
voidSPI(void){//Abfragen SPI Schnittstelle
2
uint8_ta=1,Frame1=0,Frame2=0,Frame3=0;
3
staticintzaehler=0;
4
zaehler++;
5
6
//1.Byte
7
while(((LPC_SSP1->SR&0x1F)&0x1C)){}//Testen, ob Transmit Register leer
8
//ist
9
LPC_SSP1->DR=a;//schreiben Ins Transmit Register
10
while(LPC_SSP1->SR&0x10){}//Warten, bis senden abgeschlossen ist
11
Frame1=LPC_SSP1->DR;//Abfragen der erhaltenen Bits
12
13
//2.Byte
14
while(((LPC_SSP1->SR&0x1F)&0x1C)){}//Testen, ob DR Register leer ist
15
LPC_SSP1->DR=Frame2;
16
while(LPC_SSP1->SR&0x10){}
17
Frame2=LPC_SSP1->DR;
18
19
//3.Byte
20
while(((LPC_SSP1->SR&0x1F)&0x1C)){}//Testen, ob DR Register leer ist
21
LPC_SSP1->DR=Frame3;
22
while(LPC_SSP1->SR&0x10){}
23
Frame3=LPC_SSP1->DR;
24
25
if(Frame1||Frame2||Frame3){//Testet,ob etwas anderes als Null
Matthias R. schrieb:> Mein Problem ist, dass ich sehr unregelmäßig Antworten bekommen
Bei SPI bekommst du immer (und nur!) wenn du etwas sendest
automatisch eine Antwort. Denn SPI sind nur gekoppelte
Schieberegister. Warum ist das bei dir nicht der Fall?
> Hat jemand eine Idee, woran das liegen könnte??
Falscher SPI-Mode?
Hast du ein Oszi? Denn nur damit kannst du erkennen, ob das Timing
deines uC zum Timing vom Slave passt.
> Meine Funktion sieht so aus:
1
while(((LPC_SSP1->SR&0x1F)&0x1C))...
Was ist denn das? Was willst du damit bezwecken?
BTW: mach doch bitte das nächste Mal ein [ c ] und ein [ /c ] ohne die
Leerzeichen um deinen Code. Das steht übrigens auch ein paar Zeilen über
jedem Eingabefenster...
wo wird denn das CS gemacht? Das wirst du für 24 Bit Transfers manuell
machen müssen, im Datenblatt sehe ich jetzt nur max. 16 Bit. Wenn jetzt
3x1 Byte Transfers laufen liefert dir der MC33972 vermutlich immer nur
das 1.Byte weil ein CS Wechsel oft für den Reset der Sequenz benutzt
wird.
Danke für die Antworten.
Ist das erste mal, das ich SPI programmiere.
Das ich nur was zurück bekomme,wenn ich etwas sende ist mir klar, aber
ich bekomme meist nur Nullen zurück.
Warum wird das 2. und 3. Byte nicht gesendet, ich schreibe es genau wie
das erste ins Senderegister.
Matthias R. schrieb:> Warum wird das 2. und 3. Byte nicht gesendet, ich schreibe es genau wie> das erste ins Senderegister.
Mach mal einfach ein 1ms-Delay nach dem Senden der jeweiligen Bytes. Ich
zweifle wie gesagt immer noch am Sinn deiner Busy-Abfrage...
Und: hast du jetzt ein Oszi oder nicht?
Habe jetzt 1ms Wartezeit zwischen dem senden eingebaut und die
Übertragungsrate stark zurückgesetzt. Jetzt bekomme ich immer eine
Antwort, die nicht nur aus Nullen besteht. Oszilloskop habe ich leider
keines.
Meine Funktion sieht jetzt so aus:
1
voidSPI(void){//Abfragen und programmieren der SPI Schnittstelle
2
uint8_ta=1,Frame1=1,Frame2=0,Frame3=0;
3
staticintzaehler=0;
4
zaehler++;
5
6
LPC_GPIO2->DATA&=~0x01;//Slave select low
7
//1.Byte
8
LPC_SSP1->DR=Frame1;//schreiben Ins Transmit Register
9
wait();
10
Frame1=LPC_SSP1->DR;//Abfragen der erhaltenen Bits
Matthias R. schrieb:> Jetzt bekomme ich immer eine Antwort, die nicht nur aus Nullen besteht.
Ist die Antwort sinnvoll?
> Oszilloskop habe ich leider keines.
Das ist beim SPI besonders blöd, denn jetzt musst du dich sehr genau in
die Doku beider Chips einarbeiten und den richtigen Modus herausfinden
(CPOL, CPHA).
Nein leider nicht sinnvoll, immer andere Werte, aber sie müssten immer
gleich sein, weil ich an den Schalterzuständen nichts ändere.
Ich kenn jemanden, der ein Oszi hat, zu dem fahr ich jetzt dann mal.
Mein Code sieht jezt so aus:
1
voidSPI(void){//Abfragen und programmieren der SPI Schnittstelle
2
uint8_ta=1,Frame1=127,Frame2=127,Frame3=127;
3
staticintzaehler=0;
4
zaehler++;
5
6
LPC_GPIO2->DATA&=~0x01;//Slave select low
7
//1.Byte
8
LPC_SSP1->DR=Frame1;//schreiben Ins Transmit Register
9
wait();
10
Frame1=LPC_SSP1->DR;//Abfragen der erhaltenen Bits
Ich versuch jetzt das ganze Software mässig in den Griff zu bekommen.
Allerdings bekomme ich immer noch keine sinnvollen Daten zurück, aber
immerhin immer die gleichen. Was haltet ihr von dem Code ? Hat jemand
Erfahrungen mit dem MC33972?
1
intSPI(intsend){
2
//Grundeinstellungen
3
//Sysclock ist soll nullsein, wenn nichts passiert
4
//SSl ist High wenn nichts passiert
5
inti=0;
6
intb=0,zaehler=0;
7
//Beginn senden
8
//SSL fallend
9
10
LPC_GPIO2->DATA&=~0x02;//SCKL LOW
11
LPC_GPIO2->DATA&=~0x01;//SSl LOW
12
13
intdata=0;
14
15
// Höchstes Bit muss zuerst gesendet werden
16
for(i=23;i>=0;i--){
17
18
if(send&(1<<i)){// wählt aus , ob MOSI 0 oder 1 als Zustand hat
19
LPC_GPIO2->DATA|=0x01;//MOSI = 1
20
}
21
22
else{LPC_GPIO2->DATA&=~0x01;//MOSI = 0
23
}
24
25
high;//SCKL High
26
27
b=LPC_GPIO2->DATA&0x04;//Liest Zustand des MISO Pins aus
28
29
if(b)//Speichert Bit in Datenstring ab
30
{data|=(1<<i);}
31
low;//SCKL low
32
}
33
LPC_GPIO2->DATA|=0x01;//SSl High
34
35
returndata&0xFFFFFF;//Nur Bits, die kleine als Numm er 24 sind nehmen
Ich hab zwar keine Erfahrung mit dem MC33972, aber das hier scheint
irgendwie nicht richtig:
Matthias R. schrieb:> LPC_GPIO2->DATA &=~ 0x01; //SSl LOWMatthias R. schrieb:> LPC_GPIO2->DATA |= 0x01;//MOSI = 1
es erschließt sich mir nicht wie ein Bit einmal SS1(ChipSelect) und
einmal MOSI sein kann, oder ist das bei einem MC33972 gängige Praxis?
Und wo sind "low" und "high" definiert?