Forum: Mikrocontroller und Digitale Elektronik STM32F4 verliert letztes Bit bei SPI-Kommunikation (MISO)


von Thomas M. (thomasme)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe ein STM32F4-DISCOVERY Board, welches per SPI als Master mit 
einem Slave kommunizieren soll.
Im Grunde funktioniert die Kommunikation, jedoch erkennt das STM32F4 am 
MISO Eingang das letzte Bit nicht.
Beispielsweise geht (siehe angehängtes Oszi-Bild, lila Leitung ist MISO, 
blau ist CLK) offensichtlich ein 0x2E1F ein (wäre richtig), das STM32F4 
erkennt es aber als 0x2E1E, das letzte Bit wird also falsch erkannt.
Habe es mit verschiedenen Requests versucht, bei der Response ist das 
letzte Bit immer 0. Eine komplette Verschiebung des Datenblocks um 1 Bit 
kann auch ausgeschlossen werden, da die anderen 15 an der richtigen 
Stelle stehen.

Hatte hier jemand schon mal ein ähnliches Problem, oder eine Idee, woran 
das liegen könnte?

Hier die SPI-Initialisierung:
1
tSpiError spiInit()
2
{
3
  GPIO_InitTypeDef   GPIO_InitStructure;
4
  NVIC_InitTypeDef   NVIC_InitStructure;
5
  EXTI_InitTypeDef    EXTI_InitStructure;
6
  SPI_InitTypeDef    SPI_InitStructure;
7
  tSpiError       Error = SpiNoError;
8
9
10
  // SPI1_NSS - PA15, SPI1_CLK - PB3, SPI1_MISO - PB4, SPI1_MOSI - PB5
11
  // EXT_INT_1 - PA1 to detect CS both edges
12
  // Peripheral Clock Enable -------------------------------------------------
13
  // Enable the SPI1 clock
14
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
15
16
  // Enable GPIO clocks
17
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
18
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
19
20
  // DEBUG-PIN
21
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
22
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
23
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
24
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
25
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
26
  GPIO_Init(GPIOB, &GPIO_InitStructure);
27
28
29
  // SPI GPIO Configuration --------------------------------------------------
30
  // Connect SPI pins to AF5
31
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_SPI1); // CS
32
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource3, GPIO_AF_SPI1); // SCK
33
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource4, GPIO_AF_SPI1); // MISO
34
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource5, GPIO_AF_SPI1);  // MOSI
35
36
  // MISO, MOSI
37
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
38
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
39
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
40
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
41
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
42
  GPIO_Init(GPIOB, &GPIO_InitStructure);
43
44
  // SCK
45
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
46
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
47
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
48
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
49
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
50
  GPIO_Init(GPIOB, &GPIO_InitStructure);
51
52
  // CS - Software controlled
53
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
54
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
55
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_25MHz;
56
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
57
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
58
  GPIO_Init(GPIOA, &GPIO_InitStructure);
59
  GPIO_SetBits(GPIOA, GPIO_Pin_15);
60
61
  // SPI configuration -------------------------------------------------------
62
  SPI_I2S_DeInit(SPI1);
63
  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
64
  //SPI_InitStructure.SPI_Mode = SPI_Mode_Slave;
65
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
66
  //SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;
67
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
68
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
69
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
70
  //SPI_InitStructure.SPI_NSS = SPI_NSS_Hard;
71
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
72
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
73
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
74
  SPI_InitStructure.SPI_CRCPolynomial = 0;
75
  SPI_Init(SPI1, &SPI_InitStructure);
76
77
78
  // Configure the SPI interrupt priority
79
  NVIC_InitStructure.NVIC_IRQChannel = SPI1_IRQn;
80
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = SPI_INTERRUPT_PRIO;
81
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;//(uint8_t) SpiSimInst_p;
82
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
83
  NVIC_Init(&NVIC_InitStructure);
84
85
  // Enable the Rx buffer not empty interrupt
86
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_TXE, ENABLE);
87
  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_RXNE, ENABLE);
88
//  SPI_I2S_ITConfig(SPI1, SPI_I2S_IT_ERR, ENABLE);
89
90
  // Enable the SPI peripheral
91
  // Enable in Slave-Mode should be done with CS-Signal -> additional EXTI-Input
92
  //SPI_Cmd(SPI1, ENABLE);
93
  // SPI_SSOutputCmd(SPI1, ENABLE);
94
Exit:
95
  return Error;
96
}

Vielen Dank schonmal.
Gruß
Thomas

von Rainer U. (r-u)


Lesenswert?

an der Clock-Polarität? (kann ja so richtig sein, aber häufiger sieht 
man "clock high when idle")

von Thomas M. (thomasme)


Lesenswert?

Hat mich auch ein wenig gewundert, da das ja eher untypisch ist, aber 
laut Datenblatt stimmt die Clock-Polarität so.

von Peter D. (peda)


Lesenswert?

Thomas M. schrieb:
> Hier die SPI-Initialisierung:

Wichtig wäre aber das Lesen der Daten.

Immer den kompletten Testcode als Anhang, statt Schnipselchen wo der 
Leser den nicht sichtbaren Code erraten muß.

von Thomas M. (thomasme)


Angehängte Dateien:

Lesenswert?

Okay, hier der Code zum senden der Daten.
Die umständliche Umsetzung rührt daher, dass ich mir erhofft hatte, dass 
sich der Fehler dadurch beheben ließe, wenn ich das zu sendende Wort in 
2 Byte zerlege und einzeln verschicke. Aber trotz unterschiedlicher 
Programmierung blieb der Fehler der Gleiche.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas M. schrieb:
> Beispielsweise geht (siehe angehängtes Oszi-Bild, lila Leitung ist MISO,
> blau ist CLK) offensichtlich ein 0x2E1F ein (wäre richtig), das STM32F4
> erkennt es aber als 0x2E1E, das letzte Bit wird also falsch erkannt.

 Mit CPOL=0 und CPHA=1, wird das als 0x2E1E erkannt, wo ist da dein
 Problem ?
 Und Slave ist ?

von Thomas M. (thomasme)


Lesenswert?

Es ist aber CPOL=0 und CPHA=0, dennoch fehlt das letzte Bit, da ist mein 
Problem.
Der Slave ist ein Elmos E981.08 PSI5 Transceiver.

von dummy (Gast)


Lesenswert?

Versuchs halt erst mal zu Fuss ohne Interrupt.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas M. schrieb:
> Es ist aber CPOL=0 und CPHA=0, dennoch fehlt das letzte Bit, da ist mein
> Problem.
 Probieren geht über Studieren.
 Alle Modes durchgehen, wenn es immer noch nicht stimmt, weiterfragen.

von Peter D. (peda)


Lesenswert?

Thomas M. schrieb:
> wenn ich das zu sendende Wort in
> 2 Byte zerlege und einzeln verschicke.

Dann sende auch ein 0x2F1F, d.h. ob der Fehler bei beiden Bytes 
auftritt.

Und C-Files heißen .c und nicht .txt!

dummy schrieb:
> Versuchs halt erst mal zu Fuss ohne Interrupt.

Gute Idee.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas M. schrieb:
> Die umständliche Umsetzung rührt daher, dass ich mir erhofft hatte, dass
> sich der Fehler dadurch beheben ließe, wenn ich das zu sendende Wort in
> 2 Byte zerlege und einzeln verschicke. Aber trotz unterschiedlicher
> Programmierung blieb der Fehler der Gleiche.

 Wie passt MISO zu senden ?
 Und wenn Framesize 16bit ist, warum auf 2Bytes zerlegen ?
 Interrupt braucht auch seine Zeit.

von Thomas M. (thomasme)


Lesenswert?

Marc Vesely schrieb:
>  Wie passt MISO zu senden ?
>  Und wenn Framesize 16bit ist, warum auf 2Bytes zerlegen ?

Hab ich doch geschrieben, war nur ein neuer Versuch, dass es vielleicht 
geht.
Wird ja immerhin auch in 2 Schritten empfangen dann...

von Thomas M. (thomasme)


Lesenswert?

Das Problem hat sich nun erledigt. Habe statt dem SPI1 Port den SPI2 
verwendet, entsprechend die Platine umgelötet und jetzt geht es.
Danke trotzdem für eure Ratschläge.
Gruß
Thomas

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Thomas M. schrieb:
> Das Problem hat sich nun erledigt. Habe statt dem SPI1 Port den SPI2
> verwendet, entsprechend die Platine umgelötet und jetzt geht es.

 Ähem.

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.