Forum: Mikrocontroller und Digitale Elektronik SPI NSS STM32 automatisch setzen


von Bert S. (kautschuck)


Lesenswert?

Hallo Zusammen,

Ich habe hier einen STM32F303K8T6 und verwende den SPI um Daten eines 
Sensors auszulesen. Bisher habe ich den NSS Pin als GPIO definiert und 
folgende Befehle für das Auslesen gebraucht:
1
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);
2
HAL_SPI_TransmitReceive(hspi,tx_data,rx_data,2,100);
3
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);

Nun möchte ich aber die NSS Pin Abwicklung automatisch in der 
Software/Hardware lösen, doch mir ist noch nicht klar wie das gehen 
soll. In Hardware kann man das anscheinend nicht, da die nur für die SPI 
Slaves zur Verfügung steht, richtig? Ist in den HAL Libraries irgendwo 
bereits das setzten und zurücksetzen des NSS pins eingebaut, so dass ich 
z.B mit "HAL_SPI_TransmitReceive(...)" mehrere Bytes automatisch 
auslesen kann? Interrupts bei jedem empfangenen Byte sind leider keine 
Option, da mir die anzahl Interrupts das Programm stark verlangsamen. Am 
Ende soll eigentlich der DMA eingesetzt werden, so dass ich nach einer 
gewissen Zeitperiode den Buffer auslesen und den Mittelwert über die 
Daten bilden kann.

von STM Apprentice (Gast)


Lesenswert?

Beim Konfigurieren der SPI kannst du spezifizieren ob NSS
per Hardware (also der SPI Maschine) oder per Software
gesteuert werden soll.

von Bert S. (kautschuck)


Lesenswert?

Das schon, aber die Hardware Steuerung funktioniert doch nur für Slaves, 
oder? Wenn ich Software Steuerung wähle, kann ich dann die HAL Libraries 
dazu bringen, den NSS in der Funktion HAL_SPI_TransmitReceive 
automatisch zu setzen?

von A. (Gast)


Lesenswert?

Bert S. schrieb:
> kann ich dann die HAL Libraries
> dazu bringen, den NSS in der Funktion HAL_SPI_TransmitReceive
> automatisch zu setzen?

Tja, du bist abhängig von HAL. Ich schaue ins Datenblatt, verstehe das 
Register und kann sofort alles so anpassen wie ich will.

von Bert S. (kautschuck)


Lesenswert?

Ich kann schon auch ein wenig CMSIS, aber wenn es einfacher geht 
verwende ich meist die HAL Libraries. Meine Frage ist nur, ob der SPI 
Prozess auch wirklich automatisiert werden kann, sprich DMA liest SPI 
Sensor kontinuierlich in einen Ringbuffer ohne dass ich immer einen 
Interrupt abarbeiten muss. Oder zumindest, ob ich einen SPI befehl geben 
kann um mehrere Bytes automatisch auszulesen.

von holger (Gast)


Lesenswert?

>Meine Frage ist nur, ob der SPI
>Prozess auch wirklich automatisiert werden kann

Das kann man nur beantworten wenn man deinen Sensor kennt.

von Christopher J. (christopher_j23)


Lesenswert?

Du kannst deine SPI-Transaktion genauso gut mit DMA machen und trotzdem 
den CS-Pin per Software setzen. Im Prinzip machst du das wie oben, also
1. CS-Pin auf low setzen
2. SPI-Transaktion (mit DMA) starten

Der Unterschied ist nur der, dass du den Pin jetzt nicht direkt wieder 
auf high setzen darfst, weil die Transaktion lediglich gestartet aber, 
mit an Sicherheit grenzender Wahrscheinlichkeit, noch nicht 
abgeschlossen ist. D.h. du darfst den CS-Pin erst wieder auf high setzen 
wenn du dir sicher bist, dass sie abgeschlossen ist. Eine Möglichkeit 
dazu bietet der DMA-Interrupt, der dir sagen kann ob eine Transaktion 
abgeschlossen ist.

Man kann den CS-Pin auch direkt per Hardware nutzen, allerdings gibt es 
da Einschränkungen, so dass z.B. bei einigen STM32 der CS-Pin zwischen 
zwei Bytes wieder auf high geht und das ist nicht unbedingt immer 
gewünscht. Ich würde dringend empfehlen, das per Software zu machen, es 
sei denn du kennst alle Nebenwirkungen und kannst damit leben.

von A. (Gast)


Lesenswert?

Auf Seite 272 siehst du, dass z.B. SPI2_RX mit DMA Channel 4 verbunden 
werden kann. Das ist schonmal ein Anhaltspunkt. Du wirst dir irgendwo 
eine statische Variable anlegen müssen, womit du dir merkst auf welcher 
Position deines Buffer-Arrays der DMA beim letzten Vergleich gezeigt 
hat.

Ist diese Position anders beim erneuten prüfen, hat der DMA etwas 
reinkopiert. Ein STM32f4 kann den DMA so einstellen, dass dieser immer 
im Kreis weitermacht und nie aufhört. Ich glaube beim F3 musst du 
zumindest ein Interrupt programmieren, was diesen wieder neu startet, 
nachdem der das Ende deines Arrays erreicht hat.

Auf Seite 1000 kannst du RXDMAEN DMA für ein SPI RX aktivieren. Ich habe 
es noch nicht benutzt, aber das wird wohl so sein, dass wenn ein Byte 
ankommt, dieses halt in dein Array geschrieben wird per DMA und dieser 
eines hochzählt.

Dann siehst du in deiner Main-Loop, dass DMA auf Position 1 zeigt, du 
aber auf Position 0 (statische Positions Variable) und du weisst, dass 1 
Byte empfangen wurde.

von A. (Gast)


Lesenswert?

PS: Wenn nur der Fühler an SPI hängt, kannst du evtl. dessen CS immer 
auf Low lassen (per Software einmal setzen) und über einen Timer in 
Hardware den SPI einmal takten lassen, worauf dieser per DMA die Daten 
in ein Array schiebt.

Z.B. ein Timer löst einen DMA aus, worauf SPI ein Byte rausschiebt. Dasn 
heißt ja, dass auch ein Byte eingelesen wird. Und das ist dann dein 
Empfangs DMA. So irgendwie könnte das voll automatisch gehen. Aber 
leider ist SPI eher nicht für sowas gedacht, dass es von sich aus eine 
Kommunikation eröffnet.

von Bert S. (kautschuck)


Lesenswert?

Es handelt sich um diesen Sensor hier:

https://ams.com/eng/content/download/438523/1341157/file/AS5048_DS000298_3-00.pdf

Man sieht, dass die SPI Leitung zwischen je zwei Bytes wieder auf High 
gehen muss. Es gibt ja zwei Formate für den SPI, Motorola und TI. 
Motorola erzeugt ja keine NSS Pules zwischen den Bytes, dann wäre also 
TI das richtige Format?

von A. (Gast)


Lesenswert?

Ich würde erstmal TI verwenden.

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.