Forum: Mikrocontroller und Digitale Elektronik SPI Bus programmieren


von Chris H. (xkris)


Angehängte Dateien:

Lesenswert?

Hallo,

ich muss einen Schrittmotortreiber per SPI konfigurieren. Das Problem 
ist, das der Treiber 20bit Worte erwartet, mein Controller (XC167) 
hardwareseitig aber nur maximal 16bit unterstützt.
Ich hab nur wenig Erfahrung mit SPI und Mikrocontrollerprogrammierung 
aber auf den ersten Blick müßte sich doch das auch ganz easy per 
Software machen lassen in dem man einfach die dedicated SPI Pins des 
Controllers als normale I/O Pins konfiguriert, dann den Chip Select 
runterzieht, die Bits auf den Datenbus packt und für jedes Bit die 
Clockleitung kurz auf 1 setzt um das Bit einzulesen. Das ganze dann 
entsprechend häufig wiederholen und fertig. Muss man nur drauf achten, 
das die jeweils angegeben Mindestzeiten eingehalten werden.

Funktioniert das so einfach oder übersehe ich was?

von Arne (Gast)


Lesenswert?

Chris H. schrieb:
> aber nur maximal 16bit

Was ist denn, wenn Du Deine 20bit auf zwei 10 bit Worte aufteilst und 
diese dann an den Slave schickst?
Ich schicke hier an einem STM32 immer 8Bit Worte raus, aber am Oszi kann 
ich nicht auf Anhieb sagen, wo ein Wort beginnt, d.h. Pausen zwischen 
letztem Bit von Wort n und erstem Bit von Wort n+1 sind genauso lang, 
wie alle anderen auch.

von Niemand (Gast)


Lesenswert?

@Arne
Sorry, ich denke, dass geht schief
@xkris
Danke, dass Du uns den genauen Typ des Treibers verheimlichst. Das macht 
es dann besonders spannend ;-) Du hast vermutlich einen Trinamic, so was 
wie TMC389 o.ä. Wenn Du das Datenblatt bis zum Abschnitt 18.2. gelesen 
hättest, würdest Du auch verstehen, wie man 24Bit oder 32Bit über die 
SPI an den Trinamic schickt, und dann doch nur die letzten übertragenen 
20Bit beachtet werden !

von Niemand (Gast)


Lesenswert?

@Arne
Ich nehme das zurück. Der XC167 kann unterschiedliche Datenlängen, unter 
anderem auch 10Bit. Damit ist Dein Vorschlag natürlich machbar.
@xkris
Wie schaltest Du das CSN ?

von Chris H. (xkris)


Lesenswert?

Niemand schrieb:
> @xkris
> Danke, dass Du uns den genauen Typ des Treibers verheimlichst.

Sorry, ist ein TMC260 ;)

Dass das Reinschreiben in mehreren Etappen funktionieren könnte hab ich 
vermutet, auch wenn das Datenblatt idese Option nicht explizit erwähnt. 
Das Auslesen dürfte sich aber schwierig gestalten da man an die letzten 
4 Bits des jeweiligen Registers nicht herankommt.

>Wie schaltest Du das CSN ?

Verstehe die Frage nicht. Ich hatte vor die Leitung durch den Controller 
auf low zu ziehen und nach dem Zugriff wieder auf High zu setzten. 
Warum?

von Arne (Gast)


Lesenswert?

@Niemand
Auch wenn der XC167 nur 20Bit Worte könnte: warum funktioniert mein 
Vorschlag nicht? Zwei direkt aufeinander folgende 10bit Worte sehen für 
den Empfänger doch erstmal wie ein 20Bit Wort aus, wenn er auf solch 
eine Wortgröße initialisiert ist. Erklär doch mal bitte.

von Arne (Gast)


Lesenswert?

Chris H. schrieb:
> Das Auslesen dürfte sich aber schwierig gestalten da man an die letzten
> 4 Bits des jeweiligen Registers nicht herankommt.

So meinte ich das nicht.
Ich gehe davon aus, dass der Empfänger genau 20bit Worte serviert haben 
will. Der Sender kann maximal 16bit Worte. Du initialisierst den Sender 
auf 10bit Wortbreite, schickst zweimal 10bit hintereinander, ohne /CS 
(NSS) zurückzunehmen. Somit müssten sich die zweimal 10bit am Empfänger 
wie ein 20bit Wort ins Schieberegister "reinschieben".
Ich verstehe Deinen Satz so, dass der Empfänger 20Bit Worte haben will, 
Dir aber nur den Zugang zu 16bit davon gestattet?

von Chris H. (xkris)


Lesenswert?

> Ich verstehe Deinen Satz so, dass der Empfänger 20Bit Worte haben will,
> Dir aber nur den Zugang zu 16bit davon gestattet?

Das verstehe ich nun wiederrum nicht bzw. ist es nicht eindeutig. Daher 
nochmal zur Erklärung
Master --> XC167, unterstützt max. 16bit SPI
Slave -->  TMC260  verwendet 20 Bit Register

Beim Schreiben, also Master sendet an Slave, wahrscheinlich kein 
Problem. Kann man in 2 Etappen machen, z.B. zwei mal 10 Bit oder auch 
zwei mal 16 Bit, relevant sind ja nur die letzten 20 Bit die gesendet 
wurden. Alles was älter fliegt aus dem Shiftregister des TMC260 ohnehin 
raus.

Beim Lesen, also Master bekommt Daten vom Slave, weiss ich nicht wie es 
sich verhält. Ich bekomme beim ersten Zugriff maximal 16bit, danach 
weiss ich nicht was passiert bzw. wann der Slave den Zugriff als beendet 
ansieht und den Pointer wieder zurücksetzt. Möglicherweise genügt es, 
den CS weiter aktiv zu halten und weiter zu takten, vielleicht bekommt 
man dann die nächsten vier Bit ausgeliefert, vielleicht fängt er aber 
auch wieder von vorne an...

von Niemand (Gast)


Lesenswert?

@Arne
Ich sagte ja schon, dass Du mit Deinem Vorschlag recht hast. Die 
Voraussetzung ist jedoch die Einstellung einer Wordgröße anders als 
8Bit, z.b. 4, oder 10 oder 20. Da immer ein Takt mitläuft, würden 
überzählige Bits, wie beispielsweise 3*8Bit, den Empfänger 
durcheinanderbringen. Ich kann es gerade nicht besser erklären. Nimm 
meine Entschuldigung an und das Du Recht hast.
Beim Trinamic scheint dies aber ohnehin nicht relevant zu sein. Wenn ich 
das Datenblatt richtig verstanden habe, nimmt dieser als Empfänger immer 
die letzten 20Bit vor dem CSN Low/High Übergang. Als beim Senden einfach 
3*8Bit senden.
Beim Lesen verhält es sich sehr ähnlich. Die ersten 20Bits sind die 
Statusbits.

von Niemand (Gast)


Lesenswert?

@xkris
Wie gesagt, beim schreiben die letzen 20Bit sind relevant, beim Lesen 
die ersten 20Bit, wobei lesen und schreiben bei SPI gleichzeitig 
passiert. Du brauchst Dein Interface also einfach nur auf standard 08/15 
8Bit SPI, MSB first programmieren. Für die Schreiboperation CS auf Low, 
3*8Bit, dann CS auf High

von Chris H. (xkris)


Lesenswert?

Niemand schrieb:
> @xkris
> Du brauchst Dein Interface also einfach nur auf standard 08/15
> 8Bit SPI, MSB first programmieren....

Ja, sollte funktionieren. Gibt ja auch kein Protokoll das irgendwelche 
Start oder Stopbits vorschreibt. Scheint also recht simpel. Danke für 
die Hilfe

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Chris H. schrieb:
> Gibt ja auch kein Protokoll das irgendwelche Start oder Stopbits
> vorschreibt.
Nein, gibt es nicht. Und das ist ja gerade das neckische am SPI: die 
steigende Flanke am SlaveSelect definiert das Ende der Übertragung. Und 
deshalb kann man 24 Bit auch als 3x8 versenden. Und die 
Schieberegister-Bauweise sorgt dafür, dass nur die letzten (neuesten) 
Bits verwendet werden...

von Arne (Gast)


Lesenswert?

Niemand schrieb:
> Nimm meine Entschuldigung an und das Du Recht hast.
Ich sehe keine Notwendigkeit zu einer Entschuldigung! Wir diskutieren 
einfach ;)

@xkris

Jetzt wird es klar. Ich habe nur die Richtung Master->Slave bedacht. 
Aber Du hast natürlich recht: andersrum schickt Dir der Slave 20bit. 
Aaaaber:
Du bist ja Master! Du musst bei SPI ja 16bit schicken, um vom Slave 
16bit zu erhalten, da der Master ja den SCLK Takt erzeugt.
Programmiere den Master doch so, dass er 10bit Worte sendet und empfängt 
(Dir also bei 10bit im Empfangsregister einen IRQ auslöst o.ä.). Dann 
schickst Du 10bit Dummydaten raus, der Slave überlagert diese mit seinen 
ersten 10bit der Antwort. Jetzt hält der Slave die Klappe, da Du ja den 
Takt nach dem 10. Dummybit wegnimmst - bzw. die HW macht das. Du liest 
Dein Empfangsregister aus. Nun nochmal 10 Dummybits, um Antwortbit 11-20 
vom Slave zu bekommen.
Wichtig: DU bist MASTER und gibst den TAKT vor.

von Chris H. (xkris)


Lesenswert?

Jup, ist mittlerweile alles klar, aber danke 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.