Forum: Mikrocontroller und Digitale Elektronik SPI mit SD Karte antwortet nicht korrekt auf CMD0


von C. H. (hedie)


Lesenswert?

Hallo

Ich experimentiere seit einigen Tagen mit meinem ETT STM32 Cortex M3 
Board welches ich bei ebay ersteigert habe...

Nun wollte ich einmal eine SD Karte mit meinem STM32F103RB connecten. 
Ich habe schon ettliche seiten im Netz durchsucht und bin dabei auf 
einige interessante implementierungen des FAT16 Standards gestossen.

Leider fand ich jedoch kein ausreichendes beispiel für die ansteuerung 
mit einem STM32F103.

Ich hab nun versucht den code von Ulrich Radig zu übernehmen. Es gelang 
den Code zu compilieren jedoch antwortet meine Karte nicht wie sie 
sollte.

Ich habe danach versucht für testzwecke nur mal das 0x01 zu erhalten 
welches die karte nach einem CMD0 senden sollte.

Dazu verwende ich folgenden Code:
1
//////Port initialisierung
2
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
3
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
4
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
5
  GPIO_Init(GPIOA, &GPIO_InitStructure);
6
7
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //Maximaler Speed 50MHz aktivieren
8
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //Pins als PushPull konfigurieren
9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;             //Konfiguration für PIN8 übernehmen
10
  GPIO_Init(GPIOA, &GPIO_InitStructure);                  //Konfiguration für GPIOB übernehmen
11
12
//////SPI Initialisierung
13
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
14
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
15
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
16
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
17
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
18
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
19
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
20
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
21
  SPI_InitStructure.SPI_CRCPolynomial = 7;
22
  SPI_Init(SPI1, &SPI_InitStructure);
23
  SPI_Cmd(SPI1, ENABLE);
24
25
while(1)                          
26
  {
27
    //set MMC_Chip_Select to High (MMC/SD-Karte Inaktiv)
28
    GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_SET);
29
    //sendet 8 Clock Impulse
30
    Write_Byte_MMC(0xFF);
31
    //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
32
    GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_RESET);
33
34
    Write_Byte_MMC(0x40);
35
    Write_Byte_MMC(0x00);
36
    Write_Byte_MMC(0x00);
37
    Write_Byte_MMC(0x00);
38
    Write_Byte_MMC(0x00);
39
    Write_Byte_MMC(0x95);
40
    while(ucTemp != 0x01)
41
    {
42
      Write_Byte_MMC(0xFF);  //Erzeugen von clocks
43
      ucTemp = Read_Byte_MMC();  //Daten auf dem Pin Lesen
44
    }
45
    Write_Byte_MMC(0xFF); //nur benötigt um einen breakpoint zu setzen 
46
  }

Funktion:
1
//############################################################################
2
//Routine zum Senden eines Bytes zur MMC-Karte
3
inline void Write_Byte_MMC (unsigned char Byte)
4
//############################################################################
5
{    
6
    SPI_I2S_SendData(SPI1,Byte);
7
    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);
8
}
9
10
//############################################################################
11
//Routine zum Empfangen eines Bytes von der MMC-Karte 
12
inline unsigned char Read_Byte_MMC (void)
13
//############################################################################
14
{
15
  unsigned char Byte = 0;
16
  Byte = 0xFF;
17
        Byte = SPI_I2S_ReceiveData(SPI1);
18
        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == SET);  
19
  return (Byte);
20
}

Ich habe einen Logicanalyzer sowie ein DSO für messungen zur verfügung.
Ich habe mit dem Logicanalyzer analysiert und gesendet wird korrekt.

Das problem besteht jedoch beim empfangen der daten.
Ich empfange jedoch nur "müll" die krate sendet zwar nach dem 0x40 ... 
0x95 etwas zurück (sieht man auf dem analyzer) jedoch nicht 0x01 und 
mein code meldet immer 0xFF

Ich hoffe es kann mir hier jemand nen Tipp geben.

Danke schonmal

von C. H. (hedie)


Lesenswert?

Problem gelöst.... :)

ich hab falsch auf die antwort gewartet
1
//############################################################################
2
//Routine zum Empfangen eines Bytes von der MMC-Karte 
3
inline unsigned char Read_Byte_MMC (void)
4
//############################################################################
5
{
6
  unsigned char Byte = 0;
7
  Byte = 0xFF;
8
  Write_Byte_MMC(0xFF); //Clocks erzeugen nicht vergessen :) :) :)
9
        Byte = SPI_I2S_ReceiveData(SPI1);
10
        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);  //RESER STAT SET!!!!!!!!!!!!!!!
11
  return (Byte);
12
}

Trozdem Danke!!

von R. W. (quakeman)


Lesenswert?

Wenn ich das richtig sehe, dann setzt du die SPI Geschwindigkeit mit
1
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz
gleich zu Beginn auf eine sehr hohe Geschwindigkeit. Die Spezifikation 
für SD-Karten sieht aber vor, daß während der Initialisierungsphase der 
Takt zwischen 100kHz und 400kHz betragen sollte. Erst nach der 
Initialisierung darf der Takt auf die maximal erlaubte Taktrate erhöht 
werden. Es kann also sein, daß deine Initialisierung nicht bei jeder 
SD-Karte funktionieren wird.

Ciao,
     Rainer

von C. H. (hedie)


Lesenswert?

Hallo Rainer

Danke für deinen Tipp :)
1
GPIO_Speed_50MHz

bedeutet lediglich das der APB2 Bus an dem die GPIO's hängen die Pins 
mit 50MHz Clock Speed versorgt. Ob die nun auch mit 50MHz schalten hängt 
vom rest des Programms ab...

Die eigentliche geschwindigkeit wird mit
1
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;

Eingestellt. Dort wird der PCLK dur den Prescaler geteilt.
Dies ergibt bei mir etwa 300KHz

Doch leider habe ich nun das problem das Ulrich Radigs Software meine 
Dateien nicht anzeigen kann.... 
Beitrag "SD Karte mit Ulrich Radigs Software zeigt keine Dateien"

von bubi.. (Gast)


Lesenswert?

Hallo,

Dürfte ich mal deinen kompletten Code sehen?
Ich sitz gerade selbst davor und mir gibt die Karte auch nichts zurück 
:(
Der Code schaut soweit aber ident aus...
ausser
1
//############################################################################
2
//Routine zum Empfangen eines Bytes von der MMC-Karte 
3
inline unsigned char Read_Byte_MMC (void)
4
//############################################################################
5
{
6
  unsigned char Byte = 0;
7
  Byte = 0xFF;
8
  Write_Byte_MMC(0xFF); //Clocks erzeugen nicht vergessen :) :) :)
9
        Byte = SPI_I2S_ReceiveData(SPI1);
10
        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);  //RESER STAT SET!!!!!!!!!!!!!!!
11
  return (Byte);
12
}
Ich frage zuerst das Flag ab und dann lese ich erst aus ;) Macht in 
meinen Augen auch mehr Sinn :)
Vorallem der komplette INIT Code vor dem CMD0 würde mich interresieren 
:)

von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

Ja da hast du recht... ergibt eigentlich mehr sinn zuerst warten und 
dann auslesen...

aber natüürlich darfst du den sehen :)

Hab ihn angehängt...

Init mmc funktioniert soweit problemlos

von bubi.. (Gast)


Lesenswert?

Vielen Dank :)

Aber leidergottes ist er ident g
hmmm mal schaun was das sein kann.. hast du irgendeine besondere 
Hardwarebeschaltung? Pullup an MISO nehm ich mal an?

von C. H. (hedie)


Angehängte Dateien:

Lesenswert?

Mein Hardware aufbau ist im PDF im anhang auf Seite 14 beschrieben :)

von bubi... (Gast)


Angehängte Dateien:

Lesenswert?

Hmm...irgendwie ist das komisch..
Ich hab mal mein Projekt angehängt samt Crossworks-Projektdatei...
Vl kann mal wer meine Routinen checken. Code ist eigentlich 
selbsterklärend.

Peripherial Lib mit System Init ist für #define SYSCLK_FREQ_72MHz 
72000000  konfiguriert...

von Steffen (Gast)


Lesenswert?

@hedie
ich habe das gleiche Board gekauft wie du, könntest du wohl die sourcen 
hier veröffentlichen?

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.