Hallo zusammen
Ich möchte mit einem STM32F103CBT6 einen Schrittmotor Controller TMC5160
per SPI ansteuern. Nun habe ich ein Problem mit der konfiguration des
SPI am STM32. Ich schaff es einfach nicht eine Verbindung zum TMC5160
herzustellen. Ich programmiere mit der STM32cubeIDE.
Zum testen habe ich mal ein Arduino Nano genommen und den Beispielcode
von Trinamic, und funktioniert natürlich einwandfrei, an der Hardware
liegts also nicht.
Arduino Code (läuft):
1
#include<SPI.h>
2
#include"TMC5130_registers.h"
3
4
/* The trinamic TMC5130 motor controller and driver operates through an
5
* SPI interface. Each datagram is sent to the device as an address byte
6
* followed by 4 data bytes. This is 40 bits (8 bit address and 32 bit word).
7
* Each register is specified by a one byte (MSB) address: 0 for read, 1 for
8
* write. The MSB is transmitted first on the rising edge of SCK.
9
*
10
* Arduino Pins Eval Board Pins
11
* 51 MOSI 32 SPI1_SDI
12
* 50 MISO 33 SPI1_SDO
13
* 52 SCK 31 SPI1_SCK
14
* 25 CS 30 SPI1_CSN
15
* 17 DIO 8 DIO0 (DRV_ENN)
16
* 11 DIO 23 CLK16
17
* GND 2 GND
18
* +5V 5 +5V
19
*/
20
21
intchipCS=10;
22
constbyteCLOCKOUT=9;
23
intenable=8;
24
25
voidsetup(){
26
// put your setup code here, to run once:
27
pinMode(chipCS,OUTPUT);
28
pinMode(CLOCKOUT,OUTPUT);
29
pinMode(enable,OUTPUT);
30
digitalWrite(chipCS,HIGH);
31
digitalWrite(enable,LOW);
32
digitalWrite(CLOCKOUT,LOW);
33
34
//set up Timer1
35
/* TCCR1A = bit (COM1A0); //toggle OC1A on Compare Match
36
TCCR1B = bit (WGM12) | bit (CS10); //CTC, no prescaling
Der Master (STM32) senden 5 bytes zum Slave (TMC5160), gleichzeitig
sendet der Slave 5 bytes zurück (Status). Das erste Byte ist die Adresse
des Registers. Aussehen sollte das so :
1
SPI_w: 80 0 (Befehl)
2
SPI_r: 80 FA000 (Antwort)
Aber bei mir kommt nur ein Datenmüll zurück. Der Befehl wird schon gar
nicht richtig zum Slave übertragen, sonst würde mindesten der Motor am
Controller laufen.
Ich bin mir nicht sicher ob HAL_SPI_TransmitReceive richtig ist ? Im
Arduino Code wird SPI im Mode 3 konfiguriert, bin aber der Meinung, dass
ich das so richtig konfiguriert habe ?
Ich hoffe jemand kann mir weiter helfen, oder hat sogar ein
Beispielcode.
Danke und Gruss
Michael
Ok danke. Ich bin davon ausgegangen, wenn NSS auf Hardware Output
eingestellt ist, dass die SPI Schnittstelle das selber steuert. Nun habe
ich das NSS manuel per Software gesteuert, aber es ändert sich nichts.
Auch den rxbuffer habe ich separiert, leider ohne erfolg.
Bei HAL_SPI_TransmitReceive verstehe ich nicht ganz wie lang die
Datenlänge eingestellt werden muss, man findet im www unterschiedliche
angaben. Bei 5 byte senden & empangen = 10 ? Oder doch nur 5 ?
Die Peripherie kann soweit ich weiß nicht wirklich den NSS ansprechen
das ist etwas verwirrend.
Wenn du bei DataSize 8_Bit eingestellt hast dann sendet er bei 1 1 Byte
bei 2 2 Byte und so weiter. Wenn du DataSize auf z.B. 16 stellst schickt
er mit 1 2 Byte mit 2 4 Byte usw.
In deinem Fall wenn du 5 Byte verarbeiten willst musst du bei den
aktuellen Einstellungen mit 8 Bit also 5 einstellen. Bei TransmitRecive
sendet und empfängt er gleichzeitig. Wie gesagt müssen die Buffer
unterschiedlich sein.
Ist die Taktrate und der SPI Moder richtig eingestellt?
Wenn ich das richtig sehe will der TMC SPI Mode 3 also CPOL High und und
Seconds Edge. Damit wären deine CLKPhase falsch. Außerdem kann der TMC
ohne externen Oszillator nur 8MHz, wenn du den F1 mit 72MHz taktest und
einen Prescaler von 8 hast sind das aber 9MHz. Wenn du am TMC einen
Oszillator hast sollte das aber gehen dann kann er 16MHz. Du solltest
den NSS auch auf disable stellen und ihn komplett in der Software
steuern.
Ansonsten kann es noch sein das die Konfiguration der SPI Schnittstelle
nicht vollständig ist. Der Code den du gepostet hast reicht nicht. Es
muss noch Code geben der die GPIOs initialisiert und die Clock für die
Peripherie aktiviert. Sollte das mit der IDE erstellt worden sein müsste
er das aber angelegt haben.
Ok danke ! super jetzt läufts ! CLKPhase war falsch, im Arduino Code war
der auf 1 gesetzt, und ich habe gedacht das wäre das gleiche wie 1 Edge.
Aber wie gesagt, das 2. Problem war auch das NSS Signal, geht nur per
Software. Was meinst Du, muss zwischen NSS und der ersten SPI
Komunikation eine kleine Verzögerung sein, gemäss Timingdiagramm des TMC
sollte es nicht nötig sein ? Es funktioniert bis jetzt auch einwandfrei.
1
HAL_GPIO_WritePin(GPIOA,CS_Pin,0);
2
// delay ?
3
HAL_SPI_TransmitReceive(&hspi1,data,rxData,5,100
4
// delay ?
5
HAL_GPIO_WritePin(GPIOA,CS_Pin,1);
Mit 16 prescaler ergibt sich eine Baudrate von 3 mbit/s gemäss IDE.
Michael L. schrieb:> Was meinst Du, muss zwischen NSS und der ersten SPI Komunikation eine> kleine Verzögerung sein
In der Regel nicht. Die Verzögerung zwischen GPIO Write und bis SPI
anfängt zu senden reicht meistens massig aus.
Michael L. schrieb:> Mit 16 prescaler ergibt sich eine Baudrate von 3 mbit/s gemäss IDE.
Das kommt auf deinen Systemtakt an. In dem Fall nutzt du wohl 48MHz
statt den möglichen 72MHz
Guest schrieb:> Das kommt auf deinen Systemtakt an. In dem Fall nutzt du wohl 48MHz> statt den möglichen 72MHz
Ja genau, läuft mit 48Mhz.
Vielen dank für deine Hilfe, hat mir sehr weitergeholfen.