SPI Konfiguration beim STM32F107

Gast #2491320
Lesenswert?

Hallo alle zusammen,

ich arbeite gerade mit dem STM32F107 und möchte per SPI den Winkelsensor 
AS5040 auslesen.
Das Interface aus dem Datenblatt des Sensors habe ich angehängt. Den 
STM32 habe ich dazu wie folgt konfiguriert:
1
SPI_I2S_DeInit(SPI3);
2
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
3
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
4
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
5
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
6
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
7
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
8
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
9
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
10
SPI_Init(SPI3, &SPI_InitStructure);
11

12
SPI_Cmd(SPI3, ENABLE);

Um den Winkelinformationen auszulesen nutze ich folgende Routine:
1
GPIOA->BRR = GPIO_Pin_4;     // Chip-Select low
2
SPI_I2S_SendData(SPI3, 0x55);     // Dummy-Byte senden
3
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET) {}   // warten solange Busy-Flag gesetzt ist
4
GPIOA->BSRR = GPIO_Pin_4;    // Chip-Select high
5
AS_Winkel = SPI_I2S_ReceiveData(SPI3);    // Winkelinfos lesen
6
AS_Winkel >>= 5;    // shiften

An sich funktioniert das Auslesen des Winkels, jedoch müsste ich meiner 
Meinung nach 6 mal shiften, um den Winkel zu haben, da dieser die 
obersten 10 Bit belegt. Den richtigen Winkel bekomme ich jedoch nur, 
wenn ich 5 mal shifte. Das heißt ja eigentlich, dass das letzte Bit 
nicht eingelesen wird.

Würde mich freuen, wenn mir jemand einen Tipp geben kann, an was dies 
liegt oder ob ich ein Fehler in der Konfiguration gemacht hab.

Danke und Gruß
Paul
Angehängte Dateien:
Gast #2491607
Lesenswert?

Also ich habs jetzt mal so wie du gesagt hast getestet:
1
SPI_I2S_DeInit(SPI3);
2
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
3
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
4
SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
5
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
6
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
7
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
8
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
9
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
10
SPI_Init(SPI3, &SPI_InitStructure);
11

12
SPI_Cmd(SPI3, ENABLE);

Aber egal, ob ich 5 oder 6 mal shifte, kommt trotzdem nicht das richtige 
raus.

Ich hab ein Bild vom Logikanalysator angehängt. Wenn ich das Bild mit 
dem aus dem Datenblatt des AS5040 vergleiche, sieht es aus, als würde 
CSn zu früh auf high gehen. Könnte es daran liegen?
Angehängte Dateien:
#2491628
Lesenswert?

Wenn du das Bild aus dem Datasheet genau anschaust, dann kannst du 
erkennen, dass es für das letzte Bit zwar eine Taktflanke gibt, durch 
die es ausgelöst wird, aber keine, an der es durch den Controller 
abgetastet werden könnte.

Der Sensor liefert das erste Datenbit so, dass es erst mit der zweiten 
fallenden oder steigenden Taktflanke gesampelt werden kann. Einen 
passenden SPI-Modus für dieses SSI-Protokoll gibt es nicht. Folglich 
landen die Daten um ein Bit verschoben im Register und das letzte Bit 
ist nicht verfügbar.

Wenn du dieses letzte Bit benötigst, dann kannst du nach der Übertragung 
des Datenwortes und vor Deaktivierung des Sensors den Pinzustand 
auslesen.
#2491661
Lesenswert?

Der AS5040 ist ein ganz gemeiner Hund!
Du musst aufpassen, welchen Pegel der DI-Pin (MOSI) beim Selektieren des 
Device hat. Sonst versetzt du ihn ggf. in den Programmiermodus, was du 
bestimmt nicht willst oder??
Desweiteren ist entscheidend, dass der Sensor wohl einen kompletten 
CLK-Puls benötigt bevor das erste Datenbit rausgetaktet wird, sonst 
liest du das erste Bit immer als eine 1 und der ganze Datenstrom ist um 
ein Bit verschoben... (Parity wird also abgeschnitten.)
Gast #5083095
Lesenswert?

Hey,
ich weiß der Thread ist alt, aber ich habe ein Problem seit Tagen, 
welches ich mir nicht erklären kann.

Wenn ich den AS5040 über SPI auslesen möchte, fehlen die Datenbits 0-2.

Ich habe den Magneten 3x um 90° gedreht und folgendes erhalten:

Position|tDo|_____D0___|Systeminfos|D0(Dez)|DR(HEX)|DR(Dez)|
______|___|0123456789|__________|_______|_______|_______|
0_____|1__|0000010101|10011_____|21_____|82D3___|33459__|
90____|1__|0001010110|10011_____|86_____|8AD3___|35539__|
180___|1__|0000101010|10011_____|42_____|8553___|34131__|
360___|1__|0000011101|10011_____|29_____|82B3___|33715__|

Aus der Tabelle lässt sich ja erkennen, dass D0,D1,D2 immer Null sind.
In dem angehängtem Bild meines Logikanalyzers, sieht man, der Sensor 
sendet auch genau diese Daten.

Ich weiß also nicht warum der Sensor diese Daten so sendet.

Mein SPI habe ich wie folgt deklariert:
1
  
2
  hspi1.Instance = SPI1;
3
  hspi1.Init.Mode = SPI_MODE_MASTER;
4
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
5
  hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
6
  hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
7
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
8
  hspi1.Init.NSS = SPI_NSS_SOFT;
9
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;
10
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
11
  hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
12
  hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
13
  hspi1.Init.CRCPolynomial = 7;
14
  if (HAL_SPI_Init(&hspi1) != HAL_OK)
15
  {
16
    _Error_Handler(__FILE__, __LINE__);
17
  }

Die Daten verarbeite ich wie folgt:
1
  GPIOC ->BRR = GPIO_PIN_6;// Start Receiving
2
   HAL_SPI_Receive(&hspi1,(uint8_t *)angle_data, 1, 300);//Receive 1x16Bit
3
   GPIOC ->BSRR = GPIO_PIN_6;// End Receiving
4
   *angle_data&=0x7fff; // cause tD0 broke first bit
5
   *angle_data >>=5; // Shift for getting angular position (first 10 Bit)


Ich hoffe jemand weiß mir zu helfen.

Gruß Nassim
Angehängte Dateien:

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