Forum: Mikrocontroller und Digitale Elektronik SD-Karten Initalisierung - ACMD41 gibt nur 0x01 zurück


von Moritz G. (moritz-)


Lesenswert?

HallO!°
Ich probiere nun schon einige Tage lang eine SD-Karte zu initalisieren 
(keine SDHC). (ATmega8, Assembler, 8Mhz, SPI, 1GB SD-Karte, 3,3V über 
Spannungsteiler)

Ich sende nach dem "Initalisation delay" und den >74Clock-Impulsen das 
CMD0 mit SS auf High, bekomme dann ganz richtig 0x01 zurück. Das heisst 
ja schon mal dass mit der SPI-Schnitstelle und der Karte alles in Ordung 
sein muss, wenn sie Antwortet.

Jetzt sende ich (nachdem SS kurz auf high gezogen wurde, un dann wieder 
low ist) das CMD55, bekomme ein 0x01 zurück

Jetzt mache ich SS wieder kurz high und dann low.

Jetz sende ich das ACMD41 (argument ist 0)
Dann lese ich die Response so:
1
  lesen:
2
    ldi  temp1,  0xFF
3
    rcall  sende              
4
    in   temp1,  SPDR
5
6
    cpi temp1, 0xFF      
7
  breq lesen
8
9
    cpi temp1, 0x00
10
  breq fertig_initalisiert
11
12
    cpi temp1, 0x01
13
  breq CMD55                  ;CMD55 kommt ja vor ACMD41
14
15
;sonst fehler:
16
rcall lcd_number_hex

Das programm bleibt hängen, ich bekomme also immer nur 0x01 (für 
IN_IDLE_STATE). Warum initalisiert die Karte nicht?
Normalerweise müsste nach einigen Durchläufen die Antwort der Karte ja 
0x00 sein.

Vor jedem Commando mache ich SS kurz high, sende ein byte 0xFF, mache ss 
dann wieder low:
1
sbi Portb, 2                        ;das ist der SS-Pin
2
    ldi  temp1,  0xFF
3
  rcall  sende       
4
cbi Portb, 2

Wodran kann das liegen, hatte jemand schonmal einen ähnlichen Fehler? 
Ich habe schon versucht, statt zu CMD55 direkt zu ACMD41 zu springen, da 
kommt dann aber ein Error (0x05)

Gruss,
Moritz

von Moritz G. (moritz-)


Lesenswert?

hatte ich vergessen: bei CMD1 passiert das gleiche: ewig lang sendet die 
Karte nur 0x01 und nicht 0x00.

von Rudolph (Gast)


Lesenswert?

SS ist doch aber Low-Aktiv, nicht wahr?

von Moritz G. (moritz-)


Lesenswert?

ja , deswegen hab ich ja vor jeden befehl SS auf low gezogen.
Oder hab ich da was falsch verstanden? SS wird nur kaurz wieder high, um 
sozusagen das ende des befehls anzuzeigen, dann 8 clock impulse, dann 
wieder low, weil ja dann das neue Commando kommt.
Oder ?

von Rudolph (Gast)


Lesenswert?

Sorry, ich habe mich durch das Assembler ein wenig verwirren lassen.

>rcall  sende

Das könnte noch hilfreich sein um das Problem einzukreisen.

Und wie schnell ist der SPI?

von Moritz G. (moritz-)


Lesenswert?

1
sende:  
2
  out  SPDR,  temp1
3
  loop:  sbis  SPSR,  SPIF
4
    rjmp  loop
5
ret
6
[/avrrasm]
7
8
Es würde mich wundern wenns am SPI läge, da die Kommunikation mit dem CMD0 und die zwischen-kommando-Clocks ja funktionieren, und die Karte ja auch korrekt antwortet,( nur halt mit dem falschen byte). Wenn ich irgendein falsches Kommando sende, kommt auch korrekt die Error-Meldung 0x05, usw.
9
10
Der SPI ist 8Mhz /16 , und dieses double speed ist deaktiviert, also ich initalisiere den SPI so:
11
12
[avrasm]
13
; Enable SPI, Master, set clock rate fck/16
14
15
    ldi temp1,(1<<SPE)|(1<<MSTR)|(1<<SPR0)
16
    out SPCR, temp1

von Rudolph (Gast)


Lesenswert?

Fehlt da nicht was?

---
sbi Portb, 2                        ;das ist der SS-Pin
    ldi  temp1,  0xFF
  rcall  sende
cbi Portb, 2

sende:
  out  SPDR,  temp1
  loop:  sbis  SPSR,  SPIF
    rjmp  loop
ret
---

Wenn das der Code ist dann ist SS doch High wenn Du sendest?
Wie in sbi == set bit / cbi == clear bit ??

Der Mega8 setzt den SS jedenfalls nicht automatisch, zumindest nicht auf 
Low wenn der Output ist und der SPI im Master-Mode.

von Moritz G. (moritz-)


Lesenswert?

Ja, das stimmt schon aber das ist ja nur das "bisschen warten" , was man 
machen soll wenn der SS-Pin kurz high ist. Ich sende da ja nichts im 
eigentlichen Sinne (0xFF); ich schicke sozusagen nur 8 Clock-Impulse, 
wobei der SSPin high ist. Das passiert vor jeden Kommando, dann ist der 
SS-Pin wider low, und das eigentliche Kommando kommt.

Aber ich habe es jetzt rausgekriegt. Wenn man das CMD1 sendet, muss man 
das ja widerholt tun, bis die SD-Karte ein 0x00 zurückschickt. ZWISCHEN 
den wiederholten Sendungen von CMD1 darf man aber NICHT den SS-Pin kurz 
auf High ziehen. Das Heisst praktisch, das senden von CMD1's ist als 
EINE Transaktion anzusehen, in der der SS-Pin ja immer lOW ist!!!!

Aber schon kommt die nächste komische Sache. Ich habe die Karte also 
ordentlich initalisiert, und will jetzt mit CMD16 die Blockgrösse auf 
512byte stellen. Doch als Antwort kriege ich 0x01???? De-initalisert 
sich die blöde Karte danach wieder oder ist das ein anderer Fehler?

Gruss,
Moritz

von holger (Gast)


Lesenswert?

>Aber schon kommt die nächste komische Sache. Ich habe die Karte also
>ordentlich initalisiert, und will jetzt mit CMD16 die Blockgrösse auf
>512byte stellen. Doch als Antwort kriege ich 0x01???? De-initalisert
>sich die blöde Karte danach wieder oder ist das ein anderer Fehler?

Lass das einfach sein. Einige Karten mögen SetBlocklen nicht.
Funktioniert auch ohne.

von Moritz G. (moritz-)


Lesenswert?

ah gut. umso besser.
sicher dass die Blockgrösse dann 512 ist? oder ist das egal?

von holger (Gast)


Lesenswert?

>sicher dass die Blockgrösse dann 512 ist?

Sicher ? Nö, aber wer sollte die Standardblockgröße
von 512 schon verstellen ?

von Moritz G. (moritz-)


Angehängte Dateien:

Lesenswert?

Ich hab einen Fehler gemacht, hab einen Sprungbefehl übersehen, also
DAS HIER STIMMT NICHT:
*
Aber ich habe es jetzt rausgekriegt. Wenn man das CMD1 sendet, muss man
das ja widerholt tun, bis die SD-Karte ein 0x00 zurückschickt. ZWISCHEN
den wiederholten Sendungen von CMD1 darf man aber NICHT den SS-Pin kurz
auf High ziehen. Das Heisst praktisch, das senden von CMD1's ist als
EINE Transaktion anzusehen, in der der SS-Pin ja immer lOW ist!!!!
*
Also war ich auch bei dem CMD16 im IDLE Modus, kein Wunder warum er mit 
0x01 geantwortet hat.

ALSO WIEDER BEIM ALTEN PROBLEM: WARUM INITALISIERT DIE KARTE NICHT?

hier mal der Quellcode iom Anhang. Das Programm beleibt in der CMD1 
Schleife hängen, es kommt als Antwort immer nur 0x01.

?????????????????????????????????????????????????????????????????

von holger (Gast)


Lesenswert?

Oh man, du hast nichts verstanden :(

Du kannst nicht einfach ACMD41 senden.
So sieht das richtig aus:

CMD55
ACMD41

CMD55
ACMD41

Ohne CMD55 vorne weg bringt ACMD41 nichts.

von Moritz G. (moritz-)


Lesenswert?

Häää?
Das hab ich immer so gemacht, sonst gibts ein error.

Ausserdem ist in dem Quellcode CMD1 benutzt. Das ist nämlich für normale 
SD-Karten das gleiche.

Wenn man aber über kommandos spricht, sagt man einfach ACMD41, da das 
kommando ACMD41 eben nur durch voriges enden von CDM55 angenommen wird.

von holger (Gast)


Lesenswert?

>Ausserdem ist in dem Quellcode CMD1 benutzt. Das ist nämlich für normale
>SD-Karten das gleiche.

Ja, und es gibt SD Karten die CMD1 nicht von vorneherein mögen.

  // Note: CMD1 is not supported by all SD cards
  // Thin 1,4mm cards don't accept CMD1 before sending ACMD41

von Moritz G. (moritz-)


Lesenswert?

ich weiss, ich hab aber eine dicke, und mit ACMD41 war das gleiche 
problem, dass ich nur 0x01 zurück bekommen habe.
Ich versuche nochmal, zwischen den Befehlen mehrere 0xFF Bytes zu 
senden.
Aber eigentlich kann das ja nur an der KArte ligen, weil wenn die mir 
richtig antwortet, hab ich ja wohl nichts falsch programmiert?
Ich werde es demnächst nochmal mit ner anderen SD-Karte ausprobieren.

Oder hat jemand mal einen BEispiel Assembler-Code für SD-Karten (ausser 
dieses MIDI-Projekt)??

von holger (Gast)


Lesenswert?

>Oder hat jemand mal einen BEispiel Assembler-Code für SD-Karten (ausser
>dieses MIDI-Projekt)??

Ich könnte dir das Assembler Listing von meinem C-Code schicken ;)

von Moritz G. (moritz-)


Lesenswert?

ja mach mal: moritzgreif@gmx.net

danke*

von Moritz G. (moritz-)


Lesenswert?

ok habs geschafft: der trick ist einfach, keine kompromisse einzugehen:

5A-5V- Spannungsregler
 3,3V-1,5A Spannungsregler
74HC4050 Pegelwandler

dann gehts.

von Bernhard S. (bernhard)


Angehängte Dateien:

Lesenswert?

Hallo Moritz

>ok habs geschafft: der trick ist einfach, keine kompromisse einzugehen:



Ich kämpfe gerade mit einem ähnlichen Problem, die Karte lässt sich in 
den

IDLE-MODUS versetzen (CMD0), antwortet auch korrekt mit x01

aber bei CMD1 empfange ich nur xFF, mit anderen Worten, die Karte 
reagiert

nicht. Der MISO-Pin ist permanent auf 3,5 Volt.


An was könnte das liegen? Wirklich ein Hardware-Problem?


Gruß Bernhard

von holger (Gast)


Lesenswert?

>An was könnte das liegen? Wirklich ein Hardware-Problem?

Hat es sich noch nicht herumgesprochen das Dioden
als Spannungsregler nicht geeignet sind ?

Und warum wird eine 3,6V Z-Diode von 3,6V der
SD-Karte auf MISO geschaltet ?

von ---=DIAN=--- (Gast)


Lesenswert?

Probier mal für das chipselect statt dem SS Pin einen anderen Pin zu 
nehmen und setze den SS Pin auf Dauer high. Hat bei mir geholfen...

Gruß DIAN

von ---=DIAN=--- (Gast)


Lesenswert?

Und mein Init sieht so aus:

unsigned char mmc_init(void)
{


  MMC_DDR|=(1<<MMC_CS)|(1<<SPI_CLK)|(1<<SPI_MOSI);
  MMC_DDR&=~(1<SPI_MISO);

// POWER OFF
  #if MMC_DEBUG
    printf_P(PSTR("\nMMC: Start...\n"));
    printf_P(PSTR("\nMMC: Power Off..."));
  #endif
  PORTC&=~(1<<PC4);
  MMC_PORT&=~(1<<MMC_CS);
  _delay_ms(1000);

// POWER ON
  #if MMC_DEBUG
    printf_P(PSTR("\nMMC: Power On..."));
  #endif
  PORTC|=(1<<PC4);
  MMC_PORT|=(1<<MMC_CS);
  _delay_ms(1000);

// CMD40
  unsigned char res;
  cmd[0] = 0x40;  cmd[1] = 0x00; cmd[2] = 0x00; cmd[3] = 0x00; cmd[4] = 
0x00; cmd[5] = 0x95;

  #if MMC_DEBUG
    printf_P(PSTR("MMC: Send CMD0...\n"));
  #endif

// Command CMD 0 RES should be 0x01 for IDLE STATE
  res=255;
  while(res!=1)
    {
    res=send_cmd(1);
    #if MMC_DEBUG
      printf_P(PSTR("MMC: CMD0 returns: %d \n"),res);
    #endif

    if (res==0)
      {
      MMC_PORT|=(1<<MMC_CS);
      spi_send_byte(0xFF); //Dummy delay 8 clocks
      spi_send_byte(0xFF); //Dummy delay 8 clocks
      spi_send_byte(0xFF); //Dummy delay 8 clocks
      }
    }

  #if MMC_DEBUG
    printf_P(PSTR("MMC: Send CMD1...\n"));
  #endif

// CMD41
  cmd[0] = 0x41;
  res=255;
  while(res!=0)
    {
    res=send_cmd(1);
    #if MMC_DEBUG
      printf_P(PSTR("MMC: CMD1 returns: %d \n"),res);
    #endif
    }
  #if MMC_DEBUG
    printf_P(PSTR("MMC: INIT done... \n"));
  #endif
  // Command CMD 1 RES should be 0x00 for READY

  return(MMC_OK);
}


Wichtig war wie gesagt CS!=SS Pin und das POWER OFF _VOR_ dem Init. 
Und damit habe ich bis jetzt _JEDE_ Karte initialisiert, egal ob MMC 
oder SD.

Gruß ---=DIAN=---

von Bernhard S. (bernhard)


Lesenswert?

@holger

>Hat es sich noch nicht herumgesprochen das Dioden
>als Spannungsregler nicht geeignet sind ?

Warum sollte es nicht funktionieren?


>Und warum wird eine 3,6V Z-Diode von 3,6V der
>SD-Karte auf MISO geschaltet ?

Das ist eine Shottky Diode (wenig Spannungsabfall) sie schützt den 
Ausgang der SD-Karte vor zu hoher Spannung, falls versehentlich 5V am µC 
Pin anliegen.

@DIAN

>Probier mal für das chipselect statt dem SS Pin einen anderen Pin zu
>nehmen und setze den SS Pin auf Dauer high. Hat bei mir geholfen...

Danke für Deinen Tipp, ich probier's mal aus


Bernhard

von Bernhard S. (bernhard)


Lesenswert?

> POWER OFF VOR dem Init.


Meinst Du damit den Reset der Karte (74 x Clocks und CMD0) usw?

von Bernhard S. (bernhard)


Lesenswert?

Hab mal eine andere SD-KARTE verwendet, plötzlich antwortet die Karte 
auf

das CMD1 Kommando. Ich kann's mir nicht erklären.


Dian, könntest Du mir mal Deine Schaltung und ein hex Files zur 
Verfügung stellen. Vielleicht kann ich damit ein Hardwareproblem 
ausschließen.


Danke

Bernhard

von Commtel (Gast)


Lesenswert?

SPI geschwindigkeit muß sehr langsam sein.
Das würde mir als einzigstes einfallen
Auser beim Read oder Write.
Da kann man vollgaß geben

c.u
Commtel

von Moritz G. (moritz-)


Lesenswert?

Also wichtig ist auch folgendes:

-Falls es mit einer SD-Karte geht und mit der anderen nicht, dann kann 
es daran liegen, dass eine eine dünne (1,4mm) und die andere ne dicke 
ist. Bei den dünnen geht CMD1 nicht glaub ich. Was aber bei SD-Karten 
immer geht ist CMD55/ACMD41. Das war bei mir auch der Fehler mal.

-Dann ist es auch vorteilhaft, sich grad bei Reichelt nen richtigen 
Pegelwandler zu holen:

5V-   Spannungsregler
3,3V- Spannungsregler
74HC4050 Pegelwandler

Das geht perfekt. Mein GPS zeichnet damit genüsslich Routen auf.
Damit hat man schöne Flanken, und kann den SPI-Bus auch schön schnell 
stellen. Die SD-Karte hat mit hohen Geschwindigkeiten keine Probleme 
(ich glaub sowas mit 20Mhz steh im Datenblatt)

von Bernhard S. (bernhard)


Lesenswert?

@alle

Plötzlich lassen sich die SD-Karten mit CMD0 und CMD1 initialisiern.

Was war die Ursache?

Es muss zwischen CMD0 und CMD1 einige Dummys bei CS=HIGH gesendet 
werden.


DIAN sein CODE brachte mir die Erleuchtung.

Danke

Bernhard

von Simon K. (simon) Benutzerseite


Lesenswert?

Das mit dem SS auf einen anderen Pin legen hat übrigens keinen Effekt. 
Hauptsache er ist als Ausgang geschaltet, damit das SPI-Modul im 
Master-modus arbeitet.

von Rudolph (Gast)


Lesenswert?

Dioden als Spannungs-Regler funktionieren gerade bei SD-Karten nicht 
wirklich zuverlässig da deren Durchlass-Spannung keine konstante Grösse 
ist sondern vielmehr abhängig vom Strom durch die Diode.

Und der Strom den eine SD-Karte aufnimmt ist alles andere als konstant.

Nach Sandisks "ProdManualSDCardv2.2.pdf":

2.4 Typical Power Requirements

Ta=25°C@3.0V

Sleep 250 µA max
Read 65 mA max
Write 75 mA max

Man müsste das mit den Dioden also so ausknobeln, dass bei 250 µA nicht 
über 3,6V an der Karte anliegen und bei 75 mA nicht unter 2,7V.

Dann lieber für 35 Cent einen LP2950-3.0.

von ---=DIAN=--- (Gast)


Angehängte Dateien:

Lesenswert?

Sorry für die etwas späte antwort...

Das ist schön, wenns geklappt hat. Hab mir den Code Anfang letzten 
Jahres von Grund auf neu zuschammengeschrieben, da SÄMTLICHE 
Quellcodes mit meinen Karten nicht gefunzt haben...

Mit Power OFF meinte ich den wirklichen Power off, also der Karte VCC 
wegnehmen.

Und zum Thema Spannungen: Pegelwandlung habe ich nicht drin, da die 
SDCard 5V verträgt lt. Datenblatt und der Atmel im Normalfall auch keine 
Probleme mit 3,3V Pegeln hat. Ich logge damit seit einem Jahr (24/7) 
Daten und habe bis jetzt keine Probleme gehabt. Und nen 3,3V 
Spannungswadler gibts bei Reichelt für 0,78€...

Falls Du noch Infos brauchst, mail an mich: dian-1@gmx.de

Gruß

von ---=DIAN=--- (Gast)


Lesenswert?

achso: ist nen alter Schaltplan, sieht nicht schön aus und ist nicht so 
ausgereift, der Transistor Q2 ist am besten durch nen FET mit niedrigen 
R_DS_ON zu ersetzen... Also bitte keine Kritik, sondern 
Verbesserungsvorschläge abgeben...

von Bernhard S. (bernhard)


Lesenswert?

Hallo Dian,

Danke für Deinen Schaltplan. Kleiner Tipp, man könnte den Vcc Pin der 
SD-Karte noch mit einem kleinen C von ca. 100nF + 10µF gegen GND 
beschalten.

Meine Assembler Code läuft soweit ganz gut, meine SD-Karten lassen sich 
problemlos initialisieren, die Register CID und CSD auslesen. Ich werde 
dieses Projekt demnächst veröffentlichen.

Doch nun stehe ich vor dem nächsten Problem.

Ich wollte das Label (11 Byte) der SD-Karte auslesen. Unter Windows kann 
man ja jedem Datenträger bezeichnen.

Nur bei der einen Karte steht dieses Label im Block 723, bei der 
nächsten im Block 468 und bei einer anderen im Block 470.

Wenn ich alles richtig verstanden habe hat das was mit der Formatierung 
des Datenträgers zu tun.

Befindet sich der Boot-Sektor immer im Block 0 ?

Danke

Gruß Bernhard

von ---=DIAN=--- (Gast)


Lesenswert?

ich glaube da musst Du dich mit FAT16 oder je FAT32 (je nach 
Formatierung der Karte) auseinandersetzen. Gibts auch schon viele 
Routinen im Netz, wie immer aber so dass man sie nicht so einfach 
benutzen kann...

Nen kurzen überblick gibts hier: 
http://de.wikipedia.org/wiki/File_Allocation_Table

Da ich das auch alles neu geschrieben habe (ich brauche z.B. keine 10 
gleichzeitig geöffneten Files) kann ich sagen FAT16 is nicht wirklich 
kompliziert, das war das Init mit allen Karten schwerer.

Und ja, der Bootsektor ist immer Block 0.

danach folgen die reservierten Sektor, dann FAT1 und FAT2, DIR und 
Daten. Bei unterschiedlichen Kartengrößen steht dein Label somit auch an 
unterschiedlichen Stellen. Aber keine Sorge, kann man alles errechnen. 
(Bootsektor+reserviert+fat1+fat2)

Danke für den Tip, werde aber den Plan demnächst eh nochmal radikal 
überarbeiten. ist eben nur quick and dirty gewesen zum testen.

Gruß DIAN

von Bernhard S. (bernhard)


Lesenswert?

Hallo DIAN,

ich bin etwas stutzig geworden.

Einen Block, also 512 Bytes habe ich mit CMD24 "x58 x00 x00 x03 0xE8 
0x00"
an die Position 1000 geschrieben, konne diesen Block auch problemlos mit
CMD17 wieder einlesen.


Aber:

Den Inhalt der SD-Karten habe ich mir mit dem Programm "HxD-Hexeditor" 
angeschaut, meine 512 Bytes (alles 'A') tummeln sich aber an der
Position 757 herum und nicht bei 1000.


Wie kommt das?


Gruß Bernhard

von Moritz G. (moritz-)


Lesenswert?

Das hab ich auch festgestellt. Man kann bei den HEX-Editoren umstellen, 
welches Format man haben möchte. Das eine sind "physikalische" und das 
andere irgendwie absolute Sektoren. Wozu das gut ist, wüsst ich auch 
gern.

von Bernhard S. (bernhard)


Lesenswert?

welchen HEX-EDITOR würdest Du empfehlen?

Die Assebler-Routinen habe ich mal veröffentlicht:

Beitrag "SD-Karte Initialisierung Read Write FAT ATmega8 (Assembler)"

von Commtel (Gast)


Lesenswert?

Hatte auch mal vor einem Jahr mit SD Card s zu tun
WINHEX war dabei sehr Hilfreich!

c.u
Commtel

von ---=DIAN=--- (Gast)


Lesenswert?


von Bernhard S. (bernhard)


Lesenswert?

Ich danke Euch,

leider läüft der Tiny-Hexer bei WIN98 nicht richtig, aber WINhex und HxD 
tun es ja auch, man muss nur darauf achten, dass nur die logischen und 
nicht die physikalischen Sektoren angezeigt werden.

Bernhard

von Jochen Adler (Gast)


Lesenswert?

Hallo Rudolph,

entschuldige bitte, dass ich dich auf diesem Weg anschreibe, aber das 
einzige, was ich von dir weiß, sind deine Postings hier.
Ich versuche gerade eine SD-Karte an einem C64 zu betreiben (meine 
anderen Projekte sind auf www.nlq.de). Du hast geschrieben, dass du
ProdManualSDCardv2 2 pdf
hast. Daran hätte ich absolutes Interesse, finde es aber nirgends im 
Internet. Ich würde mich freuen, wenn du Kontakt mit mir (NLQ@gmx.de) 
aufnehmen würdest und wir das besprechen könnten. Ich hätte als Dank 
z.B.
ProdManualMMCv5.2.pdf
oder
ProdManualSDCardv1.9.pdf

Vielen Dank
Jochen Adler

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.