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:
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.
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?
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.
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.
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.
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.
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.
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?