STM32F103 SPI gibt nur 0 zurück

OP #3837955
Lesenswert?

Hallo
Ich habe wieder mal ein kleines Problem, dass sich einfach nicht lösen 
lassen will:

Es geht um den SPI im STM32f103. TX funktioniert (Oszi) aber RX kommt 
nur 0 zurück. Elektrischer Fehler ist eigentlich ausgeschlossen: wenn 
ich MISO fest auf VCC hänge zeigt GPIOA->IDR zwar eine 1, aber Send() 
gibt 0 zurück!
Code ist nur das hier:
1
GPIO_InitTypeDef GPIO_InitStructure;
2
    SPI_InitTypeDef SPI_InitStructure;
3
    
4

5
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
6

7
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
8
    
9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           
11
    GPIO_Init(GPIOA, &GPIO_InitStructure);
12

13
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
14
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
15
    GPIO_Init(GPIOA, &GPIO_InitStructure);
16

17
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
18

19
    SPI_I2S_DeInit(SPI1);
20

21
    SPI_StructInit(&SPI_InitStructure);
22
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
23
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
24
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
25
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
26
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
27
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
28
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
29
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
30
    SPI_InitStructure.SPI_CRCPolynomial = 7;
31
    SPI_Init(SPI1, &SPI_InitStructure);
32

33
    SPI_Cmd(SPI1, ENABLE);
34

35
    while(1)
36
    {
37
        uint8_t x = Send(SPI1, 123);
38
    }
und die Funktion Send():
1
uint8_t Send(SPI_TypeDef* SPIx, uint8_t data){
2

3
  SPIx->DR = data; // write data to be transmitted to the SPI data register
4
  while( !(SPIx->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
5
  while( !(SPIx->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
6
  while( SPIx->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
7
  return SPIx->DR; // return received data from SPI data register
8
}
Weiss da jemand rat? SPI Slave funktioniert Perfekt (sogar mit DMA), nur 
Master RX zickt...
Vielen Dank, Sean
Gast #3838073
Lesenswert?

Das ist Wasser auf meine Mühlen. Ich hatte genau das gleiche mit einem 
32F3xx. Ich hab irgendwann nach jedem Strohhalm gegriffen und 
angefangen, am Prescaler zu drehen. Bei einer einzigen Einstellung 
klappts. Einen drunter oder drüber ist das Ding tot...
Ich habs nicht weiter verfolgt, weil reines Hobby und keine Zeit.

Versuch mal "SPI_InitStructure.SPI_BaudRatePrescaler = 12;"
Gast #3838083
Lesenswert?

Nimm mal RCC_APB2Periph_AFIO mit rein und schalte die Clocks auf
BEVOR du irgendwas initialisierst.

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, 
ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 .....
OP #3838090
Lesenswert?

1
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
2
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
3
    
4

5
    GPIO_InitTypeDef GPIO_InitStructure;
6
    SPI_InitTypeDef SPI_InitStructure;
7
    
8

9

10
    
11

12
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
13
    
14
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
15
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;           
16
    GPIO_Init(GPIOA, &GPIO_InitStructure);
17

18
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
19
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
20
    GPIO_Init(GPIOA, &GPIO_InitStructure);
21

22

23

24
    SPI_I2S_DeInit(SPI1);
25

26
    SPI_StructInit(&SPI_InitStructure);
27
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
28
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
29
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
30
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
31
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
32
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
33
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
34
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
35
    SPI_InitStructure.SPI_CRCPolynomial = 7;
36
    SPI_Init(SPI1, &SPI_InitStructure);
37

38
    SPI_Cmd(SPI1, ENABLE);
39

40
    while(1)
41
    {
42
        uint8_t x = Send(SPI1, 123);
43
        delay = x / 2;  //dummy aktion, nur zur sicherheit!
44
    }
So siehts jetzt aus, hat sich aber nichts geändert. Das mit Prescaler = 
12 habe ich auch getestet, gleiches Ergebnis. Trotzdem danke :)
Gast #3838106
Lesenswert?

>So siehts jetzt aus, hat sich aber nichts geändert.

Ich werde das Gefühl immer noch nicht los das das
nur ein Missverständnis zwischen dir und deinem Debugger ist.

Gib x über UART aus. Da MOSI ja was sendet sollte
das SPI Modul funktionieren. SCK funktioniert auch?
OP #3838121
Lesenswert?

Marc Vesely schrieb:
> Sean Goff schrieb:
>
1
>  while( !(SPIx->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit 
2
> complete
3
>  while( !(SPIx->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive 
4
> complete
5
>
>
>  Bist du sicher, dass receive complete nötig ist ?
>  SPI ist eigentlich bidirectional, es könnte sein, dass du damit nur
>  sein (leeres) SPI-Register empfängst...

Dachte ich auch schon, aber in allen Libs wird's so gemacht, und ohne 
ändert sich nichts!

holger schrieb:
>>So siehts jetzt aus, hat sich aber nichts geändert.
>
> Ich werde das Gefühl immer noch nicht los das das
> nur ein Missverständnis zwischen dir und deinem Debugger ist.
>
> Gib x über UART aus. Da MOSI ja was sendet sollte
> das SPI Modul funktionieren. SCK funktioniert auch?

SCK und MOSI funktionieren. Ich kanns mir einfach nicht vorstellen, ich 
habe EXAKT die gleiche Methode beim F4 angewendet. Funktioniert super 
(mit dem Debugger...)
UART müsste ich halt auch zuerst implementieren.

Ich hab aber jetzt mal folgendes gemacht:
1
    WS2812_init();
2
    while(1)
3
    {
4
        uint8_t x = Send(SPI1, 123);
5
        if(x == 0)
6
        {
7
            led[0].r = 3;
8
            led[0].g = 0;
9
            led[0].b = 0;
10
        }
11
        else
12
        {
13
            led[0].r = 3;
14
            led[0].g = 3;
15
            led[0].b = 3;
16
        }
17
        WS2812_update();
18
    }

-leuchtet Rot, nix Weiss!
OP #3838135
Lesenswert?

holger schrieb:
>>SCK und MOSI funktionieren.
>
> Bist du sicher das du MISO am richtigen Pin vermutest?
> Vieleicht verzählt beim anschliessen?
> Irgend sowas banales wird das sein;)

Sieht leider für mich nicht so aus, denn erstens ist das ne Platine, die 
garantiert korrekt ist und zweitens wenn ich den Pin auf VCC Brücke sehe 
ich ihn im GPIOA->IDR auf eins gehen (Debugger). Drittens habe ich ihn 
auch schon als Ausgang konfiguriert und zappeln lassen -> Oszi sagt es 
ist der richtige :(
OP #3838154
Lesenswert?

holger schrieb:
> Letzter Versuch:
>
> Schalte MISO mal auf GPIO_Mode_IPU und lass ihn offen.

Hat nichts gebracht :(

Marc Vesely schrieb:
> Sean Goff schrieb:
>> Dachte ich auch schon, aber in allen Libs wird's so gemacht, und ohne
>> ändert sich nichts!
>  Probier es mal ganz ohne Flags, etwa so:  SPIx->DR = data;
>   while (!(SPIx->SR & RXNE));  // 0x01
>   return (SPIx->DR);

Das akzeptiert der Compiler so nicht (er sagt RXNE sei nicht bekannt.) 
Wenn ich direkt 0x01 nehme, ändert sich am Ergebnis nichts (leuchtet 
rot.)

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