Forum: Mikrocontroller und Digitale Elektronik stm32 SPI - Lesen liefert keine Daten.


von Arbeitnehmer (Gast)


Lesenswert?

STM kommuniziert mit einem externen SPI EEPROM. Logic Analyzer zeigt mir 
auf der MISO Leitung die Daten, die ich zuvor über MOSI geschrieben 
habe. Leider erzählt mir die Empfangsfunktion, dass 0xFF empfangen 
wurde. Ich habe keine Idee woran das liegen mag. Beim Einlesen sende ich 
wie "vorgeschrieben" Dummy-Daten.
1
void
2
Spi2Init (void) {
3
4
  GPIO_InitTypeDef GPIO_InitStructure;
5
  SPI_InitTypeDef SPI_InitStructure;
6
  NVIC_InitTypeDef NVIC_InitStructure;
7
8
  // Disable SPI
9
  SPI_Cmd(SPI2, DISABLE);
10
11
    /* GPIOB Peripheral clock enable */
12
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
13
 
14
 /* SPI2 Peripheral clock enable */
15
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB2Periph_AFIO, ENABLE);
16
17
    /* Configure SPI2 pins: NSS, SCK, MISO and MOSI -------------------------------*/
18
    // SPI2: CS
19
    GPIO_InitStructure.GPIO_Pin             = GPIO_Pin_12;
20
  GPIO_InitStructure.GPIO_Speed           = GPIO_Speed_10MHz;
21
  GPIO_InitStructure.GPIO_Mode            = GPIO_Mode_Out_PP;
22
    GPIO_Init(GPIOB, &GPIO_InitStructure);
23
24
    // SPI2: SCK and MOSI push-pull
25
    GPIO_InitStructure.GPIO_Pin             = GPIO_Pin_13 | GPIO_Pin_15 | GPIO_Pin_14;
26
    GPIO_InitStructure.GPIO_Speed           = GPIO_Speed_50MHz;
27
    GPIO_InitStructure.GPIO_Mode            = GPIO_Mode_AF_PP;
28
    GPIO_Init(GPIOB, &GPIO_InitStructure);
29
30
    // SPI2: Configuration
31
    SPI_InitStructure.SPI_Direction     = SPI_Direction_2Lines_FullDuplex;
32
    SPI_InitStructure.SPI_Mode        = SPI_Mode_Master;
33
    SPI_InitStructure.SPI_DataSize       = SPI_DataSize_8b;
34
    SPI_InitStructure.SPI_CPOL         = SPI_CPOL_Low;
35
    SPI_InitStructure.SPI_CPHA         = SPI_CPHA_1Edge;
36
    SPI_InitStructure.SPI_NSS         = SPI_NSS_Soft;
37
    SPI_InitStructure.SPI_FirstBit       = SPI_FirstBit_MSB;
38
    SPI_InitStructure.SPI_CRCPolynomial   = 7;
39
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16; // ((72/2)/8)= 4.5MHz
40
    SPI_Init(SPI2, &SPI_InitStructure);
41
    SPI_Cmd(SPI2, ENABLE);
42
}


Die Einleseroutine:
1
uint8_t
2
SPI_ReadByte (void) {
3
4
  // send dummy byte (0xFF)
5
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
6
  SPI_I2S_SendData(SPI2, 0x00);
7
8
  // read data
9
  while(SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET);
10
  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
11
12
  return SPI_I2S_ReceiveData(SPI2);
13
}

von Lötlackl *. (pappnase) Benutzerseite


Lesenswert?

Konfiguriere MISO als Eingang!
1
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_14;
2
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
3
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4
  GPIO_Init(GPIOB, &GPIO_InitStructure);

mfg

von Arbeitnehmer (Gast)


Lesenswert?

Das hatte ich erst von vorne rein gehabt, bis ich es auf GPIO_Mode_AF_PP 
umgeändert habe, weil es in einem Beispiel von ST so beschrieben wurde. 
Wie auch immer, beide versionen gehen nicht. Ach ja, auf dem Evalboard 
hängt an der Leitung sonst nichts anderes und physikalisch ist der Pin 
auch verbunden.

von Uwe B. (derexponent)


Lesenswert?

schreib mal das noch dazu :
1
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_SPI2);
2
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource14, GPIO_AF_SPI2);
3
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource15, GPIO_AF_SPI2);

und ich glaube die Zeile :
1
while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);

kannst du dir sparen

Gruss Uwe

von Arbeitnehmer (Gast)


Lesenswert?

Das kennt meine stm lib nicht. Einsetzen tue ich gerade einen STMf103 in 
Verbindung mit der Lib V3.5.0.

Ich habe schon die SPI3 Routinen (die sicher liefen) vom alten Projekt 
übernommen und an SPI2 angepasst, immer noch nichts.... Mir sind die 
Ideen ausgegangen.

von Arbeitnehmer (Gast)


Lesenswert?

>und ich glaube die Zeile :
>while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
>kannst du dir sparen

Die brauche ich, sonst wird CS zu früh auf High gesetzt.

von Arbeitnehmer (Gast)


Lesenswert?

Also, ich bin den Umweg gegangen und habe die Empfangsfunktion auf 
Empfang in der SPI ISR umgestellt. Das Ergebnis ist das Selbe, im 
Eingangsregister landen irgendwie nur die Einsen. Ich wäre für jeden 
weiteren Rat sehr dankbar.

von Uwe B. (derexponent)


Lesenswert?

1
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2 | RCC_APB2Periph_AFIO, ENABLE);

was soll "RCC_APB2Periph_AFIO" innerhalb von "RCC_APB1PeriphClockCmd"
stimmt das so ?

sehe sonst keinen Fehler (vlt doch Hardware  :-)

Gruss Uwe

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.