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
voidsd_command_response()
2
{
3
Uint16i;
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
//If response is not 0x00, 0x01, or 0xFF branch to sd_error
18
elseif(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
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
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?
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...
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
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
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
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