SPI Slave antwortet unregelmäßig

OP #3603163
Lesenswert?

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
void SPI(void){ //Abfragen SPI Schnittstelle
2
 uint8_t a=1,Frame1=0, Frame2=0, Frame3=0;
3
 static int zaehler=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
26
   ledinit();aus();    //zurück gesendet wurde
27
     //wait();
28
     //aus();
29
}
30

31
}
Moderator (Firma: Titel) Persönliche Seite #3603179
Lesenswert?

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...
Gast #3603286
Lesenswert?

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.
Moderator (Firma: Titel) Persönliche Seite #3603305
Lesenswert?

Matthias R. schrieb:
> LPC11C24(Master) und will über SPI mit einem Freescale MC33972(Slave)
Ein Dejavu: https://www.mikrocontroller.net/search?query=MC33972
Wozu fängst du eigentlich laufend neue Threads zum selben Thema an?

Die Abfrage, ob eine Übertragung aktiv ist, wird von Anderen übrigens so 
gemacht:
1
  while ( LPC_SSP1->SR & SSPSR_BSY );
Das scheint mir irgendwie sinnvoller...
OP #3603607
Lesenswert?

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
void SPI(void){ //Abfragen und programmieren der SPI Schnittstelle
2
 uint8_t a=1,Frame1=1, Frame2=0, Frame3=0;
3
 static int zaehler=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
11

12
 //2.Byte
13
 LPC_SSP1->DR=Frame2;
14
 wait();
15
 Frame2= LPC_SSP1->DR;
16

17
 //3.Byte
18
 LPC_SSP1->DR=Frame3;
19
 wait();
20
 Frame3 = LPC_SSP1->DR;
21

22
 LPC_GPIO2->DATA |=0x01;//Slave select high
23

24
 if(Frame1||Frame2||Frame3) {
25
   ledinit();aus();
26

27
}
28

29
}
OP #3606859
Lesenswert?

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
void SPI(void){ //Abfragen und programmieren der SPI Schnittstelle
2
 uint8_t a=1,Frame1=127, Frame2=127, Frame3=127;
3
 static int zaehler=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
11

12
 //2.Byte
13
 LPC_SSP1->DR=Frame2;
14
 wait();
15
 Frame2= LPC_SSP1->DR;
16

17
 //3.Byte
18
 LPC_SSP1->DR=Frame3;
19
 wait();
20
 Frame3 = LPC_SSP1->DR;
21

22
 LPC_GPIO2->DATA |=0x01;//Slave select high
23

24
 if(Frame1||Frame2||Frame3) {
25
   ledinit();aus();
26

27
}
28

29
}
OP #3608723
Lesenswert?

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
int SPI( int send){
2
  //Grundeinstellungen
3
  //Sysclock ist soll nullsein, wenn nichts passiert
4
    //SSl ist High wenn nichts passiert
5
  int i=0;
6
  int b=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
  int data = 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
return data & 0xFFFFFF;//Nur Bits, die kleine als Numm er 24 sind nehmen
36
}
#3608753
Lesenswert?

Ich hab zwar keine Erfahrung mit dem MC33972, aber das hier scheint 
irgendwie nicht richtig:

Matthias R. schrieb:
> LPC_GPIO2->DATA &=~ 0x01; //SSl LOW

Matthias 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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren