STM32 SPI empfängt immer 0

Gast #5678402
Lesenswert?

Ich bin seit mehreren Tagen daran, über einen STM32L151 (Master) mit 
einem Funkmodul (Slave) per SPI zu kommunizieren. Mit einem Oszi konnte 
ich bereits sicherstellen, dass die Kommunikation standardgemäß abläuft. 
CS, CLK, MOSI und MISO werden von dem STM32 und der Gegenstelle 
(scheinbar) korrekt angesteuert.

Das einzige Problem ist, dass ich beim Empfangen ausschließlich 0 
erhalte, obwohl das Funkmodul die richtigen Datenbits auf MISO gibt. Ich 
habe den Chip bereits erfolglos ausgetauscht.

Hier ist die Initialisierungsroutine:
1
//Pin-Config: PA15 = Chip Select, PA12 = MOSI, PA11 = MISO, PA5 = SCK
2
GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_SPI1); // SCK
3
GPIO_PinAFConfig(GPIOA, GPIO_PinSource12, GPIO_AF_SPI1); // MOSI
4
GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_SPI1); // MISO
5

6
// SCK & MOSI
7
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_12;
8
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
9
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
10
GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_DOWN;
11
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
12
GPIO_Init(GPIOA, &GPIO_InitStructure);
13

14
// MISO
15
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
16
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
17
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
18
GPIO_Init(GPIOA, &GPIO_InitStructure);
19

20
// NSS
21
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
22
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
23
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;
24
GPIO_Init(GPIOA, &GPIO_InitStructure);
25

26
GPIO_WriteBit(GPIOA, GPIO_Pin_15, SET);
27

28
// Configure SPI
29
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
30
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
31
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
32
SPI_InitStructure.SPI_CRCPolynomial = 0;
33
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
34
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
35
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
36
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
37
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
38

39
SPI_Init(SPI1, &SPI_InitStructure);
40
SPI_Cmd(SPI1, ENABLE);

Und hier ist die Empfangsroutine:
1
uint8_t recvSPI(uint8_t address) {
2
  GPIO_WriteBit(GPIOA, GPIO_Pin_15, RESET);                // NSS off
3

4
  while (!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));  // Wait while TX buffer is full
5
  SPI1->DR = address;                                      // Send register address
6
  while (!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); // Wait while RX buffer is empty
7
  SPI1->DR;                                                // Read dummy byte
8

9
  while (!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));  // Wait while TX buffer is full
10
  SPI1->DR = 0x00;                                         // Send dummy byte
11
  while (!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE)); // Wait while RX buffer is empty
12
  uint8_t recv = SPI1->DR;                                 // Receive byte (Hier ist immer recv = 0)
13

14
  while (!SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE));  // Wait while TX buffer is full
15
  while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY));   // Wait while busy
16

17
  for(int i = 0; i < 20; i++);                             // Delay before NSS
18
  GPIO_WriteBit(GPIOA, GPIO_Pin_15, SET);                  // NSS on
19

20
  return recv;
21
}
#5678408
Lesenswert?

SPI sendet und empfängt gleichzeitig. Ohne dem code für Ablauf, ist es 
schwer raus zufinden, was du machst (Stichwort minimalcode).

Aber wenn du das DR beschreibst und liest, dann ist es null. Les das DR 
mal vorher aus und du solltest nach dem Beschreiben des DR registers 
auch den SPI Transfer starten, sonst ist da nix drinnen.

  SPI1->DR = 0x00;
  uint8_t recv = SPI1->DR;
Gast #5678422
Lesenswert?

Danke für die Tipps. So wie ich das verstanden habe, wird durch das 
Schreiben in das DR Register bereits das Senden gestartet, siehe 
Refrence Manual:

>– The sequence begins when data are written into the SPI_DR register (Tx buffer).
>– The data are then parallel loaded from the Tx buffer into the 8-bit shift 
register
>during the first bit transmission and then shifted out serially to the MOSI pin.
>– At the same time, the received data on the MISO pin is shifted in serially to 
the 8-
>bit shift register and then parallel loaded into the SPI_DR register (Rx buffer).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren