Forum: Mikrocontroller und Digitale Elektronik STM32-M0 -SPI Problem


von Andreas D. (andinger)


Lesenswert?

Hallo Leute,

ich dreh hier grad durch, weil ich mit dem STM32F0 Discovery-Board 
simplen SPI-Datentransfer nicht zum Laufen bekomme.
Argh, ich hab doch Urlaub und wollt gemütlich weng basteln :).

Naja, vielleicht könnt ihr mir ja helfen - meine letzte Hoffnung:
Denn hier sind ja anscheinend ein paar Leute unterwegs, die sich mit den 
ST-µCs auskennen - ich wäre euch sehr dankbar, wenn ihr kurz mal über 
meinen Code schaut, und mir sagt was ich falsch gemacht habe.

Soviel zur Vorrede:
Ich habe gerade keine Ansprüche mehr. Ich will fürs erste nur das es 
läuft.
Ich brauch kein nicht/halbfunktionierendes NSS-Signal und habe auch 
mittlerweile meine Peripherie abgeklemmt und direkt SPI1 mit SPI2 auf 
dem Discovery-Board verbunden um anderweitige Fehler möglichst 
auszuschließen.

SPI1 ist mein Master und schickt ein Byte an den Slave.
SPI2 ist mein Slave.

MOSI ist mit MOSI verbunden.
MISO habe ich für den Versuch auch weggelassen
NSS von SPI2 ist direkt mit GND verbunden - also immer aktiv


Initialisierung von SPI1 (Master) und SPI2 (Slave):
1
/*SPI1-Konfigurieren: 
2
  SCK = PA5
3
  MISO = PA6
4
  MOSI = PA7
5
*/
6
7
/*Clock für die Peripherie einschalten*/
8
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
9
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA , ENABLE);
10
 
11
/* Benötigte PINS aktivieren */
12
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
14
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
15
GPIO_Init(GPIOA, &GPIO_InitStructure);
16
17
/*SPI1-Konfigurieren*/
18
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
19
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
20
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
21
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
22
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
23
SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;  //Nicht verwendet
24
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
25
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
26
SPI_InitStructure.SPI_CRCPolynomial = 7;
27
SPI_Init(SPI1,&SPI_InitStructure);
28
29
/*SPI1 aktivieren*/
30
SPI_Cmd(SPI1, ENABLE);
31
 
32
33
/*SPI2-Konfigurieren: 
34
  NSS = PB12   //Pin direkt mit GND verbunden, damit SPI immer aktiv ist.
35
  SCK = PB13
36
  MISO = PB14
37
  MOSI = PB15
38
*/
39
40
/*Clock für die Peripherie einschalten*/
41
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
42
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
43
44
/* Benötigte PINS aktivieren */
45
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
46
GPIO_Init(GPIOB, &GPIO_InitStructure);
47
48
49
/*SPI2-Konfigurieren*/
50
SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;  //Empfänger ist Slave
51
/*SPI2 aktivieren*/
52
SPI_Cmd(SPI2, ENABLE);


Meine Endlosschleife schaut dann so aus - da sind keine Interrupts mehr 
- da ist eigentlich gar nichts mehr. Es geht trotzdem nicht.
Ich glaube ich habe einfach irgendwo einen dummen Denkfehler und checks 
net :(.

1
while (1)
2
{
3
c_daten=0;
4
5
SPI_SendData8(SPI1,0xAA);
6
7
/* 100 ms delay */
8
Delay(100);
9
    
10
c_daten =  SPI_ReceiveData8(SPI2);
11
12
/* 100 ms delay */
13
Delay(100);
14
    
15
}

In c_daten steht NACH dem ersten Durchlauf der Schleife weiterhin 0x00 
und dann in allen weiteren Schleifen-Durchläufen 0xFF - unabhängig von 
dem was von SPI1 gesendet wird...

Ich würd mich sehr sehr über Hilfe freuen, weil ich wie gesagt grad 
ziemlich am Ende bin.

von avrasm (Gast)


Lesenswert?

Fehlt da nicht ein

SPI_Init(SPI2,&SPI_InitStructure);
            ^

?

von Andreas D. (andinger)


Lesenswert?

Ja das stimmt, das is beim Vereinfachen irgendwie verloren gegangen. 
Danke für den Hinweis. Ich habs jetzt wieder hinzugefügt. Aber es ändert 
nichts dran - die "Symptome" sind genau gleich... :(

von avrasm (Gast)


Lesenswert?

Dann schau doch mal direkt in das SPI2-Empfangsdatenregister
rein, und zwar bevor Du SPI_ReceiveData() aufrufst.
Ich nehme an, Du hast einen Debugger...

>Ich brauch kein nicht/halbfunktionierendes NSS-Signal

Du nicht, aber vielleicht die STM32 SPI Hardware.

In Hardware mode (refer to Slave select (NSS) pin management on page 
658), the
NSS pin must be connected to a low level signal during the complete byte 
transmit
sequence. In NSS software mode, set the SSM bit and clear the SSI bit in 
the SPI_CR1
register.

von Martin M. (capiman)


Lesenswert?

Hast Du schon mal geprüft, ob Takte auf SCK zu sehen sind?
Hast Du schon mal geprüft, ob Sendedaten vom Master gesendet werden?
Wenn eines davon nicht da ist, steckt der Fehler vermutlich im Master...
Hast Du einen Logic Analyzer, Oszi oder TTL-Prüfstift,
eine LED mit passendem Vorwiderstand ?
Dann einfach mal die 3 Leitungen ansehen...

von Andreas D. (andinger)


Lesenswert?

avrasm schrieb:
> In Hardware mode (refer to Slave select (NSS) pin management on page
> 658), the
> NSS pin must be connected to a low level signal during the complete byte
> transmit

Hardwaremode hab ich aktiviert.
Dem Master sollte das doch egal sein - oder nicht? Ich hab in meinem 
Fall das NSS-Bit beim Master ja nicht mal konfiguriert. Oder kann dass 
der Grund sein:

Muss ich beim Master auch NSS konfigurieren???

Der NSS vom Slave ist wie gesagt direkt mit GND verbunden.

Zu der anderen Sache:
Ich hab leider kein Oszi hier. Aber das mit der LED ist ne gute Idee - 
da hab ich welche da, denn auf dem Evalboard sind ja LEDs :)

Kann es sein, dass die SPI-Einheit von dem Board physikalisch beschädigt 
ist?
Das Board ist praktisch neu.

von Andreas D. (andinger)


Lesenswert?

OK, ihr hattet Recht, das NSS vom Master muss auch konfiguriert sein und 
der NSS beim Master muss auf HIGH-Pegel gesetzt sein - dann klappts.

Sowas ist aber doch ziemlich sinnlos - naja, vielleicht könnte man es 
bei irgendeinem Multimasterdings brauchen....
Oder versteh ich da was falsch?

Danke jedenfalls für eure Hilfe!! Morgen mach ich mal weiter :)

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.