Forum: Mikrocontroller und Digitale Elektronik STM32 HAL SPI nur 18 Bits senden oder Bitbanging?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Ralph (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

ich möchte gerne ein Baustein (HMC6300) via SPI konfigurieren (siehe 
Anhang). Leider umfasst das Register des Bausteins nur 18 Bits. Ein 
Versuch mit der HAL_SPI_TransmitReceive() Funktion 24 Bits (um 5 
führende Nullen ergänzt, welche ggf. durch das FIFO gelatched werden) zu 
übertragen schlug fehl.

Gibt es eine Möglichkeit nur die benötigten 18 Bits zu senden?

Falls nur Bitbanging möglich ist, wie kann ich geschickt auf die 
GPIO-Pins zugreifen? Die bestehende SPI Konfiguration kann nicht ohne 
weiteres geändert werden, da auf dem SPI-BUS noch andere Bausteine sind, 
welche konfiguriert werden müssen.

Wäre sowas in der Art möglich:
void Bitbanging_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t 
*pTxData, uint8_t *pRxData, uint8_t HMC630x_NUM_TX_BITS, uint8_t 
HMC630x_NUM_RX_BITS)
{
//Default Bitbanging
...

//Pseudocode für GPIO-Zugriff über SPI-Handler
HAL_GPIO_WritePin(hspi.MOSI_Port, hspi.MOSI_PIN, MOSI_PIN_SET);
}

Vielen Dank,

Ralph

von Frickelfritze (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> Ein
> Versuch mit der HAL_SPI_TransmitReceive() Funktion 24 Bits (um 5
> führende Nullen ergänzt, welche ggf. durch das FIFO gelatched werden) zu
> übertragen schlug fehl.

Nach Adam Riese (und Eva Zwerg) müssten 6 führende Nullen ergänzt
werden damit 24 Bits aufgefüllt werden.

Aber ich behaupte dass du etwas anderes falsch machst. Es ist
offensichtlich dass die Vorgeschichte (was vor den 18 Bits
passiert) unerheblich ist, was sich aus dem aus dem Datenblatt
zitierten Absatz (speziell der zweite Teil) entnehmen lässt:

--------------------------------------------------------------
After the 18th clock pulse of the write operation, the ENABLE
line returns high to load the register array on the IC; prior
to the rising edge of the ENABLE line, no data is written to
the array.
--------------------------------------------------------------

Also nur die steigende Flanke der ENABLE Leitung entscheidet
was in die Register geschrieben wird.

Entweder ist deine SPI falsch konfiguriert (Clock Polarität,
Clock Phase) oder die Ausrichtung deiner Daten in den 24 Bit
ist nicht korrekt.

von Frickelfritze (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> Gibt es eine Möglichkeit nur die benötigten 18 Bits zu senden?

Beachte auch dass (eher ungewöhnlich) die Bits vom nieder-
wertigsten zuerst bis zum höchstwertigen gesendet werden.
Das ist eher die Analog Devices Manier, während man bei
(ehemals) Hittite "immer" MSB zuerst überträgt / übertragen hat.

von Peter D. (peda)


Bewertung
1 lesenswert
nicht lesenswert
Die Datenlänge ist beim STM32F303 von 4-16 Bits konfigurierbar. Also 
einfach 2*9 Bit senden und schon hast Du die 18 Bits.

SPI control register 2 (SPIx_CR2)
Bits 11:8 DS [3:0]: Data size
These bits configure the data length for SPI transfers:
1000: 9-bit

von Ralph (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

zunächst einmal vielen Dank für eure hilfreichen Antworten.

@Frickelfritze
Du hast natürlich recht, es müssen 6 führende Nullen sein. Die 
Problematik mit dem LSB first habe ich abgehandelt und der Vereinfachung 
nicht erwähnt. Falls es wen interessiert, dass Datenwort erzeuge ich wie 
folgt:
1
 ...
2
  /* SPI1 parameter configuration*/
3
  hspi1.Instance = SPI1;
4
  hspi1.Init.Mode = SPI_MODE_MASTER;
5
  hspi1.Init.Direction = SPI_DIRECTION_2LINES;
6
  hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
7
  hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
8
  hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
9
  hspi1.Init.NSS = SPI_NSS_SOFT;
10
  hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
11
  hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; //Kompatiblität mit anderen Bausteinen
12
 ...
13
14
 ...
15
uint32_t volatile TxWord, RxWord;
16
  
17
TxWord = (ADDRESS_BIT << HMC630x_ADDRESS_BIT_OFFSET) | (R_W_Bit << HMC630x_R_W_Bit_OFFSET) | (REG_CTRL_Bit << HMC630x_REG_CTRL_BIT_OFFSET) | (Value << HMC630x_VALUE_BIT_OFFSET);  
18
19
TxWord = (TxWord << 6); //führende Nullen anhängen
20
TxWord = Swap4Bytes(TxWord); //Byteweise Swappen
21
TxWord = reverse32(TxWord); //alles Bits reversen
22
23
HAL_SPI_TransmitReceive(hspi, (uint8_t *)&TxWord, (uint8_t *)&RxWord, HMC630x_WORD_WIDTH_BYTES, HAL_MAX_DELAY);
24
 ...

Prinzipell kann ich jetzt das gewünschte Bitpattern senden. Bei 
Anschluss des HMC6300 wird jedoch die Clk und MOSI Leitung auf high 
gezogen, ggf. ist dies noch ein Hardwareproblem bei dem ich bei muss. 
Jedenfalls antwortet der HMC6300, was er eigentlich bei gesetztem 
Write-Bit nicht machen sollte (siehe Timing Diagramm in meinem ersten 
Post).

Hier ein beispielhaftes Bitpattern an den HMC6300 gesendet (lsb first, 
ohne die 6 führende Nullen):
011100000011110000

Anbei die zugehörige Ausgabe auf dem Logikanalyser.

@Peter D.
Ich nutze einen STM32L052K8U. Mir ist noch nicht klar, wie ich die 
Datensize geschickt unter Kompatiblität zu CubeMX ändern kann. Kann ich 
die Datensize auf zur Laufzeit ändern? Wie erwähnt hängen noch andere 
Bausteine mit an dem Bus und müssen konfiguriert werden.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

Ich würde da einfach ne 9 eintragen und schauen, ob der Compiler 
meckert.

Ralph schrieb:
> Kann ich
> die Datensize auf zur Laufzeit ändern?

Du kannst das SPI jederzeit umkonfigurieren, wenn ein Transfer beendet 
ist.

von Johnny B. (johnnyb)



Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> Ich nutze einen STM32L052K8U. Mir ist noch nicht klar, wie ich die
> Datensize geschickt unter Kompatiblität zu CubeMX ändern kann.

Das kannst Du ja in CubeMX einstellen, siehe Anhang. (ich sehe aber 
gerade, dass der STM32L052 wohl nur 8- und 16-bit unterstützt)

: Bearbeitet durch User
von Ralph (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Hm oky also kann ich via Hardware nur 8 oder 16 Bit ausgeben. Schade.

Besteht die Möglichkeit die SPI-Pins ans Port A zur Laufzeit auch via 
Bitbanging zu bedienen?

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Johnny B. schrieb:
> ich sehe aber
> gerade, dass der STM32L052 wohl nur 8- und 16-bit unterstützt

So siehts aus.
Daher sollte man das konkrete Target immer als erstes angeben.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> Besteht die Möglichkeit die SPI-Pins ans Port A zur Laufzeit auch via
> Bitbanging zu bedienen?

Natürlich, das geht immer.

von Ralph (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hm, wie den? Ich kann in CubeMX die Pins als Hardware-SPI ODER als GPIO 
Input/Output konfigurieren . Beides geht nicht bzw. wüsste ich nicht 
wie. Kann ich trotz Hardware-SPI Konfiguration eine Art 
HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_SET); 
aufrufen?

Um weiter zu kommen habe ich mal Hardware-SPI durch Bitbanging ersetzt 
und getestet (zwar unschön aber naja.. ).
1
void Bitbanging_SPI_Transmit(uint32_t TxWord)
2
{
3
   for (uint8_t i = 0; i < 18; i++)
4
   {
5
       if (TxWord & 0x1)
6
           HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_SET);          
7
       else
8
           HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_RESET);
9
10
       HMC630x_Delay();
11
       HAL_GPIO_WritePin(SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_SET);
12
       HMC630x_Delay();
13
       HAL_GPIO_WritePin(SPI_CLK_GPIO_Port, SPI_CLK_Pin, GPIO_PIN_RESET);
14
       HMC630x_Delay();
15
16
       TxWord >>= 1;
17
   }
18
  
19
   HAL_GPIO_WritePin(SPI_MOSI_GPIO_Port, SPI_MOSI_Pin, GPIO_PIN_RESET);
20
}

Die Ausgabe funktioniert laut Logicanalyser (siehe Anhang). Leider 
antwortet der HMC6300 an MISO, was er bei einem Write nicht machen 
sollte.

Nach meinem Verständnis endspricht die Ausgabe jetzt der des 
Datenblattes. Etwas unsicher bin ich mir bei der TX-Adresse: "the Tx 
Chip Address 110, LSB first)." -> Verstehe ich so, dass ich erst die 
Null sende und dann die beiden Einsen.

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Niemand zwingt dich dazu, die Konfiguration der I/O Pins ausschließlich 
über Cube MX zu machen. Dein Programm kann sie zur Laufzeit beliebig 
umkonfigurieren.

Falls Dir das dann in Kombination mit Cube MX zu kompliziert wird - 
willkommen im Club. Ich benutze die ganze HAL gar nicht, CMSIS und ein 
paar Zeilen eigener Code genügen mir.

: Bearbeitet durch User
von Johnny B. (johnnyb)


Bewertung
0 lesenswert
nicht lesenswert
Zwischenfrage; Elektrisch ist das SPI vom HMC6300 richtig angeschlossen, 
d.h. mit 1.2V Pegelwandler?

von Ralph (Gast)


Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@Stefanos
Oky danke. Dann werde ich sobald das Bitbanging funktioniert, versuchen 
den Code zusammenzuführen. Schade, dass dann wahrscheinlich die 
Kompatiblität zu CubeMX verloren gehen wird. Bis jetzt konnte ich immer 
in CubeMX neuen Code generieren und nahtlos in den bestehenden 
einsetzen.

@Johnny B.
Ja genau, ich verwende Pegelwandler (MAX3392EEUD+).
Ich habe anbei drei Screenshots vom Oszilloskope beigefügt (Übersicht, 
Zoom, noch mehr Zoom). Das Oszilloskope ist hinter den Pegelwandlern, 
direkt am HMC6300 angeschlossen. Man sieht relativ starkes 
Überschwingen, ggf. wäre eine Serienterminierung sinnvoll. Was meint 
Ihr?

Ich glaube trotzdem nicht, dass dies der Grund dafür ist, dass der 
HMC6300 nicht funktioniert. Aktuell gehen mir die Ideen etwas aus.

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Gesund sehen die Signale nicht aus und 1,2V Pegel haben die auch nicht 
wirklich, jedenfalls nicht für lange.

Ausserdem funkt schon nach 16 Takten das CS dazwischen, so kommt es 
nicht zu Übernahme der 18 bit.

von pegel (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Den zweiten Satz nehme ich zurück.
Da muss ich mich vorhin irgendwie verguckt haben.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.