Forum: Mikrocontroller und Digitale Elektronik SPI (Master) sendet falsche Daten


von stip (Gast)


Angehängte Dateien:

Lesenswert?

Liebes Forum,

ich programmiere einen STM32 und möchte über SPI mit einem Slave 
(ade7912) kommunizieren. Verwende hierfür auch die stm32_library!
Mein Problem ist, dass manchmal/meistens der Master falsche Bytes 
sendet. Es kommt nicht immer vor und daher fällt es mir so schwer den 
Fehler zu finden. Jenachdem, was ich in meinem Code ändere, versendet 
der Master manchmal die richtigen Bytes, aber meistens eben nicht. Und 
mit Code-Änderung meine ich nicht bei der SPI-Initialisierung, sondern 
einen Code-Teil, der nicht einmal etwas mit SPI zu tun hat.

Im unteren Teil findet ihr die Initialisierung der SPI und als Test habe 
ich eine While-Schleife erstellt, in welcher Bytes mit laufender Numer 
versendet werden sollen. Das heißt, die Bytes sollten folgende Werte 
beinhalten: 0x00, 0x01, 0x02,... usw.

Im Anhang findet ihr ein Bild, was tatsächlich versendet wird!
In diesem Bild also: 0xD7, 0xF9, 0xCF, 0xFA, 0xC7, ...

Und beim nächsten mal Starten (debuggen) sind wieder andere Werte 
vorhanden!!

Bitte um Hilfe! Bin für jeden Hinweis dankbar!

1
void Init_SPI1(void)
2
{
3
    // Enable peripheral clock
4
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
5
6
    SPI_I2S_DeInit(SPI1);
7
8
    SPI_InitTypeDef SPI_InitStructure;
9
10
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
11
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
12
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
13
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;         
14
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;        
15
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
16
    SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_8;  
17
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
18
19
    SPI_Init(SPI1,&SPI_InitStructure);
20
21
    SPI_Cmd(SPI1, ENABLE);
22
    
23
    int count = 0;
24
25
    while(1)
26
    {
27
        SPI_SendData8(SPI1,count);         
28
        while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
29
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == 1);
30
        count ++;
31
        if (count == 255)
32
        {
33
            count = 0;
34
        }
35
    }
36
}

von OMG (Gast)


Lesenswert?

stip schrieb:
> ich programmiere einen STM32

Welchen? Ach so, es gibt ja nur einen ....

von stip (Gast)


Lesenswert?

OMG schrieb:
> stip schrieb:
>> ich programmiere einen STM32
>
> Welchen? Ach so, es gibt ja nur einen ....


verwende den STM32F303

von Ahnungslos (Gast)


Lesenswert?

Wie bewegst du NSS?

von c-hater (Gast)


Lesenswert?

stip schrieb:

> Jenachdem, was ich in meinem Code ändere, versendet
> der Master manchmal die richtigen Bytes, aber meistens eben nicht. Und
> mit Code-Änderung meine ich nicht bei der SPI-Initialisierung, sondern
> einen Code-Teil, der nicht einmal etwas mit SPI zu tun hat.

Dann dürfte wohl einem durch Programmierfehler zerschossenen Heap oder 
Stack eine gewisse Wahrscheinlichkeit zukommen.

Was passiert, wenn du alle Warnungen des Compilers einschaltest und ihn 
alle Warnungen als Fehler behandeln läßt?

;o)

von stip (Gast)


Lesenswert?

Ahnungslos schrieb:
> Wie bewegst du NSS?

Ist im oberen geposteten Code-Teil nicht vorhanden, da ich es 
übersichtlich darstellen wollte.
Ich mache es folgendermaßen:
1
#define __SELECT_CS1        {GPIOA->BRR  = GPIO_Pin_1;}
2
#define __DESELECT_CS1      {GPIOA->BSRR = GPIO_Pin_1;

Meine while-Schleife sieht eigentlich so aus:
1
while(1)
2
    {
3
        __SELECT_CS1        
4
        SPI_SendData8(SPI1,count);         
5
        while (SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE)==RESET);
6
        while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == 1);
7
        __DESELECT_CS1      
8
        count ++;
9
        if (count == 255)
10
        {
11
            count = 0;
12
        }
13
    }



In der angehängten Datei im Bild heißt die NSS-Leitung: "I1_CS"


Aber unabhängig von der NSS-Leitung und unabhängig vom Slave, sollten 
vom Master zumindest die richtigen Bytes versendet werden....

Mein Verdacht war auch, dass wenn der SPI nicht richtig abgedreht wird, 
dass es beim wieder einschalten zu Fehlern kommt. Wenn also zum Beispiel 
während dem Senden die Verbindung abgedreht wird, weil ich mit dem 
Debuggen aufhöre, dass im TX-Buffer falsche/alte Werte vorliegen und 
diese dan beim nächsten Einschalten das Senden beeinflussen???

Bin um jeden Hinweis und um jede Idee dankbar!

von OMG (Gast)


Lesenswert?

stip schrieb:
> Verwende hierfür auch die stm32_library!

Welche bitte?

Die Funktion SPI_SendData8(..) finde ich nicht in Libraries,
ist das was Selbstgeschriebenes? Wenn ja, dann zeige sie bitte.

von stip (Gast)


Lesenswert?

OMG schrieb:
> stip schrieb:
>> Verwende hierfür auch die stm32_library!
>
> Welche bitte?
>
> Die Funktion SPI_SendData8(..) finde ich nicht in Libraries,
> ist das was Selbstgeschriebenes? Wenn ja, dann zeige sie bitte.


verwende folgende Library: STMF32F30x_StdPeriph_Driver


Hier ist auch die Funktion SPI_SendData8() dabei.
Hier ein Ausschnitt aus der Library:
1
/**
2
  * @brief  Transmits a Data through the SPIx peripheral.
3
  * @param  SPIx: where x can be 1, 2,  3 or 4 to select the SPI peripheral.
4
  * @param  Data: Data to be transmitted.
5
  * @retval None
6
  */
7
void SPI_SendData8(SPI_TypeDef* SPIx, uint8_t Data)
8
{
9
  uint32_t spixbase = 0x00;
10
11
  /* Check the parameters */
12
  assert_param(IS_SPI_ALL_PERIPH(SPIx));
13
14
  spixbase = (uint32_t)SPIx;
15
  spixbase += 0x0C;
16
17
  *(__IO uint8_t *) spixbase = Data;
18
}

Danke im Vorhinein für eure Hilfe!

von OMG (Gast)


Lesenswert?

Da wirst du wohl mal dein ganzes Programm zeigen müssen,
oder ein kleines daraus abgeleitetes welches den Fehler
reproduzierbar macht.

So wie es aussieht wirst du einen Programmierfehler haben
den du uns noch nicht gezeigt hast.

Denke beim Posten von Code daran:

-----------------------------------------------
Wichtige Regeln - erst lesen, dann posten!

............
Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang
-----------------------------------------------

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.