mikrocontroller.net

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


Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht 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:
//////Port initialisierung
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;       //Maximaler Speed 50MHz aktivieren
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        //Pins als PushPull konfigurieren
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;             //Konfiguration für PIN8 übernehmen
  GPIO_Init(GPIOA, &GPIO_InitStructure);                  //Konfiguration für GPIOB übernehmen

//////SPI Initialisierung
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
  SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;
  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  SPI_InitStructure.SPI_CRCPolynomial = 7;
  SPI_Init(SPI1, &SPI_InitStructure);
  SPI_Cmd(SPI1, ENABLE);

while(1)                          
  {
    //set MMC_Chip_Select to High (MMC/SD-Karte Inaktiv)
    GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_SET);
    //sendet 8 Clock Impulse
    Write_Byte_MMC(0xFF);
    //set MMC_Chip_Select to low (MMC/SD-Karte Aktiv)
    GPIO_WriteBit(GPIOA,GPIO_Pin_4,Bit_RESET);

    Write_Byte_MMC(0x40);
    Write_Byte_MMC(0x00);
    Write_Byte_MMC(0x00);
    Write_Byte_MMC(0x00);
    Write_Byte_MMC(0x00);
    Write_Byte_MMC(0x95);
    while(ucTemp != 0x01)
    {
      Write_Byte_MMC(0xFF);  //Erzeugen von clocks
      ucTemp = Read_Byte_MMC();  //Daten auf dem Pin Lesen
    }
    Write_Byte_MMC(0xFF); //nur benötigt um einen breakpoint zu setzen 
  }  

Funktion:
//############################################################################
//Routine zum Senden eines Bytes zur MMC-Karte
inline void Write_Byte_MMC (unsigned char Byte)
//############################################################################
{    
    SPI_I2S_SendData(SPI1,Byte);
    while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_TXE) == RESET);
}

//############################################################################
//Routine zum Empfangen eines Bytes von der MMC-Karte 
inline unsigned char Read_Byte_MMC (void)
//############################################################################
{
  unsigned char Byte = 0;
  Byte = 0xFF;
        Byte = SPI_I2S_ReceiveData(SPI1);
        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == SET);  
  return (Byte);
}

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

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Problem gelöst.... :)

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



Trozdem Danke!!

Autor: R. W. (quakeman)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn ich das richtig sehe, dann setzt du die SPI Geschwindigkeit mit
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

Autor: Claudio H. (hedie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Rainer

Danke für deinen Tipp :)
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
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"

Autor: bubi.. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
//############################################################################
//Routine zum Empfangen eines Bytes von der MMC-Karte 
inline unsigned char Read_Byte_MMC (void)
//############################################################################
{
  unsigned char Byte = 0;
  Byte = 0xFF;
  Write_Byte_MMC(0xFF); //Clocks erzeugen nicht vergessen :) :) :)
        Byte = SPI_I2S_ReceiveData(SPI1);
        while(SPI_I2S_GetFlagStatus(SPI1,SPI_I2S_FLAG_RXNE) == RESET);  //RESER STAT SET!!!!!!!!!!!!!!!
  return (Byte);
}
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 
:)

Autor: Claudio H. (hedie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: bubi.. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Claudio H. (hedie)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Mein Hardware aufbau ist im PDF im anhang auf Seite 14 beschrieben :)

Autor: bubi... (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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...

Autor: Steffen (Gast)
Datum:

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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.