Probleme mit STM32F103 und SPI1 remapping

OP #7731348
Lesenswert?

Hallo allerseits, ich habe mich mal nach längerer Pause wieder an die STM's rangewagt und habe mir ein kleines Board zum Spielen designed und gebaut.

Dabei handelt es sich um ein Board mit dem STM32F103, der auch auf dem BluePill-Board verbaut ist. Ich habe am SPI1 ein kleines ILI9341 Display laufen, aber nicht an den default Pins für SPI1 (PA5-PA7) sondern an den alternativen Pins für den SPI1 (PB3-PB5). Dafür muss der SPI1 anders gemappt werden, sowie der JTAG deaktiviert werden, um diese Pins dafür nutzen zu können. Zudem soll es noch ein Errata geben, was besagt, dass bei gemapptem SPI1 der Clock vom I2C1 nicht aktiviert sein darf. Ich habe jetzt schon Stunden rumprobiert, aber ich krieg den SPI1 einfach ums verrecken nicht zum laufen. In der Init hängt er sich zwar nicht auf, aber dann in der while()-Schleife in spi_send(). Zudem hab ich mal mit dem LogicAnalyzer geguckt, was da so lost ist. Auf PB3-PB5 absolut GAR nix. Der SPI ist komplett tot. Vielleicht hat ja jemand das schonmal gemacht und könnte mir weiterhelfen. Hier mal der Code dazu:

1
//Pseudo-Functions
2
#define CS_low()      GPIOC->ODR &= ~(1<<14);
3
#define CS_high()      GPIOC->ODR |= (1<<14);
4

5

6
void spi_init(void)//set spi speed and settings 
7
{
8
  SPI_InitTypeDef SPI_InitStruct;
9
  GPIO_InitTypeDef GPIO_InitStruct;
10

11
  RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
12
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE); //Errata -> Don't use Remapped SPI1 with activated I2C1-Clock
13

14
  // GPIO pins for MISO, MOSI and SCK
15
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_4 | GPIO_Pin_3;
16
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
17
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
18
  GPIO_Init(GPIOB, &GPIO_InitStruct);
19

20
  //GPIO PortC 14 ->CS
21
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
22
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
23
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
24
  GPIO_Init(GPIOC, &GPIO_InitStruct);
25

26
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
27
  GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);
28

29
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
30
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
31
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
32
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
33
  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;
34
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
35
  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
36
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
37
  SPI_Init(SPI1, &SPI_InitStruct); 
38
  SPI_Cmd(SPI1, ENABLE);
39

40
  CS_high();
41
}
42

43
void spi_send(uint8_t spi_data)//send spi data to display
44
{
45
  SPI1->DR = spi_data;                // Write data to be transmitted to the SPI data register
46
  while (!(SPI1->SR & (SPI_I2S_FLAG_TXE)));      // Wait until transmit complete
47
  while (SPI1->SR & (SPI_I2S_FLAG_BSY));        // Wait until SPI is not busy anymore
48
}
49

50
uint8_t spi_read(void)
51
{
52
  SPI1->DR = 0x00;                // Write data to be transmitted to the SPI data register
53
  while (!(SPI1->SR & (SPI_I2S_FLAG_TXE)));      // Wait until transmit complete
54
  while (SPI1->SR & (SPI_I2S_FLAG_BSY));        // Wait until SPI is not busy anymore
55
  while (!(SPI1->SR & (SPI_I2S_FLAG_RXNE)));      // Wait until receive complete
56
  return SPI1->DR;                  // Return received data from SPI data register
57
}

Viele Grüße

Henning

#7731367
Lesenswert?

Henning S. schrieb:

Vielleicht hat ja jemand das schonmal gemacht und könnte mir weiterhelfen.

Ich hab mal schnell CubeMX angeworfen und den Code für deine Konfiguration generieren lassen. Dabei fällt auf dass MISO als Input deklariert wird, also keine alternate Function hat.

Vielleicht kannst du dir aus den restlichen Zeilen einen Reim machen ob bei dir alles stimmig ist. Siehe Anhang.

Angehängte Dateien:
OP #7731391
Lesenswert?

Moin Wastl, danke schonmal für deine Hilfe. Ich hab es jetzt mal genauso gemacht und hab den Miso als Floating Input. Zudem hab ich noch die Interrupt-Config aus dem CubeMX Code übernommen. Beides bringt aber leider keine Änderung.

1
void spi_init(void)//set spi speed and settings 
2
{
3
  SPI_InitTypeDef SPI_InitStruct;
4
  GPIO_InitTypeDef GPIO_InitStruct;
5

6
  RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
7
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE); //Errata -> Don't use Remapped SPI1 with activated I2C1-Clock
8

9
  // GPIO pins for MOSI and SCK
10
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_5;
11
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
12
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
13
  GPIO_Init(GPIOB, &GPIO_InitStruct);
14

15
  // GPIO pins for MISO
16
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
17
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
18
  GPIO_Init(GPIOB, &GPIO_InitStruct);
19

20
  //GPIO PortC 14 ->CS
21
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_14;
22
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
23
  GPIO_Init(GPIOC, &GPIO_InitStruct);
24

25
  //Remapping SPI1 to PB3-5 & Disable JTAG
26
  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
27
  GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE);
28

29
  NVIC_SetPriority(SPI1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),0, 0));
30
  NVIC_EnableIRQ(SPI1_IRQn);
31

32
  SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
33
  SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;
34
  SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;
35
  SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b;
36
  SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//SPI_Direction_1Line_Tx;
37
  SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB;
38
  SPI_InitStruct.SPI_Mode = SPI_Mode_Master;
39
  SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
40
  SPI_Init(SPI1, &SPI_InitStruct); 
41
  SPI_Cmd(SPI1, ENABLE);
42

43
  CS_high();
44
}

Grüße

OP #7731404
Lesenswert?

Wastl schrieb:

Henning S. schrieb:

Beides bringt aber leider keine Änderung.

Ist diese Zeile

1
>   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
2
>

gleichlautend zu deiner Initialisierung?

Ich würde die Clock-Initialisierung immer separat für jedes Peripherie-Element aufrufen, es ist mir sonst zu unübersichtlich ...

Hallo Wastl, DANKE! Das war entscheidende Hinweis auf den Tippfehler, den ich drin hatte. Da hast du mich auf die richtige Spur gebracht

Falsch:

1
  RCC_APB1PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE); //Errata -> Don't use Remapped SPI1 with activated I2C1-Clock

Richtig

1
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1 | RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
2
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, DISABLE); //Errata -> Don't use Remapped SPI1 with activated I2C1-Clock

Jetzt kann ich endlich schlafen gehen :-D

Viele Grüße

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