Forum: Mikrocontroller und Digitale Elektronik microSD mit SPI antwortet nicht


von zhinek20 (Gast)


Lesenswert?

Hallo alle zusammen,

das Thema wurde hier schon so oft behandelt, trotzdem konnte ich mein 
Problem mit keinen der Beträge, die hier schon gepostet wurden sind 
lösen.

Ich versuche eine 8GB microSDHC Karte von SanDisk mit dem TMSF28335 von 
TI über eine SPI Schnittstelle zu initialisieren, doch die Karte 
antwortet schon gar nicht auf das CMD0.
Um die microSD zu initialisieren bin ich größtenteil nach der Anleitung 
von "elm-chan.org" gegangen.
Andere microSD Karten habe ich auch schon ausprobiert, ohne Erfolg.

Meine Init Sequenz sieht folgendermaßen aus:

1) SD Detection + 80 Clock cycles + CS auf High
1
  CS_HIGH;  //Pull CS High
2
  while (GpioDataRegs.GPBDAT.bit.GPIO33 == 1){} // Warten bis µSD eingelegt ist
3
  for(i=0;i<10;i++)   //Transmit 0xFF for 80 clock cycles
4
  xmit_byte(DUMMY_DATA);

2) Initialisierung mit CMD0
1
     CS_LOW;                  //Pull CS low
2
//Transmit GO IDLE STATE command to card with CS low to select SPI mode 
3
//and put the card in IDLE mode.
4
     
5
     xmit_byte(0x40);
6
  xmit_byte(0x00);
7
  xmit_byte(0x00);
8
  xmit_byte(0x00);
9
  xmit_byte(0x00);
10
  xmit_byte(0x95);  
11
     EIGHT_CLOCK_CYCLE_DELAY; 
12
     
13
     RESET_RESPONSE;      //Reset response  
14
  while(response != IN_IDLE_STATE)  //Wait until card responds with IDLE response
15
    sd_command_response();
1
void sd_command_response()
2
{
3
  Uint16 i;
4
5
  RESET_RESPONSE;              //Reset Response
6
    
7
//This loop continously transmits 0xFF in order to receive response from card. 
8
//The card is expected to return 00 or 01 stating that it is in idle state or 
9
//it has finished it's initialization(SUCCESS). If anything is received besides
10
  //0x00, 0x01, or 0xFF then an error has occured. 
11
  for(i=0;i<8;i++)
12
  {
13
    response = xmit_byte(DUMMY_DATA);
14
    //If response is 0x00 or 0x01 break from loop    
15
    if ((response == IN_IDLE_STATE) || (response == SUCCESS))
16
      break;
17
    //If response is not 0x00, 0x01, or 0xFF branch to sd_error
18
    else if (response != DUMMY_DATA)
19
      sd_error();
20
  }
21
}

bei diesem 2. Schritt bekomm ich von den µSD Karten immer ein 0xFF als 
Antwort, was nicht sein kann.

Hat einer von euch schon mal so ein ähliches Problem gehabt und kann mir 
weiter helfen?? Falls noch mehr informationen benötigt werden bitte 
bescheid geben.

Ich habe meinen Code auch mit einer normalen SD Karte 128MB getestet, 
mit dieser hat alles ganz gut funktioniert.

Ich hoffe mir kann jemand helfen, Gruß zhinek20

von Christoph.b (Gast)


Lesenswert?

sind die 8GB vieleicht zu groß?

von zhinek20 (Gast)


Lesenswert?

Ich hab auch eine 2Gb µSD ausbrobiert, diese konnte auch nicht 
initialisieren. Bekomme als Antwort nur 0xFF auf das CMD0.

von Bernhard D. (pc1401)


Lesenswert?

Wie sieht die Beschaltung der Karte aus? Versorgung 3.3V, max. 60 mV 
Ripple?
Falls Pegelwandler erforderlich, KEINE Spannungsteiler verwenden.
Abblock-C vorhanden?

An den Eingängen der Karte erst Signale anlegen, wenn die Versorgung 
vorhanden ist. Habe hier SanDisk 2GB, die dann nicht mehr antworten. 
Pullup an DO nicht vergessen?

An diesen Punkten sollte man absolut nicht schludern, sonst ist 
jegliches Herumprogrammieren sinnlos.

Gruß,
Bernhard

von zhinek20 (Gast)


Lesenswert?

Hallo Bernhard,
Die Leitungen CS, DO, DI, CLK sind jeweils mit 100k Pullup Widerst. 
versehen, der Abblock-C ist 100nF.
Die Versorgungsspannung 3,3v ist auf dem Board auch vorhanden.

Wie ich schon oben erwähnt habe, wurde eine große sd Karte erfolgreich 
initialisiert.
Muss man bei den µSD´s noch was anders machen als bei den normalen SD 
Karten?

von Bernhard D. (pc1401)


Lesenswert?

Wie angedeutet, ich hatte auch das Problem, dass eine 2GB SD Karte von 
SanDisk nach Gabe von CMD0 nicht immer in IDLE gehen wollte.

In einem batteriebetriebenen Gerät wurde die Versorgung der Karte nach 
dem Zugriff wieder abgeschaltet. CS, DI und CLK blieben aber als 
Ausgänge aktiviert. Beim ersten Zugriff nach dem Einschalten war alles 
ok, beim nächsten Mal ging die Karte nach CMD0 nicht mehr in IDLE.

Die weiterhin aktiven Steuerausgänge am Controller waren bei mir das 
Problem. Als ich CS, DI und CLK in den Zeiten ohne Versorgung an der 
Karte hochohmig (als Eingänge) schaltete, ging es...

Generell sollte man bei jeglicher Digitaltechnik erst die Versorgung, 
dann die Signale anlegen. Vermutlich zwingt dies die Statemachine der 
SanDisk 2GB-Karten sonst in einen undefinierten Zustand, aus dem es kein 
Zurück gibt.

Verschiedene andere Karten wiederum (SanDisk 1GB, Platinum 1GB) machen 
in diese Hinsicht keine Schwierigkeiten. Sind dann vielleicht wieder 
empfindlicher bei Ripple auf der Versorgung oder der Verwendung von 
Spannungsteiler-Pegelwandlern...

von zhinek20 (Gast)


Lesenswert?

Hallo Bernhard,
esrt mal danke dir für deine Mühe mir zu helfen.
Hab jetzt mal den Vorschlag von dir ausprobiert und alle Ports als 
Eingang geschaltet. Erst wenn die Karte eingesteckt, detektiert und ein 
timer von 2ms abgelaufen ist schalte ich alle Ports auf die gewünschten 
Funktionen um und versuche die Karte zu initialisieren. Leider regt sich 
immer noch nichts am Ausgang der µSD und mein µC ließt nur 0xFF.

Hab mir heute noch eine 1GB µSD besorgt, auch die will nicht 
Kommunizieren.
Die große SD Karte mit 128mb läuft ganz gut.

Hat vllt. sonst noch jemand Vorschläge?
Gruß zhinek20

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

Hast du schon mit dem Oszi die CLK Frequenz gemessen, die sollte <400kHz 
sein. Funktioniert das CS Signal? Sind an allen Funktionspins pull-up 
Widerstände?

Grüsse

von Bernhard D. (pc1401)


Lesenswert?

Hallo "zhinek20",

ich denke auch, Du solltest mal ein Oszilloskop bemühen, bzw. den 
Datenstrom an der SPI Schnittstelle analysieren.

Die Initialisierungssequenz der SD-Karten ist ja nicht so kompliziert, 
und wenn diese mit mehreren Karten nicht funktioniert, muss in Aufbau 
oder / und Programmierung ein Fehler vorliegen. Benutzt Du eine 
industriell gefertigte Leiterplatte, oder was selber geätztes?

Bei letzterem übersieht man gerne mal was, Kurzschlüsse, mikroskopisch 
kleine Zinnspritzer, bei den microSDs hat sich da schnell was 
eingeschlichen.

Zur Programmierung:

Die Originalspezifikation
https://www.sdcard.org/downloads/pls/simplified_specs/Part_1_Physical_Layer_Simplified_Specification_Ver_3.01_Final_100518.pdf

bzw. auch Chans Info-Seite http://elm-chan.org/docs/mmc/mmc_e.html 
kennst Du?

Gruss,
Bernhard

von Detlev T. (detlevt)


Lesenswert?

Der Standard schreibt übrigens NICHT vor, dass eine µSD-Karte SPI können 
muss. (bei SD-Karten ist das anders)

von Gebhard R. (Firma: Raich Gerätebau & Entwicklung) (geb)


Lesenswert?

@Detlev
Das mag sein, aber auch im 4 Bit Modus wird die Karte mit 1 Datenleitung 
initialisiert.

Grüsse

von zhinek20 (Gast)


Lesenswert?

Hallo Leute,

habe heute mal weiter mit der microSD experementiert und es endlich 
hinbekommen, dass die Karte zumindest auf das CMD0 erfolgreich 
antwortet.

Die Lösung für das Problem war ein Timing Problem. Der Fehler lag im 
Schritt 2(1. Beitrag). Dort wird zuerst die CS Leitung auf 0 gesetzt und 
unmittelbar danach wird das CMD0 versendet. Heute habe ich den Code 
minimal verändert:
1
    CS_LOW;                  //Pull CS low
2
    xmit_byte(DUMMY_BYTE);   //Sende 0xFF Byte bevor CMD0 gesendet wird
3
4
//Transmit GO IDLE STATE command to card with CS low to select SPI mode 
5
//and put the card in IDLE mode.
6
     
7
    xmit_byte(0x40);
8
    xmit_byte(0x00);
9
    xmit_byte(0x00);
10
    xmit_byte(0x00);
11
    xmit_byte(0x00);
12
    xmit_byte(0x95);  
13
    EIGHT_CLOCK_CYCLE_DELAY; 
14
     
15
     RESET_RESPONSE;      //Reset response  
16
  while(response != IN_IDLE_STATE)  //Wait until card responds with IDLE response
17
    sd_command_response();

Nach dem die CS Leitung gezogen wird, sende ich erstmal ein Dummy Byte 
erst danach das CMD0. So klappt es.

Ich danke euch für eure Hilfe.

Gruß zhinek20

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.