Forum: Mikrocontroller und Digitale Elektronik SPI Probleme mit CLRC633


von Neo (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich benötige einmal das allwissende Forum!

Es geht um eine SPI-Verbindung zwischen dem µC der Reihe STM32F0 und dem 
RFID-Leser CLRC663. Normalerweise sollte dies ja kein Problem sein, 
jedoch komme ich nicht weiter. Vielleicht kann mir jemand da 
weiterhelfen, bzw. das Problem etwas helfen einzugrenzen. Leider konnte 
mir kein Thread dazu weiterhelfen im Forum.

Habe nun nach dem Datenblatt des CLRC663 die "Connection scheme" für den 
SPI angeschlossen.

Möchte um den SPI zu testen, das Register 0x7F auslesen, welches die 
aktuelle Version des Moduls angibt. Jedoch erhalte ich komische Signale 
auf dem SPI-Bus, welche ich mir nicht erklären kann.

Auf dem MOSI schicke ich 0xFF hin (Bitmanipulation für Register 0x7F 
auslesen), bekomme jedoch schon im gleichen Augennlick über den MISO 
0x30 zurück. Die Antwort ist laut Datenblatt im nächsten Byte die 0x18 
(Version des Moduls), was auch so richtig ist. Dann wiederhole ich das. 
Hier jedoch kommt auf einmal die 0x40 auf der MISO zurück, obwohl doch 
hier noch garnichts kommen dürfte? Zusätzlich schickt der MOSI eine 
0x18, was jedoch so nicht programmiert ist und die Antwort vom Slave 
wäre 0xFF bei der gleichen Registeranfrage.


Der Code wie folgt:
1
#define read  1
2
#define write 0
3
4
5
  uint8_t transmit_Data[8];
6
  uint8_t receive_Data[8];
7
8
  transmit_Data[0] = 0x7F;   // Register IRQ1EN Interrupt enable register 1 r/w // /0x7F
9
  transmit_Data[1] = 0x00;
10
11
//*************************************************************************
12
//                Bitmanipulation
13
14
  transmit_Data[0]=transmit_Data[0]<<1;
15
  transmit_Data[0]= transmit_Data[0]|read;  // Register 1RQ1EN lesen
16
17
//******************************************************************************
18
//                SPI-Verbindung
19
20
  __HAL_SPI_ENABLE(&hspi1);
21
22
   HAL_SPI_Transmit(&hspi1,&transmit_Data[0],1,100);     // Register 1RQ1EN lesen
23
   HAL_SPI_Receive(&hspi1,&receive_Data[0],1,100);      // Daten von 1RQ1EN erhalten
24
25
   HAL_SPI_Transmit(&hspi1,&transmit_Data[0],1,1000);     // Register 1RQ1EN lesen
26
   HAL_SPI_Receive(&hspi1,&receive_Data[0],1,1000);      // Daten von 1RQ1EN erhalten
27
28
  __HAL_SPI_DISABLE(&hspi1);


Hat da jemand eine Idee woran das liegen kann?
Vielen Dank und viele Grüße!

von honk (Gast)


Lesenswert?

Was an:

"Between every SPI command, the NSS must go to logical high to be able 
to start the next command read or write"

hast Du nicht verstanden?

von Joe F. (easylife)


Lesenswert?

Du mischt hier Lese- und Schreibzugriffe.
Du kannst zwar mehrere Register in einer CS_N-Low-Phase auslesen (Daten 
kommen immer um 1 Byte verschoben auf MISO zurück), kannst aber nicht in 
einer Transaction auf schreiben umschalten.
Bzw. geht das evtl. sogar, aber ich würde es nicht machen. 
Zurückschalten auf Lesen kann dann jedenfalls nicht funktionieren.

Das R/W Bit ist Bestandteil der Adresse, bei von dir verwendeten 
Adressen 0xFF und 0x00 sind also Lesen und Schreiben gemischt.
Ob Bit 0 high oder low sein muss zum Lesen, habe ich auf die Schnelle im 
Datenblatt nicht gefunden...
Ich nehme an 1=read, 0=write, nachdem dein erster Read auf Adresse 0x7F 
(<<1) ja funktioniert hat.
Lesen und Schreiben muss immer durch eine CS_N high Phase getrennt sein.

: Bearbeitet durch User
von Neo (Gast)


Angehängte Dateien:

Lesenswert?

Danke Joe, ja das habe ich Überlesen!

Habe es nun umgeschrieben, kommen aber trotzdem nicht das erwartete 
Ergebnis zurück. Vielmehr ein Wert auf MOSI, der keinen Sinn macht. Und 
wieso wird auf der MOSI die 0x60 geschickt? Könnten das Interferenzen 
sein? Habe den Versuchsaufbau schon so kurz wie möglich gehalten.

Hier nochmal der Code und das Bild zum Logic Analyser.
1
 //**********************************************************************
2
 //                Deklaration
3
#define read  1
4
#define write 0
5
6
7
  uint8_t transmit_Data[8];
8
  uint8_t receive_Data[8];
9
10
  transmit_Data[0] = 0x7F;   // Register IRQ1EN Interrupt enable register 1 r/w // /0x7F
11
  transmit_Data[1] = 0x00;
12
13
//*************************************************************************
14
//                Bitmanipulation
15
16
  transmit_Data[0]=transmit_Data[0]<<1;
17
  transmit_Data[0]= transmit_Data[0]|read;  // Register 1RQ1EN lesen
18
19
//******************************************************************************
20
//                SPI-Verbindung
21
22
  __HAL_SPI_ENABLE(&hspi1);
23
   HAL_SPI_Transmit(&hspi1,&transmit_Data[0],1,100);     // Register 1RQ1EN lesen
24
   __HAL_SPI_DISABLE(&hspi1);
25
   __HAL_SPI_ENABLE(&hspi1);
26
   HAL_SPI_Receive(&hspi1,&receive_Data[0],1,100);      // Daten von 1RQ1EN erhalten
27
   __HAL_SPI_DISABLE(&hspi1);

von Joe F. (easylife)


Angehängte Dateien:

Lesenswert?

Jetzt ist es auf eine andere Art falsch.
Für das Auslesen eines Registers musst du in einem CS_N-Low-Cycle 2 
Bytes auf MOSI senden und bekommst 2 Bytes auf MISO.
Das erste Byte, das du sendest ist die Adresse + Read-Bit des Registers,
auf MOSI bekommst du um 1 Byte verschoben die Daten.
Das erste Byte ist Müll.

Was du gerade machst ist, du initiierst einen Read auf Reg. 0x7F, liest 
aber die Daten nicht aus (CS geht ein Byte zu früh wieder high).
Dann startest du eine Write-Transaction auf Reg. 0x30, schickst aber 
keine Daten...
Wenn das 2. Byte auf MOSI auch eine "Read"-Adresse wäre, würden als 3. 
Byte auf MISO dann die Daten dieses Registers zurückgeliefert.

: Bearbeitet durch User
von Peter (Gast)


Lesenswert?

Welchen SPI Mode hast Du denn an Deinem Controller initialisiert?
Und welchen Mode benötigt Dein angehängtes IC?

Beide sollten übereinstimmen. Das gilt auch für Deinen Logic-Analyzer.

Gruß Peter

von Neo (Gast)


Angehängte Dateien:

Lesenswert?

Guten Morgen zusammen,

Eingestellt ist der der SPI-Modus folgendermaßen:

Baud Rate           : 125,0 KBits/s
Clock Polarity CPOL : Low
Clock Phase CPHA    : 1 Edge

So habe ich auch die Einstellung des CLRC663 auch verstanden. Der Logic 
Analyser besitzt dieselbe.


Danke Joe, ja da hast du recht! Was meinst du damit das das erste Byte 
Müll ist?

Habe nun nochmal zusätzlich den Power Down des CLRC663 beschaltet, 
jedoch auch hiermit keine Verbesserung.
1
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_5,GPIO_PIN_SET);    //PDOWN High
2
  HAL_Delay(1);
3
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_5,GPIO_PIN_RESET);  //PDOWN Low
4
  HAL_Delay(5);
5
6
  __HAL_SPI_ENABLE(&hspi1);
7
  HAL_SPI_Transmit(&hspi1,&transmit_Data[0],1,100);     // Register 1RQ1EN lesen
8
  HAL_SPI_Receive(&hspi1,&receive_Data[0],1,100);      // Daten von 1RQ1EN erhalten
9
  __HAL_SPI_DISABLE(&hspi1);
10
11
  __HAL_SPI_ENABLE(&hspi1);
12
  HAL_SPI_Transmit(&hspi1,&transmit_Data[0],1,100);     // Register 1RQ1EN lesen
13
  HAL_SPI_Receive(&hspi1,&receive_Data[0],1,100);      // Daten von 1RQ1EN erhalten
14
  __HAL_SPI_DISABLE(&hspi1);
15
16
17
  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_5,GPIO_PIN_SET);         //PDOWN High

Jetzt setze ich den ENABLE zwischen den beiden Lesesequenzen nochmal auf 
High.

Es verwirrt mich einfach, woher die 0x03 und die 0x80 auf der MISO 
kommen und die 0x18 auf der MOSI (rot markiert). Kann es mir nicht 
erklären, da ich ja nur das 0xFF über MOSI hinschicke und die 0x18 über 
die MISO erhalten möchte.

Hat jemand eine Idee woher das kommen kann? Vielen Dank nochmal!

von Joe F. (easylife)


Lesenswert?

Jetzt passt es doch.
Die Daten, die du während des Sendens der Adresse auf MISO 
zurückbekommst sind einfach zu ignorieren. Das ist in der Regel 
"Daten-Müll".

Der CLRC663 kann dir ja den Registerinhalt erst auf MISO zurückgeben, 
wenn ihm die Adresse bekannt ist, die du auslesen möchtest.
Und das ist eben erst NACH der vollständigen Übertragung der Adresse 
möglich.
Daher kommt die Verschiebung um 1 Byte zwischen MOSI und MISO Daten.

Du liest nun beide male 0x18 aus Register 0x7F aus, was korrekt ist.

PS: die nadelartige High-Phase von CS zwischen den beiden Transaktionen 
ist unschöne.
CS sollte länger high sein (->Datenblatt), ich nehme mal an, ein CLK 
cycle reicht.

: Bearbeitet durch User
von Neo (Gast)


Lesenswert?

Also somit können die rot markierten Datenpakete, jeweils auf MOSI und 
MISO ignoriert werden? Der µC verwertet diese dann nicht aus?

Denn ich verstehe den SPI- BUS so, dass dieser dann auch nichts schickt, 
wenn nichts zu schicken ist, ob Master oder Slave. Aber ich lasse mich 
gerne eines besseren Belehren! :)

Vielen Dank Joe!

von Joe F. (easylife)


Lesenswert?

Neo schrieb:
> Also somit können die rot markierten Datenpakete, jeweils auf MOSI und
> MISO ignoriert werden? Der µC verwertet diese dann nicht aus?

Die rot markierten Daten auf MISO: ja.

Bei MOSI ist es so, dass der CLRC663 das 2. Byte ebenfalls als Adresse 
(mit R/W-Bit) interpretiert.
Du könntest also auch gleich mehrere Register hintereinander auslesen.

Damit du nicht aus Versehen einen Schreib-Zugriff startest, würde ich 
darauf achten, dass das "Dummy-Byte", das du während des Lesens des 
Registerinhaltes auf MOSI anlegen musst, ebenfalls das Read-Bit gesetzt 
hat (Bit 0).
"0x18" ist ein Schreib-Zugriff.
Man könnte hier z.B. einfach immer "0xFF" nehmen.

von Neo (Gast)


Lesenswert?

Okay das macht dann Sinn! Jetzt funktioniert es! Vielen Dank nochmal!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.